From 01cb37e82e566c74ea863de8096743efc21f6891 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 18 Nov 2024 11:06:00 -0500 Subject: [PATCH 01/30] refactor: move signer implementation to mpc package --- x/did/types/formatter.go | 1 - x/did/types/{ => mpc}/signer.go | 3 +- x/did/types/pubkey.go | 76 --------------------------------- 3 files changed, 1 insertion(+), 79 deletions(-) delete mode 100644 x/did/types/formatter.go rename x/did/types/{ => mpc}/signer.go (97%) delete mode 100644 x/did/types/pubkey.go diff --git a/x/did/types/formatter.go b/x/did/types/formatter.go deleted file mode 100644 index ab1254f4c..000000000 --- a/x/did/types/formatter.go +++ /dev/null @@ -1 +0,0 @@ -package types diff --git a/x/did/types/signer.go b/x/did/types/mpc/signer.go similarity index 97% rename from x/did/types/signer.go rename to x/did/types/mpc/signer.go index 87f4336a8..ad54e9c3b 100644 --- a/x/did/types/signer.go +++ b/x/did/types/mpc/signer.go @@ -1,4 +1,4 @@ -package types +package mpc import ( "context" @@ -25,6 +25,5 @@ func (s directHandler) GetSignBytes( ChainId: signerData.ChainID, AccountNumber: signerData.AccountNumber, } - return txDoc.Marshal() } diff --git a/x/did/types/pubkey.go b/x/did/types/pubkey.go deleted file mode 100644 index 97d17ee5f..000000000 --- a/x/did/types/pubkey.go +++ /dev/null @@ -1,76 +0,0 @@ -package types - -import ( - "strings" - - didv1 "github.com/onsonr/sonr/api/did/v1" -) - -type PubKeyI interface { - GetRole() string - GetKeyType() string - GetRawKey() *didv1.RawKey - GetJwk() *didv1.JSONWebKey -} - -// PubKey defines a generic pubkey. -type PublicKey interface { - VerifySignature(msg, sig []byte) bool -} - -type PubKeyG[T any] interface { - *T - PublicKey -} - -type pubKeyImpl struct { - decode func(b []byte) (PublicKey, error) - validate func(key PublicKey) error -} - -// func WithSecp256K1PubKey() Option { -// return WithPubKeyWithValidationFunc(func(pt *secp256k1.PubKey) error { -// _, err := dcrd_secp256k1.ParsePubKey(pt.Key) -// return err -// }) -// } -// -// func WithPubKey[T any, PT PubKeyG[T]]() Option { -// return WithPubKeyWithValidationFunc[T, PT](func(_ PT) error { -// return nil -// }) -// } -// -// func WithPubKeyWithValidationFunc[T any, PT PubKeyG[T]](validateFn func(PT) error) Option { -// pkImpl := pubKeyImpl{ -// decode: func(b []byte) (PublicKey, error) { -// key := PT(new(T)) -// err := gogoproto.Unmarshal(b, key) -// if err != nil { -// return nil, err -// } -// return key, nil -// }, -// validate: func(k PublicKey) error { -// concrete, ok := k.(PT) -// if !ok { -// return fmt.Errorf( -// "invalid pubkey type passed for validation, wanted: %T, got: %T", -// concrete, -// k, -// ) -// } -// return validateFn(concrete) -// }, -// } -// return func(a *Account) { -// a.supportedPubKeys[gogoproto.MessageName(PT(new(T)))] = pkImpl -// } -// } -func nameFromTypeURL(url string) string { - name := url - if i := strings.LastIndexByte(url, '/'); i >= 0 { - name = name[i+len("/"):] - } - return name -} From bf94277b0f32125c71f1f52f272925512b4f5299 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 18 Nov 2024 19:04:10 -0500 Subject: [PATCH 02/30] feature/1110 abstract connected wallet operations (#1166) - **refactor: refactor DID module types and move to controller package** - **refactor: move controller creation and resolution logic to keeper** - **refactor: update imports to reflect controller package move** - **refactor: update protobuf definitions for DID module** - **docs: update proto README to reflect changes** - **refactor: move hway to gateway, update node modules, and refactor pkl generation** - **build: update pkl-gen task to use new pkl file paths** - **refactor: refactor DWN WASM build and deployment process** - **refactor: refactor DID controller implementation to use account-based storage** - **refactor: move DID controller interface to base file and update implementation** - **chore: migrate to google protobuf** - **feat: Add v0.52.0 Interfaces for Acc Abstraction** - **refactor: replace public_key with public_key_hex in Assertion message** - **refactor: remove unused PubKey, JSONWebKey, and RawKey message types and related code** --- .github/workflows/publish-assets.yml | 72 +- .gitignore | 4 +- Makefile | 9 +- Taskfile.yml | 58 +- api/did/module/v1/module.pulsar.go | 69 +- api/did/v1/genesis.pulsar.go | 4499 +++-------------- api/did/v1/params.pulsar.go | 1750 +++++++ api/did/v1/query.pulsar.go | 1374 +---- api/did/v1/query_grpc.pb.go | 40 - api/did/v1/state.cosmos_orm.go | 537 +- api/did/v1/state.pulsar.go | 2944 ++++------- api/did/v1/tx.pulsar.go | 276 +- api/service/module/v1/module.pulsar.go | 71 +- api/service/v1/state.pulsar.go | 718 +-- api/vault/module/v1/module.pulsar.go | 63 +- buf.work.yaml | 4 + .../dwn/fetch/serve.go => cmd/dwn/main.go | 46 +- cmd/{hway => gateway}/bun.lockb | Bin cmd/{hway => gateway}/main.go | 7 +- cmd/{hway => gateway}/wrangler.toml | 0 go.mod | 2 - go.sum | 4 - internal/dwn/app.wasm | Bin 11003100 -> 0 bytes internal/dwn/gen/init.pkl.go | 10 - internal/dwn/wasm/main.go | 48 - internal/orm/transactions/Msg.pkl.go | 6 - .../transactions/MsgDidAllocateVault.pkl.go | 44 - .../orm/transactions/MsgDidAuthorize.pkl.go | 60 - .../transactions/MsgDidProveWitness.pkl.go | 52 - .../MsgDidRegisterController.pkl.go | 60 - .../transactions/MsgDidRegisterService.pkl.go | 76 - .../orm/transactions/MsgDidSyncVault.pkl.go | 36 - .../transactions/MsgDidUpdateParams.pkl.go | 44 - .../orm/transactions/MsgGovDeposit.pkl.go | 44 - .../transactions/MsgGovSubmitProposal.pkl.go | 45 - internal/orm/transactions/MsgGovVote.pkl.go | 42 - .../transactions/MsgGroupCreateGroup.pkl.go | 45 - .../MsgGroupSubmitProposal.pkl.go | 60 - internal/orm/transactions/MsgGroupVote.pkl.go | 58 - .../MsgStakingBeginRedelegate.pkl.go | 52 - .../MsgStakingCreateValidator.pkl.go | 77 - .../transactions/MsgStakingDelegate.pkl.go | 44 - .../transactions/MsgStakingUndelegate.pkl.go | 44 - internal/orm/transactions/Proposal.pkl.go | 11 - internal/orm/transactions/Transactions.pkl.go | 36 - internal/orm/transactions/TxBody.pkl.go | 17 - internal/orm/transactions/init.pkl.go | 27 - pkg/common/README.md | 1 + {internal => pkg/common}/ctx/cookies.go | 0 {internal => pkg/common}/ctx/ctx_dwn.go | 9 +- {internal => pkg/common}/ctx/ctx_hway.go | 0 {internal => pkg/common}/ctx/headers.go | 3 +- {internal => pkg/common}/ctx/request.go | 0 {internal => pkg/common}/ctx/response.go | 0 {internal => pkg/common}/ctx/utils.go | 0 pkg/common/types/ipfs.pb.go | 64 + pkg/common/types/keys.pb.go | 377 ++ pkg/common/types/uri.pb.go | 215 + pkg/core/README.md | 1 + pkg/core/appmodule/environment.go | 30 + pkg/core/branch/branch.go | 34 + pkg/core/log/logger.go | 29 + pkg/core/router/service.go | 16 + pkg/core/transaction/service.go | 25 + pkg/core/transaction/transaction.go | 45 + pkg/hway/README.md | 1 + pkg/{workers => hway}/handlers/jsonrpc.go | 0 pkg/{workers => hway}/handlers/querier.go | 0 pkg/hway/handlers/sync.go | 13 + .../gateway.go => hway/routes/routes.go} | 0 pkg/hway/types/api.pb.go | 535 ++ pkg/hway/types/client.pb.go | 63 + pkg/motr/README.md | 1 + .../dwn/gen => pkg/motr/config}/Config.pkl.go | 4 +- .../motr/config/Dwn.pkl.go | 16 +- .../dwn/gen => pkg/motr/config}/Schema.pkl.go | 4 +- pkg/motr/config/init.pkl.go | 10 + {internal/dwn => pkg/motr}/embed.go | 20 +- pkg/{workers => motr}/handlers/auth.go | 18 +- pkg/motr/handlers/openid.go | 23 + pkg/motr/routes/routes.go | 26 + pkg/{nebula => motr/static}/index.go | 7 +- {internal/dwn => pkg/motr/static}/sw.js | 0 pkg/motr/types/api.pb.go | 342 ++ .../motr/types}/orm/Account.pkl.go | 0 {internal => pkg/motr/types}/orm/Asset.pkl.go | 0 {internal => pkg/motr/types}/orm/Chain.pkl.go | 0 .../motr/types}/orm/Credential.pkl.go | 0 {internal => pkg/motr/types}/orm/DID.pkl.go | 10 +- {internal => pkg/motr/types}/orm/Grant.pkl.go | 0 {internal => pkg/motr/types}/orm/JWK.pkl.go | 0 .../motr/types}/orm/Keyshare.pkl.go | 0 {internal => pkg/motr/types}/orm/Orm.pkl.go | 0 .../motr/types}/orm/Profile.pkl.go | 0 .../types}/orm/assettype/AssetType.pkl.go | 0 .../types}/orm/didmethod/DIDMethod.pkl.go | 0 {internal => pkg/motr/types}/orm/init.pkl.go | 0 .../orm/keyalgorithm/KeyAlgorithm.pkl.go | 0 .../motr/types}/orm/keycurve/KeyCurve.pkl.go | 0 .../types}/orm/keyencoding/KeyEncoding.pkl.go | 0 .../motr/types}/orm/keyrole/KeyRole.pkl.go | 0 .../orm/keysharerole/KeyShareRole.pkl.go | 0 .../motr/types}/orm/keytype/KeyType.pkl.go | 0 .../permissiongrant/PermissionGrant.pkl.go | 0 .../permissionscope/PermissionScope.pkl.go | 0 {internal => pkg/motr/types}/orm/schema.go | 0 {internal => pkg/motr/types}/orm/webauthn.go | 0 pkg/nebula/marketing/section_arch.templ | 2 +- pkg/nebula/marketing/section_arch_templ.go | 2 +- pkg/nebula/marketing/section_cta.templ | 2 +- pkg/nebula/marketing/section_cta_templ.go | 2 +- pkg/nebula/marketing/section_hero.templ | 2 +- pkg/nebula/marketing/section_hero_templ.go | 2 +- pkg/nebula/marketing/section_highlights.templ | 2 +- .../marketing/section_highlights_templ.go | 2 +- pkg/nebula/marketing/section_lowlights.templ | 2 +- .../marketing/section_lowlights_templ.go | 2 +- pkg/nebula/marketing/section_mission.templ | 2 +- pkg/nebula/marketing/section_mission_templ.go | 2 +- pkg/nebula/routes/auth.go | 3 +- pkg/nebula/routes/home.go | 3 +- .../nebula/types/marketing.go | 2 +- pkg/workers/README.md | 1 - pkg/workers/client/http.go | 47 - pkg/workers/handlers/openid.go | 31 - pkg/workers/handlers/sync.go | 25 - pkg/workers/routes/webnode.go | 33 - pkl/Txns.pkl | 174 - proto/README.md | 6 - proto/buf.lock | 9 +- proto/buf.yaml | 1 + proto/did/module/v1/module.proto | 4 +- proto/did/v1/genesis.proto | 68 +- proto/did/v1/params.proto | 34 + proto/did/v1/query.proto | 17 +- proto/did/v1/state.proto | 141 +- proto/did/v1/tx.proto | 25 +- proto/service/module/v1/module.proto | 4 +- proto/service/v1/state.proto | 35 +- proto/service/v1/tx.proto | 6 +- proto/vault/module/v1/module.proto | 4 +- scripts/protocgen.sh | 19 +- {pkl => third_party/pkl}/README.md | 0 .../pkl/src/sonr.configs.v1}/DWN.pkl | 4 +- .../pkl/src/sonr.models.v1}/ORM.pkl | 2 +- third_party/proto/README.md | 19 + third_party/proto/buf.gen.yaml | 7 + third_party/proto/buf.lock | 38 + third_party/proto/buf.yaml | 15 + third_party/proto/common/v1/ipfs.proto | 5 + third_party/proto/common/v1/keys.proto | 30 + third_party/proto/common/v1/uri.proto | 16 + third_party/proto/hway/v1/api.proto | 40 + third_party/proto/hway/v1/client.proto | 3 + third_party/proto/motr/v1/api.proto | 26 + .../controller.go => controller/base.go} | 26 +- x/did/controller/signer/actor.go | 1 + x/did/controller/signer/context.go | 1 + .../mpc => controller/signer}/signer.go | 2 +- x/did/controller/table.go | 20 + x/did/controller/wallet/pubkey.go | 140 + x/did/controller/wallet/txns.go | 1 + x/did/controller/wallet/wallet.go | 1 + x/did/keeper/controller.go | 31 - x/did/keeper/genesis.go | 28 +- x/did/keeper/issuer.go | 59 - x/did/types/account.go | 12 - x/did/types/accstd/exports.go | 166 + .../accstd/internal/accounts/api_builder.go | 112 + .../types/accstd/internal/accounts/context.go | 124 + .../accstd/internal/accounts/encoding.go | 66 + .../internal/accounts/implementation.go | 157 + .../accstd/internal/accounts/interface.go | 17 + .../accstd/internal/accounts/protoaccount.go | 78 + .../internal/prefixstore/prefixstore.go | 223 + x/did/types/{address.go => compute.go} | 12 +- x/did/types/genesis.pb.go | 1970 +------- x/did/types/mpc/secp256k1_pk.go | 68 - x/did/types/params.go | 8 +- x/did/types/params.pb.go | 931 ++++ x/did/types/pubkey/pubkey.go | 76 - x/did/types/query.pb.go | 607 +-- x/did/types/query.pb.gw.go | 119 - x/did/types/state.pb.go | 1441 ++---- x/did/types/tx.pb.go | 99 +- x/service/types/state.pb.go | 321 +- x/vault/keeper/keeper.go | 2 +- x/vault/keeper/querier.go | 4 +- x/vault/types/params.go | 2 +- x/vault/types/vault.go | 10 +- 190 files changed, 9345 insertions(+), 14038 deletions(-) create mode 100644 api/did/v1/params.pulsar.go create mode 100644 buf.work.yaml rename internal/dwn/fetch/serve.go => cmd/dwn/main.go (69%) rename cmd/{hway => gateway}/bun.lockb (100%) rename cmd/{hway => gateway}/main.go (66%) rename cmd/{hway => gateway}/wrangler.toml (100%) delete mode 100755 internal/dwn/app.wasm delete mode 100644 internal/dwn/gen/init.pkl.go delete mode 100644 internal/dwn/wasm/main.go delete mode 100644 internal/orm/transactions/Msg.pkl.go delete mode 100644 internal/orm/transactions/MsgDidAllocateVault.pkl.go delete mode 100644 internal/orm/transactions/MsgDidAuthorize.pkl.go delete mode 100644 internal/orm/transactions/MsgDidProveWitness.pkl.go delete mode 100644 internal/orm/transactions/MsgDidRegisterController.pkl.go delete mode 100644 internal/orm/transactions/MsgDidRegisterService.pkl.go delete mode 100644 internal/orm/transactions/MsgDidSyncVault.pkl.go delete mode 100644 internal/orm/transactions/MsgDidUpdateParams.pkl.go delete mode 100644 internal/orm/transactions/MsgGovDeposit.pkl.go delete mode 100644 internal/orm/transactions/MsgGovSubmitProposal.pkl.go delete mode 100644 internal/orm/transactions/MsgGovVote.pkl.go delete mode 100644 internal/orm/transactions/MsgGroupCreateGroup.pkl.go delete mode 100644 internal/orm/transactions/MsgGroupSubmitProposal.pkl.go delete mode 100644 internal/orm/transactions/MsgGroupVote.pkl.go delete mode 100644 internal/orm/transactions/MsgStakingBeginRedelegate.pkl.go delete mode 100644 internal/orm/transactions/MsgStakingCreateValidator.pkl.go delete mode 100644 internal/orm/transactions/MsgStakingDelegate.pkl.go delete mode 100644 internal/orm/transactions/MsgStakingUndelegate.pkl.go delete mode 100644 internal/orm/transactions/Proposal.pkl.go delete mode 100644 internal/orm/transactions/Transactions.pkl.go delete mode 100644 internal/orm/transactions/TxBody.pkl.go delete mode 100644 internal/orm/transactions/init.pkl.go create mode 100644 pkg/common/README.md rename {internal => pkg/common}/ctx/cookies.go (100%) rename {internal => pkg/common}/ctx/ctx_dwn.go (92%) rename {internal => pkg/common}/ctx/ctx_hway.go (100%) rename {internal => pkg/common}/ctx/headers.go (94%) rename {internal => pkg/common}/ctx/request.go (100%) rename {internal => pkg/common}/ctx/response.go (100%) rename {internal => pkg/common}/ctx/utils.go (100%) create mode 100644 pkg/common/types/ipfs.pb.go create mode 100644 pkg/common/types/keys.pb.go create mode 100644 pkg/common/types/uri.pb.go create mode 100644 pkg/core/README.md create mode 100644 pkg/core/appmodule/environment.go create mode 100644 pkg/core/branch/branch.go create mode 100644 pkg/core/log/logger.go create mode 100644 pkg/core/router/service.go create mode 100644 pkg/core/transaction/service.go create mode 100644 pkg/core/transaction/transaction.go create mode 100644 pkg/hway/README.md rename pkg/{workers => hway}/handlers/jsonrpc.go (100%) rename pkg/{workers => hway}/handlers/querier.go (100%) create mode 100644 pkg/hway/handlers/sync.go rename pkg/{workers/routes/gateway.go => hway/routes/routes.go} (100%) create mode 100644 pkg/hway/types/api.pb.go create mode 100644 pkg/hway/types/client.pb.go create mode 100644 pkg/motr/README.md rename {internal/dwn/gen => pkg/motr/config}/Config.pkl.go (88%) rename internal/dwn/gen/Dwngen.pkl.go => pkg/motr/config/Dwn.pkl.go (68%) rename {internal/dwn/gen => pkg/motr/config}/Schema.pkl.go (87%) create mode 100644 pkg/motr/config/init.pkl.go rename {internal/dwn => pkg/motr}/embed.go (59%) rename pkg/{workers => motr}/handlers/auth.go (84%) create mode 100644 pkg/motr/handlers/openid.go create mode 100644 pkg/motr/routes/routes.go rename pkg/{nebula => motr/static}/index.go (74%) rename {internal/dwn => pkg/motr/static}/sw.js (100%) create mode 100644 pkg/motr/types/api.pb.go rename {internal => pkg/motr/types}/orm/Account.pkl.go (100%) rename {internal => pkg/motr/types}/orm/Asset.pkl.go (100%) rename {internal => pkg/motr/types}/orm/Chain.pkl.go (100%) rename {internal => pkg/motr/types}/orm/Credential.pkl.go (100%) rename {internal => pkg/motr/types}/orm/DID.pkl.go (60%) rename {internal => pkg/motr/types}/orm/Grant.pkl.go (100%) rename {internal => pkg/motr/types}/orm/JWK.pkl.go (100%) rename {internal => pkg/motr/types}/orm/Keyshare.pkl.go (100%) rename {internal => pkg/motr/types}/orm/Orm.pkl.go (100%) rename {internal => pkg/motr/types}/orm/Profile.pkl.go (100%) rename {internal => pkg/motr/types}/orm/assettype/AssetType.pkl.go (100%) rename {internal => pkg/motr/types}/orm/didmethod/DIDMethod.pkl.go (100%) rename {internal => pkg/motr/types}/orm/init.pkl.go (100%) rename {internal => pkg/motr/types}/orm/keyalgorithm/KeyAlgorithm.pkl.go (100%) rename {internal => pkg/motr/types}/orm/keycurve/KeyCurve.pkl.go (100%) rename {internal => pkg/motr/types}/orm/keyencoding/KeyEncoding.pkl.go (100%) rename {internal => pkg/motr/types}/orm/keyrole/KeyRole.pkl.go (100%) rename {internal => pkg/motr/types}/orm/keysharerole/KeyShareRole.pkl.go (100%) rename {internal => pkg/motr/types}/orm/keytype/KeyType.pkl.go (100%) rename {internal => pkg/motr/types}/orm/permissiongrant/PermissionGrant.pkl.go (100%) rename {internal => pkg/motr/types}/orm/permissionscope/PermissionScope.pkl.go (100%) rename {internal => pkg/motr/types}/orm/schema.go (100%) rename {internal => pkg/motr/types}/orm/webauthn.go (100%) rename internal/orm/marketing/models.go => pkg/nebula/types/marketing.go (99%) delete mode 100644 pkg/workers/README.md delete mode 100644 pkg/workers/client/http.go delete mode 100644 pkg/workers/handlers/openid.go delete mode 100644 pkg/workers/handlers/sync.go delete mode 100644 pkg/workers/routes/webnode.go delete mode 100644 pkl/Txns.pkl create mode 100644 proto/did/v1/params.proto rename {pkl => third_party/pkl}/README.md (100%) rename {pkl => third_party/pkl/src/sonr.configs.v1}/DWN.pkl (90%) rename {pkl => third_party/pkl/src/sonr.models.v1}/ORM.pkl (98%) create mode 100644 third_party/proto/README.md create mode 100644 third_party/proto/buf.gen.yaml create mode 100644 third_party/proto/buf.lock create mode 100644 third_party/proto/buf.yaml create mode 100644 third_party/proto/common/v1/ipfs.proto create mode 100644 third_party/proto/common/v1/keys.proto create mode 100644 third_party/proto/common/v1/uri.proto create mode 100644 third_party/proto/hway/v1/api.proto create mode 100644 third_party/proto/hway/v1/client.proto create mode 100644 third_party/proto/motr/v1/api.proto rename x/did/{types/controller.go => controller/base.go} (63%) create mode 100644 x/did/controller/signer/actor.go create mode 100644 x/did/controller/signer/context.go rename x/did/{types/mpc => controller/signer}/signer.go (97%) create mode 100644 x/did/controller/table.go create mode 100644 x/did/controller/wallet/pubkey.go create mode 100644 x/did/controller/wallet/txns.go create mode 100644 x/did/controller/wallet/wallet.go delete mode 100644 x/did/keeper/controller.go delete mode 100644 x/did/keeper/issuer.go delete mode 100644 x/did/types/account.go create mode 100644 x/did/types/accstd/exports.go create mode 100644 x/did/types/accstd/internal/accounts/api_builder.go create mode 100644 x/did/types/accstd/internal/accounts/context.go create mode 100644 x/did/types/accstd/internal/accounts/encoding.go create mode 100644 x/did/types/accstd/internal/accounts/implementation.go create mode 100644 x/did/types/accstd/internal/accounts/interface.go create mode 100644 x/did/types/accstd/internal/accounts/protoaccount.go create mode 100644 x/did/types/accstd/internal/prefixstore/prefixstore.go rename x/did/types/{address.go => compute.go} (72%) delete mode 100644 x/did/types/mpc/secp256k1_pk.go create mode 100644 x/did/types/params.pb.go delete mode 100644 x/did/types/pubkey/pubkey.go diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index 7a50f5ba5..57e6fce9b 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -9,7 +9,7 @@ permissions: issues: write jobs: - buf_push: + buf_push_core: name: Publish to buf.build/onsonr/sonr runs-on: ubuntu-latest steps: @@ -24,40 +24,60 @@ jobs: input: proto buf_token: ${{ secrets.BUF_TOKEN }} - # - # upload_configs: - # runs-on: ubuntu-latest - # name: Publish to configs.sonr.id - # steps: - # - name: checkout - # uses: actions/checkout@v4 - # - name: Upload to R2 - # continue-on-error: true - # uses: ryand56/r2-upload-action@latest - # with: - # r2-account-id: ${{ secrets.R2_ACCOUNT_ID }} - # r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }} - # r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }} - # r2-bucket: configs - # source-dir: config - # destination-dir: ./pkl - # - - upload_pkl: + buf_push_thirdparty: + name: Publish to buf.build/onsonr/thirdparty runs-on: ubuntu-latest - name: Publish to pkl.sh + steps: + # Run `git checkout` + - uses: actions/checkout@v3 + # Install the `buf` CLI + - uses: bufbuild/buf-setup-action@v1 + # Push only the Input in `proto` to the BSR + - uses: bufbuild/buf-push-action@v1 + continue-on-error: true + with: + input: third_party/proto + buf_token: ${{ secrets.BUF_TOKEN }} + + upload_motr_dwn: + runs-on: ubuntu-latest + name: Publish to configs.sonr.id steps: - name: checkout uses: actions/checkout@v4 - - name: Upload to R2 + + - uses: actions/setup-go@v5 + with: + go-version: "1.23" + check-latest: true + + - name: Setup go-task / task / taskfile + uses: rnorton5432/setup-task@v1 + + - name: Build DWN WASM + run: task dwn:build + + - name: Upload WASM to R2 + continue-on-error: true uses: ryand56/r2-upload-action@latest with: r2-account-id: ${{ secrets.R2_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }} r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }} - r2-bucket: pkljar - source-dir: pkl - destination-dir: . + r2-bucket: nebula + source-dir: ./build/app.wasm + destination-dir: wasm + + - name: Upload SW JS to R2 + continue-on-error: true + uses: ryand56/r2-upload-action@latest + with: + r2-account-id: ${{ secrets.R2_ACCOUNT_ID }} + r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }} + r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }} + r2-bucket: nebula + source-dir: ./pkg/motr/static/sw.js + destination-dir: js upload_nebula_cdn: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 1bf639ce3..7dd9471b5 100644 --- a/.gitignore +++ b/.gitignore @@ -71,7 +71,9 @@ deploy/**/data x/.DS_Store .aider* buildenv* -nebula/node_modules +node_modules +cmd/gateway/node_modules +pkg/nebula/node_modules mprocs.yaml build diff --git a/Makefile b/Makefile index f05600097..b12a05119 100644 --- a/Makefile +++ b/Makefile @@ -296,19 +296,14 @@ sh-testnet: mod-tidy .PHONY: templ-gen pkl-gen -assets-gen: - @echo "(assets) Generating gateway cloudflare workers assets" - go run github.com/syumai/workers/cmd/workers-assets-gen -mode=go -o ./cmd/hway/build - templ-gen: @echo "(templ) Generating templ files" templ generate pkl-gen: @echo "(pkl) Building PKL" - go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/DWN.pkl - go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/ORM.pkl - go run github.com/apple/pkl-go/cmd/pkl-gen-go ./pkl/Txns.pkl + go run github.com/apple/pkl-go/cmd/pkl-gen-go ./third_party/pkl/src/sonr.configs.v1/DWN.pkl + go run github.com/apple/pkl-go/cmd/pkl-gen-go ./third_party/pkl/src/sonr.models.v1/ORM.pkl ############################################################################### ### help ### diff --git a/Taskfile.yml b/Taskfile.yml index b46e78fd6..7c472ea43 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,37 +1,41 @@ version: "3" - vars: ROOT_DIR: sh: pwd tasks: + hway:assets: + internal: true + cmds: + - go run github.com/syumai/workers/cmd/workers-assets-gen -mode=go -o ./cmd/gateway/build + hway:build: - dir: cmd/hway + dir: cmd/gateway env: GOOS: js GOARCH: wasm cmds: + - task: hway:assets - go build -o build/app.wasm main.go hway:dev: - dir: cmd/hway + dir: cmd/gateway cmds: - task: nebula:build - bunx wrangler dev hway:deploy: - dir: cmd/hway + dir: cmd/gateway cmds: - task: nebula:build - bunx wrangler deploy - motr:build: - dir: internal/dwn + dwn:build: env: GOOS: js GOARCH: wasm cmds: - - go build -o app.wasm wasm/main.go + - go build -o build/app.wasm ./cmd/dwn/main.go nebula:build: dir: pkg/nebula @@ -40,3 +44,43 @@ tasks: - bun run deps.mjs - bunx tailwindcss -i ./global/styles/globals.css -o ./assets/css/styles.css - templ generate + + # ╭───────────────────────────────────────────────────────────╮ + # │ Registration Components │ + # ╰───────────────────────────────────────────────────────────╯ + + buf:push: + cmds: + - task: buf:push:sonr + - task: buf:push:thirdparty + + buf:deps: + cmds: + - task: buf:deps:sonr + - task: buf:deps:thirdparty + + buf:deps:sonr: + internal: true + dir: proto + cmds: + - buf dep update + + buf:deps:thirdparty: + internal: true + dir: third_party/proto + cmds: + - buf dep update + + buf:push:sonr: + internal: true + dir: proto + cmds: + - buf build + - buf push + + buf:push:thirdparty: + internal: true + dir: third_party/proto + cmds: + - buf build + - buf push diff --git a/api/did/module/v1/module.pulsar.go b/api/did/module/v1/module.pulsar.go index 460d51bc5..56d217580 100644 --- a/api/did/module/v1/module.pulsar.go +++ b/api/did/module/v1/module.pulsar.go @@ -104,9 +104,9 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -120,9 +120,9 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -136,9 +136,9 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro switch descriptor.FullName() { default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", descriptor.FullName())) } } @@ -156,9 +156,9 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -176,9 +176,9 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -189,9 +189,9 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.did.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.did.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -201,7 +201,7 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in onsonr.sonr.did.module.v1.Module", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in did.module.v1.Module", d.FullName())) } panic("unreachable") } @@ -414,29 +414,24 @@ var File_did_module_v1_module_proto protoreflect.FileDescriptor var file_did_module_v1_module_proto_rawDesc = []byte{ 0x0a, 0x1a, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x6e, - 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x6d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, - 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2e, 0x0a, 0x06, 0x4d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x3a, 0x24, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x1e, 0x0a, 0x1c, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, - 0x6f, 0x6e, 0x72, 0x2f, 0x78, 0x2f, 0x64, 0x69, 0x64, 0x42, 0xe8, 0x01, 0x0a, 0x1d, 0x63, 0x6f, - 0x6d, 0x2e, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x64, 0x69, - 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, - 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x04, - 0x4f, 0x53, 0x44, 0x4d, 0xaa, 0x02, 0x19, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x53, 0x6f, - 0x6e, 0x72, 0x2e, 0x44, 0x69, 0x64, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, - 0xca, 0x02, 0x19, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x5c, 0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x44, - 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x25, 0x4f, - 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x5c, 0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x44, 0x69, 0x64, 0x5c, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x53, - 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x69, + 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, + 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a, + 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, + 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, 0xa9, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, + 0x64, 0x69, 0x64, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, + 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x44, 0x4d, 0x58, 0xaa, 0x02, 0x0d, 0x44, 0x69, 0x64, 0x2e, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x44, 0x69, 0x64, 0x5c, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x0f, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -453,7 +448,7 @@ func file_did_module_v1_module_proto_rawDescGZIP() []byte { var file_did_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_did_module_v1_module_proto_goTypes = []interface{}{ - (*Module)(nil), // 0: onsonr.sonr.did.module.v1.Module + (*Module)(nil), // 0: did.module.v1.Module } var file_did_module_v1_module_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type diff --git a/api/did/v1/genesis.pulsar.go b/api/did/v1/genesis.pulsar.go index 5195e993a..ac24273bc 100644 --- a/api/did/v1/genesis.pulsar.go +++ b/api/did/v1/genesis.pulsar.go @@ -11,7 +11,6 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" reflect "reflect" - sort "sort" sync "sync" ) @@ -450,166 +449,268 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { } } -var _ protoreflect.Map = (*_Params_2_map)(nil) +var _ protoreflect.List = (*_Document_3_list)(nil) -type _Params_2_map struct { - m *map[string]*KeyInfo -} - -func (x *_Params_2_map) Len() int { - if x.m == nil { - return 0 - } - return len(*x.m) -} - -func (x *_Params_2_map) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { - if x.m == nil { - return - } - for k, v := range *x.m { - mapKey := (protoreflect.MapKey)(protoreflect.ValueOfString(k)) - mapValue := protoreflect.ValueOfMessage(v.ProtoReflect()) - if !f(mapKey, mapValue) { - break - } - } -} - -func (x *_Params_2_map) Has(key protoreflect.MapKey) bool { - if x.m == nil { - return false - } - keyUnwrapped := key.String() - concreteValue := keyUnwrapped - _, ok := (*x.m)[concreteValue] - return ok -} - -func (x *_Params_2_map) Clear(key protoreflect.MapKey) { - if x.m == nil { - return - } - keyUnwrapped := key.String() - concreteKey := keyUnwrapped - delete(*x.m, concreteKey) -} - -func (x *_Params_2_map) Get(key protoreflect.MapKey) protoreflect.Value { - if x.m == nil { - return protoreflect.Value{} - } - keyUnwrapped := key.String() - concreteKey := keyUnwrapped - v, ok := (*x.m)[concreteKey] - if !ok { - return protoreflect.Value{} - } - return protoreflect.ValueOfMessage(v.ProtoReflect()) -} - -func (x *_Params_2_map) Set(key protoreflect.MapKey, value protoreflect.Value) { - if !key.IsValid() || !value.IsValid() { - panic("invalid key or value provided") - } - keyUnwrapped := key.String() - concreteKey := keyUnwrapped - valueUnwrapped := value.Message() - concreteValue := valueUnwrapped.Interface().(*KeyInfo) - (*x.m)[concreteKey] = concreteValue -} - -func (x *_Params_2_map) Mutable(key protoreflect.MapKey) protoreflect.Value { - keyUnwrapped := key.String() - concreteKey := keyUnwrapped - v, ok := (*x.m)[concreteKey] - if ok { - return protoreflect.ValueOfMessage(v.ProtoReflect()) - } - newValue := new(KeyInfo) - (*x.m)[concreteKey] = newValue - return protoreflect.ValueOfMessage(newValue.ProtoReflect()) -} - -func (x *_Params_2_map) NewValue() protoreflect.Value { - v := new(KeyInfo) - return protoreflect.ValueOfMessage(v.ProtoReflect()) -} - -func (x *_Params_2_map) IsValid() bool { - return x.m != nil -} - -var _ protoreflect.List = (*_Params_4_list)(nil) - -type _Params_4_list struct { +type _Document_3_list struct { list *[]string } -func (x *_Params_4_list) Len() int { +func (x *_Document_3_list) Len() int { if x.list == nil { return 0 } return len(*x.list) } -func (x *_Params_4_list) Get(i int) protoreflect.Value { +func (x *_Document_3_list) Get(i int) protoreflect.Value { return protoreflect.ValueOfString((*x.list)[i]) } -func (x *_Params_4_list) Set(i int, value protoreflect.Value) { +func (x *_Document_3_list) Set(i int, value protoreflect.Value) { valueUnwrapped := value.String() concreteValue := valueUnwrapped (*x.list)[i] = concreteValue } -func (x *_Params_4_list) Append(value protoreflect.Value) { +func (x *_Document_3_list) Append(value protoreflect.Value) { valueUnwrapped := value.String() concreteValue := valueUnwrapped *x.list = append(*x.list, concreteValue) } -func (x *_Params_4_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Params at list field AttestationFormats as it is not of Message kind")) +func (x *_Document_3_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Document at list field Authentication as it is not of Message kind")) } -func (x *_Params_4_list) Truncate(n int) { +func (x *_Document_3_list) Truncate(n int) { *x.list = (*x.list)[:n] } -func (x *_Params_4_list) NewElement() protoreflect.Value { +func (x *_Document_3_list) NewElement() protoreflect.Value { v := "" return protoreflect.ValueOfString(v) } -func (x *_Params_4_list) IsValid() bool { +func (x *_Document_3_list) IsValid() bool { + return x.list != nil +} + +var _ protoreflect.List = (*_Document_4_list)(nil) + +type _Document_4_list struct { + list *[]string +} + +func (x *_Document_4_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Document_4_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Document_4_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Document_4_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Document_4_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Document at list field AssertionMethod as it is not of Message kind")) +} + +func (x *_Document_4_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Document_4_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Document_4_list) IsValid() bool { + return x.list != nil +} + +var _ protoreflect.List = (*_Document_5_list)(nil) + +type _Document_5_list struct { + list *[]string +} + +func (x *_Document_5_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Document_5_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Document_5_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Document_5_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Document_5_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Document at list field CapabilityDelegation as it is not of Message kind")) +} + +func (x *_Document_5_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Document_5_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Document_5_list) IsValid() bool { + return x.list != nil +} + +var _ protoreflect.List = (*_Document_6_list)(nil) + +type _Document_6_list struct { + list *[]string +} + +func (x *_Document_6_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Document_6_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Document_6_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Document_6_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Document_6_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Document at list field CapabilityInvocation as it is not of Message kind")) +} + +func (x *_Document_6_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Document_6_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Document_6_list) IsValid() bool { + return x.list != nil +} + +var _ protoreflect.List = (*_Document_7_list)(nil) + +type _Document_7_list struct { + list *[]string +} + +func (x *_Document_7_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Document_7_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Document_7_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Document_7_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Document_7_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Document at list field Service as it is not of Message kind")) +} + +func (x *_Document_7_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Document_7_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Document_7_list) IsValid() bool { return x.list != nil } var ( - md_Params protoreflect.MessageDescriptor - fd_Params_allowed_public_keys protoreflect.FieldDescriptor - fd_Params_conveyance_preference protoreflect.FieldDescriptor - fd_Params_attestation_formats protoreflect.FieldDescriptor + md_Document protoreflect.MessageDescriptor + fd_Document_id protoreflect.FieldDescriptor + fd_Document_controller protoreflect.FieldDescriptor + fd_Document_authentication protoreflect.FieldDescriptor + fd_Document_assertion_method protoreflect.FieldDescriptor + fd_Document_capability_delegation protoreflect.FieldDescriptor + fd_Document_capability_invocation protoreflect.FieldDescriptor + fd_Document_service protoreflect.FieldDescriptor ) func init() { file_did_v1_genesis_proto_init() - md_Params = File_did_v1_genesis_proto.Messages().ByName("Params") - fd_Params_allowed_public_keys = md_Params.Fields().ByName("allowed_public_keys") - fd_Params_conveyance_preference = md_Params.Fields().ByName("conveyance_preference") - fd_Params_attestation_formats = md_Params.Fields().ByName("attestation_formats") + md_Document = File_did_v1_genesis_proto.Messages().ByName("Document") + fd_Document_id = md_Document.Fields().ByName("id") + fd_Document_controller = md_Document.Fields().ByName("controller") + fd_Document_authentication = md_Document.Fields().ByName("authentication") + fd_Document_assertion_method = md_Document.Fields().ByName("assertion_method") + fd_Document_capability_delegation = md_Document.Fields().ByName("capability_delegation") + fd_Document_capability_invocation = md_Document.Fields().ByName("capability_invocation") + fd_Document_service = md_Document.Fields().ByName("service") } -var _ protoreflect.Message = (*fastReflection_Params)(nil) +var _ protoreflect.Message = (*fastReflection_Document)(nil) -type fastReflection_Params Params +type fastReflection_Document Document -func (x *Params) ProtoReflect() protoreflect.Message { - return (*fastReflection_Params)(x) +func (x *Document) ProtoReflect() protoreflect.Message { + return (*fastReflection_Document)(x) } -func (x *Params) slowProtoReflect() protoreflect.Message { +func (x *Document) slowProtoReflect() protoreflect.Message { mi := &file_did_v1_genesis_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -621,43 +722,43 @@ func (x *Params) slowProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -var _fastReflection_Params_messageType fastReflection_Params_messageType -var _ protoreflect.MessageType = fastReflection_Params_messageType{} +var _fastReflection_Document_messageType fastReflection_Document_messageType +var _ protoreflect.MessageType = fastReflection_Document_messageType{} -type fastReflection_Params_messageType struct{} +type fastReflection_Document_messageType struct{} -func (x fastReflection_Params_messageType) Zero() protoreflect.Message { - return (*fastReflection_Params)(nil) +func (x fastReflection_Document_messageType) Zero() protoreflect.Message { + return (*fastReflection_Document)(nil) } -func (x fastReflection_Params_messageType) New() protoreflect.Message { - return new(fastReflection_Params) +func (x fastReflection_Document_messageType) New() protoreflect.Message { + return new(fastReflection_Document) } -func (x fastReflection_Params_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Params +func (x fastReflection_Document_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Document } // Descriptor returns message descriptor, which contains only the protobuf // type information for the message. -func (x *fastReflection_Params) Descriptor() protoreflect.MessageDescriptor { - return md_Params +func (x *fastReflection_Document) Descriptor() protoreflect.MessageDescriptor { + return md_Document } // Type returns the message type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the message descriptor be used instead. -func (x *fastReflection_Params) Type() protoreflect.MessageType { - return _fastReflection_Params_messageType +func (x *fastReflection_Document) Type() protoreflect.MessageType { + return _fastReflection_Document_messageType } // New returns a newly allocated and mutable empty message. -func (x *fastReflection_Params) New() protoreflect.Message { - return new(fastReflection_Params) +func (x *fastReflection_Document) New() protoreflect.Message { + return new(fastReflection_Document) } // Interface unwraps the message reflection interface and // returns the underlying ProtoMessage interface. -func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { - return (*Params)(x) +func (x *fastReflection_Document) Interface() protoreflect.ProtoMessage { + return (*Document)(x) } // Range iterates over every populated field in an undefined order, @@ -665,22 +766,46 @@ func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { // Range returns immediately if f returns false. // While iterating, mutating operations may only be performed // on the current field descriptor. -func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if len(x.AllowedPublicKeys) != 0 { - value := protoreflect.ValueOfMap(&_Params_2_map{m: &x.AllowedPublicKeys}) - if !f(fd_Params_allowed_public_keys, value) { +func (x *fastReflection_Document) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Id != "" { + value := protoreflect.ValueOfString(x.Id) + if !f(fd_Document_id, value) { return } } - if x.ConveyancePreference != "" { - value := protoreflect.ValueOfString(x.ConveyancePreference) - if !f(fd_Params_conveyance_preference, value) { + if x.Controller != "" { + value := protoreflect.ValueOfString(x.Controller) + if !f(fd_Document_controller, value) { return } } - if len(x.AttestationFormats) != 0 { - value := protoreflect.ValueOfList(&_Params_4_list{list: &x.AttestationFormats}) - if !f(fd_Params_attestation_formats, value) { + if len(x.Authentication) != 0 { + value := protoreflect.ValueOfList(&_Document_3_list{list: &x.Authentication}) + if !f(fd_Document_authentication, value) { + return + } + } + if len(x.AssertionMethod) != 0 { + value := protoreflect.ValueOfList(&_Document_4_list{list: &x.AssertionMethod}) + if !f(fd_Document_assertion_method, value) { + return + } + } + if len(x.CapabilityDelegation) != 0 { + value := protoreflect.ValueOfList(&_Document_5_list{list: &x.CapabilityDelegation}) + if !f(fd_Document_capability_delegation, value) { + return + } + } + if len(x.CapabilityInvocation) != 0 { + value := protoreflect.ValueOfList(&_Document_6_list{list: &x.CapabilityInvocation}) + if !f(fd_Document_capability_invocation, value) { + return + } + } + if len(x.Service) != 0 { + value := protoreflect.ValueOfList(&_Document_7_list{list: &x.Service}) + if !f(fd_Document_service, value) { return } } @@ -697,19 +822,27 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto // In other cases (aside from the nullable cases above), // a proto3 scalar field is populated if it contains a non-zero value, and // a repeated field is populated if it is non-empty. -func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { +func (x *fastReflection_Document) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "did.v1.Params.allowed_public_keys": - return len(x.AllowedPublicKeys) != 0 - case "did.v1.Params.conveyance_preference": - return x.ConveyancePreference != "" - case "did.v1.Params.attestation_formats": - return len(x.AttestationFormats) != 0 + case "did.v1.Document.id": + return x.Id != "" + case "did.v1.Document.controller": + return x.Controller != "" + case "did.v1.Document.authentication": + return len(x.Authentication) != 0 + case "did.v1.Document.assertion_method": + return len(x.AssertionMethod) != 0 + case "did.v1.Document.capability_delegation": + return len(x.CapabilityDelegation) != 0 + case "did.v1.Document.capability_invocation": + return len(x.CapabilityInvocation) != 0 + case "did.v1.Document.service": + return len(x.Service) != 0 default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) } - panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) } } @@ -719,19 +852,27 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { // associated with the given field number. // // Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { +func (x *fastReflection_Document) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "did.v1.Params.allowed_public_keys": - x.AllowedPublicKeys = nil - case "did.v1.Params.conveyance_preference": - x.ConveyancePreference = "" - case "did.v1.Params.attestation_formats": - x.AttestationFormats = nil + case "did.v1.Document.id": + x.Id = "" + case "did.v1.Document.controller": + x.Controller = "" + case "did.v1.Document.authentication": + x.Authentication = nil + case "did.v1.Document.assertion_method": + x.AssertionMethod = nil + case "did.v1.Document.capability_delegation": + x.CapabilityDelegation = nil + case "did.v1.Document.capability_invocation": + x.CapabilityInvocation = nil + case "did.v1.Document.service": + x.Service = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) } - panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) } } @@ -741,28 +882,49 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { // the default value of a bytes scalar is guaranteed to be a copy. // For unpopulated composite types, it returns an empty, read-only view // of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Document) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "did.v1.Params.allowed_public_keys": - if len(x.AllowedPublicKeys) == 0 { - return protoreflect.ValueOfMap(&_Params_2_map{}) - } - mapValue := &_Params_2_map{m: &x.AllowedPublicKeys} - return protoreflect.ValueOfMap(mapValue) - case "did.v1.Params.conveyance_preference": - value := x.ConveyancePreference + case "did.v1.Document.id": + value := x.Id return protoreflect.ValueOfString(value) - case "did.v1.Params.attestation_formats": - if len(x.AttestationFormats) == 0 { - return protoreflect.ValueOfList(&_Params_4_list{}) + case "did.v1.Document.controller": + value := x.Controller + return protoreflect.ValueOfString(value) + case "did.v1.Document.authentication": + if len(x.Authentication) == 0 { + return protoreflect.ValueOfList(&_Document_3_list{}) } - listValue := &_Params_4_list{list: &x.AttestationFormats} + listValue := &_Document_3_list{list: &x.Authentication} + return protoreflect.ValueOfList(listValue) + case "did.v1.Document.assertion_method": + if len(x.AssertionMethod) == 0 { + return protoreflect.ValueOfList(&_Document_4_list{}) + } + listValue := &_Document_4_list{list: &x.AssertionMethod} + return protoreflect.ValueOfList(listValue) + case "did.v1.Document.capability_delegation": + if len(x.CapabilityDelegation) == 0 { + return protoreflect.ValueOfList(&_Document_5_list{}) + } + listValue := &_Document_5_list{list: &x.CapabilityDelegation} + return protoreflect.ValueOfList(listValue) + case "did.v1.Document.capability_invocation": + if len(x.CapabilityInvocation) == 0 { + return protoreflect.ValueOfList(&_Document_6_list{}) + } + listValue := &_Document_6_list{list: &x.CapabilityInvocation} + return protoreflect.ValueOfList(listValue) + case "did.v1.Document.service": + if len(x.Service) == 0 { + return protoreflect.ValueOfList(&_Document_7_list{}) + } + listValue := &_Document_7_list{list: &x.Service} return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) } - panic(fmt.Errorf("message did.v1.Params does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message did.v1.Document does not contain field %s", descriptor.FullName())) } } @@ -776,23 +938,37 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro // empty, read-only value, then it panics. // // Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { +func (x *fastReflection_Document) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "did.v1.Params.allowed_public_keys": - mv := value.Map() - cmv := mv.(*_Params_2_map) - x.AllowedPublicKeys = *cmv.m - case "did.v1.Params.conveyance_preference": - x.ConveyancePreference = value.Interface().(string) - case "did.v1.Params.attestation_formats": + case "did.v1.Document.id": + x.Id = value.Interface().(string) + case "did.v1.Document.controller": + x.Controller = value.Interface().(string) + case "did.v1.Document.authentication": lv := value.List() - clv := lv.(*_Params_4_list) - x.AttestationFormats = *clv.list + clv := lv.(*_Document_3_list) + x.Authentication = *clv.list + case "did.v1.Document.assertion_method": + lv := value.List() + clv := lv.(*_Document_4_list) + x.AssertionMethod = *clv.list + case "did.v1.Document.capability_delegation": + lv := value.List() + clv := lv.(*_Document_5_list) + x.CapabilityDelegation = *clv.list + case "did.v1.Document.capability_invocation": + lv := value.List() + clv := lv.(*_Document_6_list) + x.CapabilityInvocation = *clv.list + case "did.v1.Document.service": + lv := value.List() + clv := lv.(*_Document_7_list) + x.Service = *clv.list default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) } - panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) } } @@ -806,58 +982,89 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto // It panics if the field does not contain a composite type. // // Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Document) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Params.allowed_public_keys": - if x.AllowedPublicKeys == nil { - x.AllowedPublicKeys = make(map[string]*KeyInfo) + case "did.v1.Document.authentication": + if x.Authentication == nil { + x.Authentication = []string{} } - value := &_Params_2_map{m: &x.AllowedPublicKeys} - return protoreflect.ValueOfMap(value) - case "did.v1.Params.attestation_formats": - if x.AttestationFormats == nil { - x.AttestationFormats = []string{} - } - value := &_Params_4_list{list: &x.AttestationFormats} + value := &_Document_3_list{list: &x.Authentication} return protoreflect.ValueOfList(value) - case "did.v1.Params.conveyance_preference": - panic(fmt.Errorf("field conveyance_preference of message did.v1.Params is not mutable")) + case "did.v1.Document.assertion_method": + if x.AssertionMethod == nil { + x.AssertionMethod = []string{} + } + value := &_Document_4_list{list: &x.AssertionMethod} + return protoreflect.ValueOfList(value) + case "did.v1.Document.capability_delegation": + if x.CapabilityDelegation == nil { + x.CapabilityDelegation = []string{} + } + value := &_Document_5_list{list: &x.CapabilityDelegation} + return protoreflect.ValueOfList(value) + case "did.v1.Document.capability_invocation": + if x.CapabilityInvocation == nil { + x.CapabilityInvocation = []string{} + } + value := &_Document_6_list{list: &x.CapabilityInvocation} + return protoreflect.ValueOfList(value) + case "did.v1.Document.service": + if x.Service == nil { + x.Service = []string{} + } + value := &_Document_7_list{list: &x.Service} + return protoreflect.ValueOfList(value) + case "did.v1.Document.id": + panic(fmt.Errorf("field id of message did.v1.Document is not mutable")) + case "did.v1.Document.controller": + panic(fmt.Errorf("field controller of message did.v1.Document is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) } - panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) } } // NewField returns a new value that is assignable to the field // for the given descriptor. For scalars, this returns the default value. // For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Document) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Params.allowed_public_keys": - m := make(map[string]*KeyInfo) - return protoreflect.ValueOfMap(&_Params_2_map{m: &m}) - case "did.v1.Params.conveyance_preference": + case "did.v1.Document.id": return protoreflect.ValueOfString("") - case "did.v1.Params.attestation_formats": + case "did.v1.Document.controller": + return protoreflect.ValueOfString("") + case "did.v1.Document.authentication": list := []string{} - return protoreflect.ValueOfList(&_Params_4_list{list: &list}) + return protoreflect.ValueOfList(&_Document_3_list{list: &list}) + case "did.v1.Document.assertion_method": + list := []string{} + return protoreflect.ValueOfList(&_Document_4_list{list: &list}) + case "did.v1.Document.capability_delegation": + list := []string{} + return protoreflect.ValueOfList(&_Document_5_list{list: &list}) + case "did.v1.Document.capability_invocation": + list := []string{} + return protoreflect.ValueOfList(&_Document_6_list{list: &list}) + case "did.v1.Document.service": + list := []string{} + return protoreflect.ValueOfList(&_Document_7_list{list: &list}) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) } - panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) } } // WhichOneof reports which field within the oneof is populated, // returning nil if none are populated. // It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { +func (x *fastReflection_Document) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Params", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in did.v1.Document", d.FullName())) } panic("unreachable") } @@ -865,7 +1072,7 @@ func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) proto // GetUnknown retrieves the entire list of unknown fields. // The caller may only mutate the contents of the RawFields // if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Params) GetUnknown() protoreflect.RawFields { +func (x *fastReflection_Document) GetUnknown() protoreflect.RawFields { return x.unknownFields } @@ -876,7 +1083,7 @@ func (x *fastReflection_Params) GetUnknown() protoreflect.RawFields { // An empty RawFields may be passed to clear the fields. // // SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) SetUnknown(fields protoreflect.RawFields) { +func (x *fastReflection_Document) SetUnknown(fields protoreflect.RawFields) { x.unknownFields = fields } @@ -888,7 +1095,7 @@ func (x *fastReflection_Params) SetUnknown(fields protoreflect.RawFields) { // message type, but the details are implementation dependent. // Validity is not part of the protobuf data model, and may not // be preserved in marshaling or other operations. -func (x *fastReflection_Params) IsValid() bool { +func (x *fastReflection_Document) IsValid() bool { return x != nil } @@ -898,9 +1105,9 @@ func (x *fastReflection_Params) IsValid() bool { // The returned methods type is identical to // "google.golang.org/protobuf/runtime/protoiface".Methods. // Consult the protoiface package documentation for details. -func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { +func (x *fastReflection_Document) ProtoMethods() *protoiface.Methods { size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Params) + x := input.Message.Interface().(*Document) if x == nil { return protoiface.SizeOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -912,38 +1119,40 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { var n int var l int _ = l - if len(x.AllowedPublicKeys) > 0 { - SiZeMaP := func(k string, v *KeyInfo) { - l := 0 - if v != nil { - l = options.Size(v) - } - l += 1 + runtime.Sov(uint64(l)) - mapEntrySize := 1 + len(k) + runtime.Sov(uint64(len(k))) + l - n += mapEntrySize + 1 + runtime.Sov(uint64(mapEntrySize)) - } - if options.Deterministic { - sortme := make([]string, 0, len(x.AllowedPublicKeys)) - for k := range x.AllowedPublicKeys { - sortme = append(sortme, k) - } - sort.Strings(sortme) - for _, k := range sortme { - v := x.AllowedPublicKeys[k] - SiZeMaP(k, v) - } - } else { - for k, v := range x.AllowedPublicKeys { - SiZeMaP(k, v) - } - } - } - l = len(x.ConveyancePreference) + l = len(x.Id) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if len(x.AttestationFormats) > 0 { - for _, s := range x.AttestationFormats { + l = len(x.Controller) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.Authentication) > 0 { + for _, s := range x.Authentication { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if len(x.AssertionMethod) > 0 { + for _, s := range x.AssertionMethod { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if len(x.CapabilityDelegation) > 0 { + for _, s := range x.CapabilityDelegation { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if len(x.CapabilityInvocation) > 0 { + for _, s := range x.CapabilityInvocation { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if len(x.Service) > 0 { + for _, s := range x.Service { l = len(s) n += 1 + l + runtime.Sov(uint64(l)) } @@ -958,7 +1167,7 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Params) + x := input.Message.Interface().(*Document) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -977,746 +1186,62 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if len(x.AttestationFormats) > 0 { - for iNdEx := len(x.AttestationFormats) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.AttestationFormats[iNdEx]) - copy(dAtA[i:], x.AttestationFormats[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.AttestationFormats[iNdEx]))) + if len(x.Service) > 0 { + for iNdEx := len(x.Service) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Service[iNdEx]) + copy(dAtA[i:], x.Service[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Service[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if len(x.CapabilityInvocation) > 0 { + for iNdEx := len(x.CapabilityInvocation) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.CapabilityInvocation[iNdEx]) + copy(dAtA[i:], x.CapabilityInvocation[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.CapabilityInvocation[iNdEx]))) + i-- + dAtA[i] = 0x32 + } + } + if len(x.CapabilityDelegation) > 0 { + for iNdEx := len(x.CapabilityDelegation) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.CapabilityDelegation[iNdEx]) + copy(dAtA[i:], x.CapabilityDelegation[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.CapabilityDelegation[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + if len(x.AssertionMethod) > 0 { + for iNdEx := len(x.AssertionMethod) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.AssertionMethod[iNdEx]) + copy(dAtA[i:], x.AssertionMethod[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.AssertionMethod[iNdEx]))) i-- dAtA[i] = 0x22 } } - if len(x.ConveyancePreference) > 0 { - i -= len(x.ConveyancePreference) - copy(dAtA[i:], x.ConveyancePreference) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ConveyancePreference))) - i-- - dAtA[i] = 0x1a - } - if len(x.AllowedPublicKeys) > 0 { - MaRsHaLmAp := func(k string, v *KeyInfo) (protoiface.MarshalOutput, error) { - baseI := i - encoded, err := options.Marshal(v) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + if len(x.Authentication) > 0 { + for iNdEx := len(x.Authentication) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Authentication[iNdEx]) + copy(dAtA[i:], x.Authentication[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authentication[iNdEx]))) i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = runtime.EncodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = runtime.EncodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x12 - return protoiface.MarshalOutput{}, nil - } - if options.Deterministic { - keysForAllowedPublicKeys := make([]string, 0, len(x.AllowedPublicKeys)) - for k := range x.AllowedPublicKeys { - keysForAllowedPublicKeys = append(keysForAllowedPublicKeys, string(k)) - } - sort.Slice(keysForAllowedPublicKeys, func(i, j int) bool { - return keysForAllowedPublicKeys[i] < keysForAllowedPublicKeys[j] - }) - for iNdEx := len(keysForAllowedPublicKeys) - 1; iNdEx >= 0; iNdEx-- { - v := x.AllowedPublicKeys[string(keysForAllowedPublicKeys[iNdEx])] - out, err := MaRsHaLmAp(keysForAllowedPublicKeys[iNdEx], v) - if err != nil { - return out, err - } - } - } else { - for k := range x.AllowedPublicKeys { - v := x.AllowedPublicKeys[k] - out, err := MaRsHaLmAp(k, v) - if err != nil { - return out, err - } - } + dAtA[i] = 0x1a } } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Params) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AllowedPublicKeys", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.AllowedPublicKeys == nil { - x.AllowedPublicKeys = make(map[string]*KeyInfo) - } - var mapkey string - var mapvalue *KeyInfo - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postStringIndexmapkey > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postmsgIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - mapvalue = &KeyInfo{} - if err := options.Unmarshal(dAtA[iNdEx:postmsgIndex], mapvalue); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - x.AllowedPublicKeys[mapkey] = mapvalue - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ConveyancePreference", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.ConveyancePreference = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AttestationFormats", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.AttestationFormats = append(x.AttestationFormats, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_KeyInfo protoreflect.MessageDescriptor - fd_KeyInfo_role protoreflect.FieldDescriptor - fd_KeyInfo_algorithm protoreflect.FieldDescriptor - fd_KeyInfo_encoding protoreflect.FieldDescriptor - fd_KeyInfo_curve protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_genesis_proto_init() - md_KeyInfo = File_did_v1_genesis_proto.Messages().ByName("KeyInfo") - fd_KeyInfo_role = md_KeyInfo.Fields().ByName("role") - fd_KeyInfo_algorithm = md_KeyInfo.Fields().ByName("algorithm") - fd_KeyInfo_encoding = md_KeyInfo.Fields().ByName("encoding") - fd_KeyInfo_curve = md_KeyInfo.Fields().ByName("curve") -} - -var _ protoreflect.Message = (*fastReflection_KeyInfo)(nil) - -type fastReflection_KeyInfo KeyInfo - -func (x *KeyInfo) ProtoReflect() protoreflect.Message { - return (*fastReflection_KeyInfo)(x) -} - -func (x *KeyInfo) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_genesis_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_KeyInfo_messageType fastReflection_KeyInfo_messageType -var _ protoreflect.MessageType = fastReflection_KeyInfo_messageType{} - -type fastReflection_KeyInfo_messageType struct{} - -func (x fastReflection_KeyInfo_messageType) Zero() protoreflect.Message { - return (*fastReflection_KeyInfo)(nil) -} -func (x fastReflection_KeyInfo_messageType) New() protoreflect.Message { - return new(fastReflection_KeyInfo) -} -func (x fastReflection_KeyInfo_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_KeyInfo -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_KeyInfo) Descriptor() protoreflect.MessageDescriptor { - return md_KeyInfo -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_KeyInfo) Type() protoreflect.MessageType { - return _fastReflection_KeyInfo_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_KeyInfo) New() protoreflect.Message { - return new(fastReflection_KeyInfo) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_KeyInfo) Interface() protoreflect.ProtoMessage { - return (*KeyInfo)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_KeyInfo) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Role != "" { - value := protoreflect.ValueOfString(x.Role) - if !f(fd_KeyInfo_role, value) { - return - } - } - if x.Algorithm != "" { - value := protoreflect.ValueOfString(x.Algorithm) - if !f(fd_KeyInfo_algorithm, value) { - return - } - } - if x.Encoding != "" { - value := protoreflect.ValueOfString(x.Encoding) - if !f(fd_KeyInfo_encoding, value) { - return - } - } - if x.Curve != "" { - value := protoreflect.ValueOfString(x.Curve) - if !f(fd_KeyInfo_curve, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_KeyInfo) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.KeyInfo.role": - return x.Role != "" - case "did.v1.KeyInfo.algorithm": - return x.Algorithm != "" - case "did.v1.KeyInfo.encoding": - return x.Encoding != "" - case "did.v1.KeyInfo.curve": - return x.Curve != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) - } - panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_KeyInfo) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.KeyInfo.role": - x.Role = "" - case "did.v1.KeyInfo.algorithm": - x.Algorithm = "" - case "did.v1.KeyInfo.encoding": - x.Encoding = "" - case "did.v1.KeyInfo.curve": - x.Curve = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) - } - panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_KeyInfo) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.KeyInfo.role": - value := x.Role - return protoreflect.ValueOfString(value) - case "did.v1.KeyInfo.algorithm": - value := x.Algorithm - return protoreflect.ValueOfString(value) - case "did.v1.KeyInfo.encoding": - value := x.Encoding - return protoreflect.ValueOfString(value) - case "did.v1.KeyInfo.curve": - value := x.Curve - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) - } - panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_KeyInfo) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.KeyInfo.role": - x.Role = value.Interface().(string) - case "did.v1.KeyInfo.algorithm": - x.Algorithm = value.Interface().(string) - case "did.v1.KeyInfo.encoding": - x.Encoding = value.Interface().(string) - case "did.v1.KeyInfo.curve": - x.Curve = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) - } - panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_KeyInfo) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.KeyInfo.role": - panic(fmt.Errorf("field role of message did.v1.KeyInfo is not mutable")) - case "did.v1.KeyInfo.algorithm": - panic(fmt.Errorf("field algorithm of message did.v1.KeyInfo is not mutable")) - case "did.v1.KeyInfo.encoding": - panic(fmt.Errorf("field encoding of message did.v1.KeyInfo is not mutable")) - case "did.v1.KeyInfo.curve": - panic(fmt.Errorf("field curve of message did.v1.KeyInfo is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) - } - panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_KeyInfo) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.KeyInfo.role": - return protoreflect.ValueOfString("") - case "did.v1.KeyInfo.algorithm": - return protoreflect.ValueOfString("") - case "did.v1.KeyInfo.encoding": - return protoreflect.ValueOfString("") - case "did.v1.KeyInfo.curve": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) - } - panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_KeyInfo) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.KeyInfo", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_KeyInfo) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_KeyInfo) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_KeyInfo) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_KeyInfo) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*KeyInfo) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Role) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Algorithm) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Encoding) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Curve) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*KeyInfo) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Curve) > 0 { - i -= len(x.Curve) - copy(dAtA[i:], x.Curve) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Curve))) - i-- - dAtA[i] = 0x22 - } - if len(x.Encoding) > 0 { - i -= len(x.Encoding) - copy(dAtA[i:], x.Encoding) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Encoding))) - i-- - dAtA[i] = 0x1a - } - if len(x.Algorithm) > 0 { - i -= len(x.Algorithm) - copy(dAtA[i:], x.Algorithm) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Algorithm))) + if len(x.Controller) > 0 { + i -= len(x.Controller) + copy(dAtA[i:], x.Controller) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) i-- dAtA[i] = 0x12 } - if len(x.Role) > 0 { - i -= len(x.Role) - copy(dAtA[i:], x.Role) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Role))) + if len(x.Id) > 0 { + i -= len(x.Id) + copy(dAtA[i:], x.Id) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Id))) i-- dAtA[i] = 0xa } @@ -1731,7 +1256,7 @@ func (x *fastReflection_KeyInfo) ProtoMethods() *protoiface.Methods { }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*KeyInfo) + x := input.Message.Interface().(*Document) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -1763,15 +1288,15 @@ func (x *fastReflection_KeyInfo) ProtoMethods() *protoiface.Methods { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: KeyInfo: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Document: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: KeyInfo: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Document: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1799,11 +1324,11 @@ func (x *fastReflection_KeyInfo) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Role = string(dAtA[iNdEx:postIndex]) + x.Id = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Algorithm", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1831,11 +1356,11 @@ func (x *fastReflection_KeyInfo) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Algorithm = string(dAtA[iNdEx:postIndex]) + x.Controller = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Encoding", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authentication", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1863,11 +1388,11 @@ func (x *fastReflection_KeyInfo) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Encoding = string(dAtA[iNdEx:postIndex]) + x.Authentication = append(x.Authentication, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 4: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Curve", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AssertionMethod", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1895,1861 +1420,11 @@ func (x *fastReflection_KeyInfo) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Curve = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_Keyshares protoreflect.MessageDescriptor - fd_Keyshares_validator_cid protoreflect.FieldDescriptor - fd_Keyshares_user_cid protoreflect.FieldDescriptor - fd_Keyshares_last_updated_block protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_genesis_proto_init() - md_Keyshares = File_did_v1_genesis_proto.Messages().ByName("Keyshares") - fd_Keyshares_validator_cid = md_Keyshares.Fields().ByName("validator_cid") - fd_Keyshares_user_cid = md_Keyshares.Fields().ByName("user_cid") - fd_Keyshares_last_updated_block = md_Keyshares.Fields().ByName("last_updated_block") -} - -var _ protoreflect.Message = (*fastReflection_Keyshares)(nil) - -type fastReflection_Keyshares Keyshares - -func (x *Keyshares) ProtoReflect() protoreflect.Message { - return (*fastReflection_Keyshares)(x) -} - -func (x *Keyshares) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_genesis_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Keyshares_messageType fastReflection_Keyshares_messageType -var _ protoreflect.MessageType = fastReflection_Keyshares_messageType{} - -type fastReflection_Keyshares_messageType struct{} - -func (x fastReflection_Keyshares_messageType) Zero() protoreflect.Message { - return (*fastReflection_Keyshares)(nil) -} -func (x fastReflection_Keyshares_messageType) New() protoreflect.Message { - return new(fastReflection_Keyshares) -} -func (x fastReflection_Keyshares_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Keyshares -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Keyshares) Descriptor() protoreflect.MessageDescriptor { - return md_Keyshares -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Keyshares) Type() protoreflect.MessageType { - return _fastReflection_Keyshares_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Keyshares) New() protoreflect.Message { - return new(fastReflection_Keyshares) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Keyshares) Interface() protoreflect.ProtoMessage { - return (*Keyshares)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Keyshares) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.ValidatorCid != "" { - value := protoreflect.ValueOfString(x.ValidatorCid) - if !f(fd_Keyshares_validator_cid, value) { - return - } - } - if x.UserCid != "" { - value := protoreflect.ValueOfString(x.UserCid) - if !f(fd_Keyshares_user_cid, value) { - return - } - } - if x.LastUpdatedBlock != int64(0) { - value := protoreflect.ValueOfInt64(x.LastUpdatedBlock) - if !f(fd_Keyshares_last_updated_block, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Keyshares) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.Keyshares.validator_cid": - return x.ValidatorCid != "" - case "did.v1.Keyshares.user_cid": - return x.UserCid != "" - case "did.v1.Keyshares.last_updated_block": - return x.LastUpdatedBlock != int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Keyshares")) - } - panic(fmt.Errorf("message did.v1.Keyshares does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Keyshares) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.Keyshares.validator_cid": - x.ValidatorCid = "" - case "did.v1.Keyshares.user_cid": - x.UserCid = "" - case "did.v1.Keyshares.last_updated_block": - x.LastUpdatedBlock = int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Keyshares")) - } - panic(fmt.Errorf("message did.v1.Keyshares does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Keyshares) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.Keyshares.validator_cid": - value := x.ValidatorCid - return protoreflect.ValueOfString(value) - case "did.v1.Keyshares.user_cid": - value := x.UserCid - return protoreflect.ValueOfString(value) - case "did.v1.Keyshares.last_updated_block": - value := x.LastUpdatedBlock - return protoreflect.ValueOfInt64(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Keyshares")) - } - panic(fmt.Errorf("message did.v1.Keyshares does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Keyshares) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.Keyshares.validator_cid": - x.ValidatorCid = value.Interface().(string) - case "did.v1.Keyshares.user_cid": - x.UserCid = value.Interface().(string) - case "did.v1.Keyshares.last_updated_block": - x.LastUpdatedBlock = value.Int() - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Keyshares")) - } - panic(fmt.Errorf("message did.v1.Keyshares does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Keyshares) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Keyshares.validator_cid": - panic(fmt.Errorf("field validator_cid of message did.v1.Keyshares is not mutable")) - case "did.v1.Keyshares.user_cid": - panic(fmt.Errorf("field user_cid of message did.v1.Keyshares is not mutable")) - case "did.v1.Keyshares.last_updated_block": - panic(fmt.Errorf("field last_updated_block of message did.v1.Keyshares is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Keyshares")) - } - panic(fmt.Errorf("message did.v1.Keyshares does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Keyshares) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Keyshares.validator_cid": - return protoreflect.ValueOfString("") - case "did.v1.Keyshares.user_cid": - return protoreflect.ValueOfString("") - case "did.v1.Keyshares.last_updated_block": - return protoreflect.ValueOfInt64(int64(0)) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Keyshares")) - } - panic(fmt.Errorf("message did.v1.Keyshares does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Keyshares) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Keyshares", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Keyshares) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Keyshares) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Keyshares) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Keyshares) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Keyshares) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.ValidatorCid) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.UserCid) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.LastUpdatedBlock != 0 { - n += 1 + runtime.Sov(uint64(x.LastUpdatedBlock)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Keyshares) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.LastUpdatedBlock != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.LastUpdatedBlock)) - i-- - dAtA[i] = 0x18 - } - if len(x.UserCid) > 0 { - i -= len(x.UserCid) - copy(dAtA[i:], x.UserCid) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.UserCid))) - i-- - dAtA[i] = 0x12 - } - if len(x.ValidatorCid) > 0 { - i -= len(x.ValidatorCid) - copy(dAtA[i:], x.ValidatorCid) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ValidatorCid))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Keyshares) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Keyshares: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Keyshares: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ValidatorCid", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.ValidatorCid = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field UserCid", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.UserCid = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field LastUpdatedBlock", wireType) - } - x.LastUpdatedBlock = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.LastUpdatedBlock |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_PubKey protoreflect.MessageDescriptor - fd_PubKey_role protoreflect.FieldDescriptor - fd_PubKey_key_type protoreflect.FieldDescriptor - fd_PubKey_raw_key protoreflect.FieldDescriptor - fd_PubKey_jwk protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_genesis_proto_init() - md_PubKey = File_did_v1_genesis_proto.Messages().ByName("PubKey") - fd_PubKey_role = md_PubKey.Fields().ByName("role") - fd_PubKey_key_type = md_PubKey.Fields().ByName("key_type") - fd_PubKey_raw_key = md_PubKey.Fields().ByName("raw_key") - fd_PubKey_jwk = md_PubKey.Fields().ByName("jwk") -} - -var _ protoreflect.Message = (*fastReflection_PubKey)(nil) - -type fastReflection_PubKey PubKey - -func (x *PubKey) ProtoReflect() protoreflect.Message { - return (*fastReflection_PubKey)(x) -} - -func (x *PubKey) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_genesis_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_PubKey_messageType fastReflection_PubKey_messageType -var _ protoreflect.MessageType = fastReflection_PubKey_messageType{} - -type fastReflection_PubKey_messageType struct{} - -func (x fastReflection_PubKey_messageType) Zero() protoreflect.Message { - return (*fastReflection_PubKey)(nil) -} -func (x fastReflection_PubKey_messageType) New() protoreflect.Message { - return new(fastReflection_PubKey) -} -func (x fastReflection_PubKey_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_PubKey -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_PubKey) Descriptor() protoreflect.MessageDescriptor { - return md_PubKey -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_PubKey) Type() protoreflect.MessageType { - return _fastReflection_PubKey_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_PubKey) New() protoreflect.Message { - return new(fastReflection_PubKey) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_PubKey) Interface() protoreflect.ProtoMessage { - return (*PubKey)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_PubKey) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Role != "" { - value := protoreflect.ValueOfString(x.Role) - if !f(fd_PubKey_role, value) { - return - } - } - if x.KeyType != "" { - value := protoreflect.ValueOfString(x.KeyType) - if !f(fd_PubKey_key_type, value) { - return - } - } - if x.RawKey != nil { - value := protoreflect.ValueOfMessage(x.RawKey.ProtoReflect()) - if !f(fd_PubKey_raw_key, value) { - return - } - } - if x.Jwk != nil { - value := protoreflect.ValueOfMessage(x.Jwk.ProtoReflect()) - if !f(fd_PubKey_jwk, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_PubKey) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.PubKey.role": - return x.Role != "" - case "did.v1.PubKey.key_type": - return x.KeyType != "" - case "did.v1.PubKey.raw_key": - return x.RawKey != nil - case "did.v1.PubKey.jwk": - return x.Jwk != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PubKey")) - } - panic(fmt.Errorf("message did.v1.PubKey does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_PubKey) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.PubKey.role": - x.Role = "" - case "did.v1.PubKey.key_type": - x.KeyType = "" - case "did.v1.PubKey.raw_key": - x.RawKey = nil - case "did.v1.PubKey.jwk": - x.Jwk = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PubKey")) - } - panic(fmt.Errorf("message did.v1.PubKey does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_PubKey) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.PubKey.role": - value := x.Role - return protoreflect.ValueOfString(value) - case "did.v1.PubKey.key_type": - value := x.KeyType - return protoreflect.ValueOfString(value) - case "did.v1.PubKey.raw_key": - value := x.RawKey - return protoreflect.ValueOfMessage(value.ProtoReflect()) - case "did.v1.PubKey.jwk": - value := x.Jwk - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PubKey")) - } - panic(fmt.Errorf("message did.v1.PubKey does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_PubKey) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.PubKey.role": - x.Role = value.Interface().(string) - case "did.v1.PubKey.key_type": - x.KeyType = value.Interface().(string) - case "did.v1.PubKey.raw_key": - x.RawKey = value.Message().Interface().(*RawKey) - case "did.v1.PubKey.jwk": - x.Jwk = value.Message().Interface().(*JSONWebKey) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PubKey")) - } - panic(fmt.Errorf("message did.v1.PubKey does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_PubKey) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.PubKey.raw_key": - if x.RawKey == nil { - x.RawKey = new(RawKey) - } - return protoreflect.ValueOfMessage(x.RawKey.ProtoReflect()) - case "did.v1.PubKey.jwk": - if x.Jwk == nil { - x.Jwk = new(JSONWebKey) - } - return protoreflect.ValueOfMessage(x.Jwk.ProtoReflect()) - case "did.v1.PubKey.role": - panic(fmt.Errorf("field role of message did.v1.PubKey is not mutable")) - case "did.v1.PubKey.key_type": - panic(fmt.Errorf("field key_type of message did.v1.PubKey is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PubKey")) - } - panic(fmt.Errorf("message did.v1.PubKey does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_PubKey) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.PubKey.role": - return protoreflect.ValueOfString("") - case "did.v1.PubKey.key_type": - return protoreflect.ValueOfString("") - case "did.v1.PubKey.raw_key": - m := new(RawKey) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - case "did.v1.PubKey.jwk": - m := new(JSONWebKey) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PubKey")) - } - panic(fmt.Errorf("message did.v1.PubKey does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_PubKey) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.PubKey", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_PubKey) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_PubKey) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_PubKey) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_PubKey) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*PubKey) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Role) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.KeyType) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.RawKey != nil { - l = options.Size(x.RawKey) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.Jwk != nil { - l = options.Size(x.Jwk) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*PubKey) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Jwk != nil { - encoded, err := options.Marshal(x.Jwk) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x22 - } - if x.RawKey != nil { - encoded, err := options.Marshal(x.RawKey) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x1a - } - if len(x.KeyType) > 0 { - i -= len(x.KeyType) - copy(dAtA[i:], x.KeyType) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.KeyType))) - i-- - dAtA[i] = 0x12 - } - if len(x.Role) > 0 { - i -= len(x.Role) - copy(dAtA[i:], x.Role) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Role))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*PubKey) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: PubKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: PubKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Role = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field KeyType", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.KeyType = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field RawKey", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.RawKey == nil { - x.RawKey = &RawKey{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.RawKey); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Jwk", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Jwk == nil { - x.Jwk = &JSONWebKey{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Jwk); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_JSONWebKey protoreflect.MessageDescriptor - fd_JSONWebKey_kty protoreflect.FieldDescriptor - fd_JSONWebKey_crv protoreflect.FieldDescriptor - fd_JSONWebKey_x protoreflect.FieldDescriptor - fd_JSONWebKey_y protoreflect.FieldDescriptor - fd_JSONWebKey_n protoreflect.FieldDescriptor - fd_JSONWebKey_e protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_genesis_proto_init() - md_JSONWebKey = File_did_v1_genesis_proto.Messages().ByName("JSONWebKey") - fd_JSONWebKey_kty = md_JSONWebKey.Fields().ByName("kty") - fd_JSONWebKey_crv = md_JSONWebKey.Fields().ByName("crv") - fd_JSONWebKey_x = md_JSONWebKey.Fields().ByName("x") - fd_JSONWebKey_y = md_JSONWebKey.Fields().ByName("y") - fd_JSONWebKey_n = md_JSONWebKey.Fields().ByName("n") - fd_JSONWebKey_e = md_JSONWebKey.Fields().ByName("e") -} - -var _ protoreflect.Message = (*fastReflection_JSONWebKey)(nil) - -type fastReflection_JSONWebKey JSONWebKey - -func (x *JSONWebKey) ProtoReflect() protoreflect.Message { - return (*fastReflection_JSONWebKey)(x) -} - -func (x *JSONWebKey) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_genesis_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_JSONWebKey_messageType fastReflection_JSONWebKey_messageType -var _ protoreflect.MessageType = fastReflection_JSONWebKey_messageType{} - -type fastReflection_JSONWebKey_messageType struct{} - -func (x fastReflection_JSONWebKey_messageType) Zero() protoreflect.Message { - return (*fastReflection_JSONWebKey)(nil) -} -func (x fastReflection_JSONWebKey_messageType) New() protoreflect.Message { - return new(fastReflection_JSONWebKey) -} -func (x fastReflection_JSONWebKey_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_JSONWebKey -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_JSONWebKey) Descriptor() protoreflect.MessageDescriptor { - return md_JSONWebKey -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_JSONWebKey) Type() protoreflect.MessageType { - return _fastReflection_JSONWebKey_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_JSONWebKey) New() protoreflect.Message { - return new(fastReflection_JSONWebKey) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_JSONWebKey) Interface() protoreflect.ProtoMessage { - return (*JSONWebKey)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_JSONWebKey) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Kty != "" { - value := protoreflect.ValueOfString(x.Kty) - if !f(fd_JSONWebKey_kty, value) { - return - } - } - if x.Crv != "" { - value := protoreflect.ValueOfString(x.Crv) - if !f(fd_JSONWebKey_crv, value) { - return - } - } - if x.X != "" { - value := protoreflect.ValueOfString(x.X) - if !f(fd_JSONWebKey_x, value) { - return - } - } - if x.Y != "" { - value := protoreflect.ValueOfString(x.Y) - if !f(fd_JSONWebKey_y, value) { - return - } - } - if x.N != "" { - value := protoreflect.ValueOfString(x.N) - if !f(fd_JSONWebKey_n, value) { - return - } - } - if x.E != "" { - value := protoreflect.ValueOfString(x.E) - if !f(fd_JSONWebKey_e, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_JSONWebKey) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.JSONWebKey.kty": - return x.Kty != "" - case "did.v1.JSONWebKey.crv": - return x.Crv != "" - case "did.v1.JSONWebKey.x": - return x.X != "" - case "did.v1.JSONWebKey.y": - return x.Y != "" - case "did.v1.JSONWebKey.n": - return x.N != "" - case "did.v1.JSONWebKey.e": - return x.E != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.JSONWebKey")) - } - panic(fmt.Errorf("message did.v1.JSONWebKey does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_JSONWebKey) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.JSONWebKey.kty": - x.Kty = "" - case "did.v1.JSONWebKey.crv": - x.Crv = "" - case "did.v1.JSONWebKey.x": - x.X = "" - case "did.v1.JSONWebKey.y": - x.Y = "" - case "did.v1.JSONWebKey.n": - x.N = "" - case "did.v1.JSONWebKey.e": - x.E = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.JSONWebKey")) - } - panic(fmt.Errorf("message did.v1.JSONWebKey does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_JSONWebKey) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.JSONWebKey.kty": - value := x.Kty - return protoreflect.ValueOfString(value) - case "did.v1.JSONWebKey.crv": - value := x.Crv - return protoreflect.ValueOfString(value) - case "did.v1.JSONWebKey.x": - value := x.X - return protoreflect.ValueOfString(value) - case "did.v1.JSONWebKey.y": - value := x.Y - return protoreflect.ValueOfString(value) - case "did.v1.JSONWebKey.n": - value := x.N - return protoreflect.ValueOfString(value) - case "did.v1.JSONWebKey.e": - value := x.E - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.JSONWebKey")) - } - panic(fmt.Errorf("message did.v1.JSONWebKey does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_JSONWebKey) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.JSONWebKey.kty": - x.Kty = value.Interface().(string) - case "did.v1.JSONWebKey.crv": - x.Crv = value.Interface().(string) - case "did.v1.JSONWebKey.x": - x.X = value.Interface().(string) - case "did.v1.JSONWebKey.y": - x.Y = value.Interface().(string) - case "did.v1.JSONWebKey.n": - x.N = value.Interface().(string) - case "did.v1.JSONWebKey.e": - x.E = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.JSONWebKey")) - } - panic(fmt.Errorf("message did.v1.JSONWebKey does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_JSONWebKey) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.JSONWebKey.kty": - panic(fmt.Errorf("field kty of message did.v1.JSONWebKey is not mutable")) - case "did.v1.JSONWebKey.crv": - panic(fmt.Errorf("field crv of message did.v1.JSONWebKey is not mutable")) - case "did.v1.JSONWebKey.x": - panic(fmt.Errorf("field x of message did.v1.JSONWebKey is not mutable")) - case "did.v1.JSONWebKey.y": - panic(fmt.Errorf("field y of message did.v1.JSONWebKey is not mutable")) - case "did.v1.JSONWebKey.n": - panic(fmt.Errorf("field n of message did.v1.JSONWebKey is not mutable")) - case "did.v1.JSONWebKey.e": - panic(fmt.Errorf("field e of message did.v1.JSONWebKey is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.JSONWebKey")) - } - panic(fmt.Errorf("message did.v1.JSONWebKey does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_JSONWebKey) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.JSONWebKey.kty": - return protoreflect.ValueOfString("") - case "did.v1.JSONWebKey.crv": - return protoreflect.ValueOfString("") - case "did.v1.JSONWebKey.x": - return protoreflect.ValueOfString("") - case "did.v1.JSONWebKey.y": - return protoreflect.ValueOfString("") - case "did.v1.JSONWebKey.n": - return protoreflect.ValueOfString("") - case "did.v1.JSONWebKey.e": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.JSONWebKey")) - } - panic(fmt.Errorf("message did.v1.JSONWebKey does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_JSONWebKey) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.JSONWebKey", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_JSONWebKey) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_JSONWebKey) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_JSONWebKey) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_JSONWebKey) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*JSONWebKey) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Kty) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Crv) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.X) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Y) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.N) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.E) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*JSONWebKey) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.E) > 0 { - i -= len(x.E) - copy(dAtA[i:], x.E) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.E))) - i-- - dAtA[i] = 0x32 - } - if len(x.N) > 0 { - i -= len(x.N) - copy(dAtA[i:], x.N) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.N))) - i-- - dAtA[i] = 0x2a - } - if len(x.Y) > 0 { - i -= len(x.Y) - copy(dAtA[i:], x.Y) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Y))) - i-- - dAtA[i] = 0x22 - } - if len(x.X) > 0 { - i -= len(x.X) - copy(dAtA[i:], x.X) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.X))) - i-- - dAtA[i] = 0x1a - } - if len(x.Crv) > 0 { - i -= len(x.Crv) - copy(dAtA[i:], x.Crv) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Crv))) - i-- - dAtA[i] = 0x12 - } - if len(x.Kty) > 0 { - i -= len(x.Kty) - copy(dAtA[i:], x.Kty) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Kty))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*JSONWebKey) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: JSONWebKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: JSONWebKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Kty", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Kty = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Crv", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Crv = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field X", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.X = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Y", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Y = string(dAtA[iNdEx:postIndex]) + x.AssertionMethod = append(x.AssertionMethod, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 5: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field N", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CapabilityDelegation", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3777,11 +1452,11 @@ func (x *fastReflection_JSONWebKey) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.N = string(dAtA[iNdEx:postIndex]) + x.CapabilityDelegation = append(x.CapabilityDelegation, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 6: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field E", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CapabilityInvocation", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3809,495 +1484,11 @@ func (x *fastReflection_JSONWebKey) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.E = string(dAtA[iNdEx:postIndex]) + x.CapabilityInvocation = append(x.CapabilityInvocation, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_RawKey protoreflect.MessageDescriptor - fd_RawKey_algorithm protoreflect.FieldDescriptor - fd_RawKey_encoding protoreflect.FieldDescriptor - fd_RawKey_curve protoreflect.FieldDescriptor - fd_RawKey_key protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_genesis_proto_init() - md_RawKey = File_did_v1_genesis_proto.Messages().ByName("RawKey") - fd_RawKey_algorithm = md_RawKey.Fields().ByName("algorithm") - fd_RawKey_encoding = md_RawKey.Fields().ByName("encoding") - fd_RawKey_curve = md_RawKey.Fields().ByName("curve") - fd_RawKey_key = md_RawKey.Fields().ByName("key") -} - -var _ protoreflect.Message = (*fastReflection_RawKey)(nil) - -type fastReflection_RawKey RawKey - -func (x *RawKey) ProtoReflect() protoreflect.Message { - return (*fastReflection_RawKey)(x) -} - -func (x *RawKey) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_genesis_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_RawKey_messageType fastReflection_RawKey_messageType -var _ protoreflect.MessageType = fastReflection_RawKey_messageType{} - -type fastReflection_RawKey_messageType struct{} - -func (x fastReflection_RawKey_messageType) Zero() protoreflect.Message { - return (*fastReflection_RawKey)(nil) -} -func (x fastReflection_RawKey_messageType) New() protoreflect.Message { - return new(fastReflection_RawKey) -} -func (x fastReflection_RawKey_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_RawKey -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_RawKey) Descriptor() protoreflect.MessageDescriptor { - return md_RawKey -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_RawKey) Type() protoreflect.MessageType { - return _fastReflection_RawKey_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_RawKey) New() protoreflect.Message { - return new(fastReflection_RawKey) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_RawKey) Interface() protoreflect.ProtoMessage { - return (*RawKey)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_RawKey) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Algorithm != "" { - value := protoreflect.ValueOfString(x.Algorithm) - if !f(fd_RawKey_algorithm, value) { - return - } - } - if x.Encoding != "" { - value := protoreflect.ValueOfString(x.Encoding) - if !f(fd_RawKey_encoding, value) { - return - } - } - if x.Curve != "" { - value := protoreflect.ValueOfString(x.Curve) - if !f(fd_RawKey_curve, value) { - return - } - } - if len(x.Key) != 0 { - value := protoreflect.ValueOfBytes(x.Key) - if !f(fd_RawKey_key, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_RawKey) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.RawKey.algorithm": - return x.Algorithm != "" - case "did.v1.RawKey.encoding": - return x.Encoding != "" - case "did.v1.RawKey.curve": - return x.Curve != "" - case "did.v1.RawKey.key": - return len(x.Key) != 0 - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.RawKey")) - } - panic(fmt.Errorf("message did.v1.RawKey does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_RawKey) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.RawKey.algorithm": - x.Algorithm = "" - case "did.v1.RawKey.encoding": - x.Encoding = "" - case "did.v1.RawKey.curve": - x.Curve = "" - case "did.v1.RawKey.key": - x.Key = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.RawKey")) - } - panic(fmt.Errorf("message did.v1.RawKey does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_RawKey) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.RawKey.algorithm": - value := x.Algorithm - return protoreflect.ValueOfString(value) - case "did.v1.RawKey.encoding": - value := x.Encoding - return protoreflect.ValueOfString(value) - case "did.v1.RawKey.curve": - value := x.Curve - return protoreflect.ValueOfString(value) - case "did.v1.RawKey.key": - value := x.Key - return protoreflect.ValueOfBytes(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.RawKey")) - } - panic(fmt.Errorf("message did.v1.RawKey does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_RawKey) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.RawKey.algorithm": - x.Algorithm = value.Interface().(string) - case "did.v1.RawKey.encoding": - x.Encoding = value.Interface().(string) - case "did.v1.RawKey.curve": - x.Curve = value.Interface().(string) - case "did.v1.RawKey.key": - x.Key = value.Bytes() - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.RawKey")) - } - panic(fmt.Errorf("message did.v1.RawKey does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_RawKey) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.RawKey.algorithm": - panic(fmt.Errorf("field algorithm of message did.v1.RawKey is not mutable")) - case "did.v1.RawKey.encoding": - panic(fmt.Errorf("field encoding of message did.v1.RawKey is not mutable")) - case "did.v1.RawKey.curve": - panic(fmt.Errorf("field curve of message did.v1.RawKey is not mutable")) - case "did.v1.RawKey.key": - panic(fmt.Errorf("field key of message did.v1.RawKey is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.RawKey")) - } - panic(fmt.Errorf("message did.v1.RawKey does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_RawKey) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.RawKey.algorithm": - return protoreflect.ValueOfString("") - case "did.v1.RawKey.encoding": - return protoreflect.ValueOfString("") - case "did.v1.RawKey.curve": - return protoreflect.ValueOfString("") - case "did.v1.RawKey.key": - return protoreflect.ValueOfBytes(nil) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.RawKey")) - } - panic(fmt.Errorf("message did.v1.RawKey does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_RawKey) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.RawKey", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_RawKey) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_RawKey) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_RawKey) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_RawKey) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*RawKey) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Algorithm) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Encoding) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Curve) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Key) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*RawKey) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Key) > 0 { - i -= len(x.Key) - copy(dAtA[i:], x.Key) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Key))) - i-- - dAtA[i] = 0x22 - } - if len(x.Curve) > 0 { - i -= len(x.Curve) - copy(dAtA[i:], x.Curve) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Curve))) - i-- - dAtA[i] = 0x1a - } - if len(x.Encoding) > 0 { - i -= len(x.Encoding) - copy(dAtA[i:], x.Encoding) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Encoding))) - i-- - dAtA[i] = 0x12 - } - if len(x.Algorithm) > 0 { - i -= len(x.Algorithm) - copy(dAtA[i:], x.Algorithm) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Algorithm))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*RawKey) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: RawKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: RawKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 7: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Algorithm", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4325,105 +1516,7 @@ func (x *fastReflection_RawKey) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Algorithm = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Encoding", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Encoding = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Curve", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Curve = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Key = append(x.Key[:0], dAtA[iNdEx:postIndex]...) - if x.Key == nil { - x.Key = []byte{} - } + x.Service = append(x.Service, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -4510,22 +1603,23 @@ func (x *GenesisState) GetParams() *Params { return nil } -// Params defines the set of module parameters. -type Params struct { +// Document defines a DID document +type Document struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Whitelisted Key Types - AllowedPublicKeys map[string]*KeyInfo `protobuf:"bytes,2,rep,name=allowed_public_keys,json=allowedPublicKeys,proto3" json:"allowed_public_keys,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // ConveyancePreference defines the conveyance preference - ConveyancePreference string `protobuf:"bytes,3,opt,name=conveyance_preference,json=conveyancePreference,proto3" json:"conveyance_preference,omitempty"` - // AttestationFormats defines the attestation formats - AttestationFormats []string `protobuf:"bytes,4,rep,name=attestation_formats,json=attestationFormats,proto3" json:"attestation_formats,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` // The DID of the controller + Authentication []string `protobuf:"bytes,3,rep,name=authentication,proto3" json:"authentication,omitempty"` + AssertionMethod []string `protobuf:"bytes,4,rep,name=assertion_method,json=assertionMethod,proto3" json:"assertion_method,omitempty"` + CapabilityDelegation []string `protobuf:"bytes,5,rep,name=capability_delegation,json=capabilityDelegation,proto3" json:"capability_delegation,omitempty"` + CapabilityInvocation []string `protobuf:"bytes,6,rep,name=capability_invocation,json=capabilityInvocation,proto3" json:"capability_invocation,omitempty"` + Service []string `protobuf:"bytes,7,rep,name=service,proto3" json:"service,omitempty"` } -func (x *Params) Reset() { - *x = Params{} +func (x *Document) Reset() { + *x = Document{} if protoimpl.UnsafeEnabled { mi := &file_did_v1_genesis_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -4533,340 +1627,62 @@ func (x *Params) Reset() { } } -func (x *Params) String() string { +func (x *Document) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Params) ProtoMessage() {} +func (*Document) ProtoMessage() {} -// Deprecated: Use Params.ProtoReflect.Descriptor instead. -func (*Params) Descriptor() ([]byte, []int) { +// Deprecated: Use Document.ProtoReflect.Descriptor instead. +func (*Document) Descriptor() ([]byte, []int) { return file_did_v1_genesis_proto_rawDescGZIP(), []int{1} } -func (x *Params) GetAllowedPublicKeys() map[string]*KeyInfo { +func (x *Document) GetId() string { if x != nil { - return x.AllowedPublicKeys + return x.Id + } + return "" +} + +func (x *Document) GetController() string { + if x != nil { + return x.Controller + } + return "" +} + +func (x *Document) GetAuthentication() []string { + if x != nil { + return x.Authentication } return nil } -func (x *Params) GetConveyancePreference() string { +func (x *Document) GetAssertionMethod() []string { if x != nil { - return x.ConveyancePreference - } - return "" -} - -func (x *Params) GetAttestationFormats() []string { - if x != nil { - return x.AttestationFormats + return x.AssertionMethod } return nil } -// KeyInfo defines information for accepted PubKey types -type KeyInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` - Algorithm string `protobuf:"bytes,2,opt,name=algorithm,proto3" json:"algorithm,omitempty"` // e.g., "ES256", "EdDSA", "ES256K" - Encoding string `protobuf:"bytes,3,opt,name=encoding,proto3" json:"encoding,omitempty"` // e.g., "hex", "base64", "multibase" - Curve string `protobuf:"bytes,4,opt,name=curve,proto3" json:"curve,omitempty"` // e.g., "P256", "P384", "P521", "X25519", "X448", -} - -func (x *KeyInfo) Reset() { - *x = KeyInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_genesis_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *KeyInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*KeyInfo) ProtoMessage() {} - -// Deprecated: Use KeyInfo.ProtoReflect.Descriptor instead. -func (*KeyInfo) Descriptor() ([]byte, []int) { - return file_did_v1_genesis_proto_rawDescGZIP(), []int{2} -} - -func (x *KeyInfo) GetRole() string { +func (x *Document) GetCapabilityDelegation() []string { if x != nil { - return x.Role - } - return "" -} - -func (x *KeyInfo) GetAlgorithm() string { - if x != nil { - return x.Algorithm - } - return "" -} - -func (x *KeyInfo) GetEncoding() string { - if x != nil { - return x.Encoding - } - return "" -} - -func (x *KeyInfo) GetCurve() string { - if x != nil { - return x.Curve - } - return "" -} - -type Keyshares struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ValidatorCid string `protobuf:"bytes,1,opt,name=validator_cid,json=validatorCid,proto3" json:"validator_cid,omitempty"` - UserCid string `protobuf:"bytes,2,opt,name=user_cid,json=userCid,proto3" json:"user_cid,omitempty"` - LastUpdatedBlock int64 `protobuf:"varint,3,opt,name=last_updated_block,json=lastUpdatedBlock,proto3" json:"last_updated_block,omitempty"` -} - -func (x *Keyshares) Reset() { - *x = Keyshares{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_genesis_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Keyshares) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Keyshares) ProtoMessage() {} - -// Deprecated: Use Keyshares.ProtoReflect.Descriptor instead. -func (*Keyshares) Descriptor() ([]byte, []int) { - return file_did_v1_genesis_proto_rawDescGZIP(), []int{3} -} - -func (x *Keyshares) GetValidatorCid() string { - if x != nil { - return x.ValidatorCid - } - return "" -} - -func (x *Keyshares) GetUserCid() string { - if x != nil { - return x.UserCid - } - return "" -} - -func (x *Keyshares) GetLastUpdatedBlock() int64 { - if x != nil { - return x.LastUpdatedBlock - } - return 0 -} - -// PubKey defines a public key for a did -type PubKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` - KeyType string `protobuf:"bytes,2,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` - RawKey *RawKey `protobuf:"bytes,3,opt,name=raw_key,json=rawKey,proto3" json:"raw_key,omitempty"` - Jwk *JSONWebKey `protobuf:"bytes,4,opt,name=jwk,proto3" json:"jwk,omitempty"` -} - -func (x *PubKey) Reset() { - *x = PubKey{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_genesis_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PubKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PubKey) ProtoMessage() {} - -// Deprecated: Use PubKey.ProtoReflect.Descriptor instead. -func (*PubKey) Descriptor() ([]byte, []int) { - return file_did_v1_genesis_proto_rawDescGZIP(), []int{4} -} - -func (x *PubKey) GetRole() string { - if x != nil { - return x.Role - } - return "" -} - -func (x *PubKey) GetKeyType() string { - if x != nil { - return x.KeyType - } - return "" -} - -func (x *PubKey) GetRawKey() *RawKey { - if x != nil { - return x.RawKey + return x.CapabilityDelegation } return nil } -func (x *PubKey) GetJwk() *JSONWebKey { +func (x *Document) GetCapabilityInvocation() []string { if x != nil { - return x.Jwk + return x.CapabilityInvocation } return nil } -// JWK represents a JSON Web Key -type JSONWebKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Kty string `protobuf:"bytes,1,opt,name=kty,proto3" json:"kty,omitempty"` // Key Type - Crv string `protobuf:"bytes,2,opt,name=crv,proto3" json:"crv,omitempty"` // Curve (for EC and OKP keys) - X string `protobuf:"bytes,3,opt,name=x,proto3" json:"x,omitempty"` // X coordinate (for EC and OKP keys) - Y string `protobuf:"bytes,4,opt,name=y,proto3" json:"y,omitempty"` // Y coordinate (for EC keys) - N string `protobuf:"bytes,5,opt,name=n,proto3" json:"n,omitempty"` // Modulus (for RSA keys) - E string `protobuf:"bytes,6,opt,name=e,proto3" json:"e,omitempty"` // Exponent (for RSA keys) -} - -func (x *JSONWebKey) Reset() { - *x = JSONWebKey{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_genesis_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *JSONWebKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*JSONWebKey) ProtoMessage() {} - -// Deprecated: Use JSONWebKey.ProtoReflect.Descriptor instead. -func (*JSONWebKey) Descriptor() ([]byte, []int) { - return file_did_v1_genesis_proto_rawDescGZIP(), []int{5} -} - -func (x *JSONWebKey) GetKty() string { +func (x *Document) GetService() []string { if x != nil { - return x.Kty - } - return "" -} - -func (x *JSONWebKey) GetCrv() string { - if x != nil { - return x.Crv - } - return "" -} - -func (x *JSONWebKey) GetX() string { - if x != nil { - return x.X - } - return "" -} - -func (x *JSONWebKey) GetY() string { - if x != nil { - return x.Y - } - return "" -} - -func (x *JSONWebKey) GetN() string { - if x != nil { - return x.N - } - return "" -} - -func (x *JSONWebKey) GetE() string { - if x != nil { - return x.E - } - return "" -} - -type RawKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Algorithm string `protobuf:"bytes,1,opt,name=algorithm,proto3" json:"algorithm,omitempty"` - Encoding string `protobuf:"bytes,2,opt,name=encoding,proto3" json:"encoding,omitempty"` - Curve string `protobuf:"bytes,3,opt,name=curve,proto3" json:"curve,omitempty"` - Key []byte `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"` -} - -func (x *RawKey) Reset() { - *x = RawKey{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_genesis_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RawKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RawKey) ProtoMessage() {} - -// Deprecated: Use RawKey.ProtoReflect.Descriptor instead. -func (*RawKey) Descriptor() ([]byte, []int) { - return file_did_v1_genesis_proto_rawDescGZIP(), []int{6} -} - -func (x *RawKey) GetAlgorithm() string { - if x != nil { - return x.Algorithm - } - return "" -} - -func (x *RawKey) GetEncoding() string { - if x != nil { - return x.Encoding - } - return "" -} - -func (x *RawKey) GetCurve() string { - if x != nil { - return x.Curve - } - return "" -} - -func (x *RawKey) GetKey() []byte { - if x != nil { - return x.Key + return x.Service } return nil } @@ -4877,76 +1693,39 @@ var file_did_v1_genesis_proto_rawDesc = []byte{ 0x0a, 0x14, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, - 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3c, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, - 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xb5, 0x02, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x12, 0x55, 0x0a, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, - 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x41, 0x6c, - 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x33, 0x0a, 0x15, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x79, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x79, 0x61, 0x6e, - 0x63, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x13, - 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x74, 0x74, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x1a, 0x55, 0x0a, - 0x16, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, - 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x17, 0x98, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, - 0xb0, 0x2a, 0x0a, 0x64, 0x69, 0x64, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x6d, 0x0a, - 0x07, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, - 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, - 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x75, 0x72, 0x76, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x75, 0x72, 0x76, 0x65, 0x22, 0x79, 0x0a, 0x09, - 0x4b, 0x65, 0x79, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x69, 0x64, 0x12, 0x19, - 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x43, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x86, 0x01, 0x0a, 0x06, 0x50, 0x75, 0x62, 0x4b, - 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x27, 0x0a, 0x07, 0x72, 0x61, 0x77, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x4b, - 0x65, 0x79, 0x52, 0x06, 0x72, 0x61, 0x77, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x03, 0x6a, 0x77, - 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, - 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6a, 0x77, 0x6b, - 0x22, 0x68, 0x0a, 0x0a, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x74, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x63, 0x72, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, - 0x72, 0x76, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x78, - 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x79, 0x12, 0x0c, - 0x0a, 0x01, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x6e, 0x12, 0x0c, 0x0a, 0x01, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x65, 0x22, 0x6a, 0x0a, 0x06, 0x52, 0x61, - 0x77, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, - 0x68, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x14, - 0x0a, 0x05, 0x63, 0x75, 0x72, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, - 0x75, 0x72, 0x76, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x42, 0x7c, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x69, - 0x64, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, 0x31, 0xa2, 0x02, 0x03, - 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, - 0x69, 0x64, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x69, 0x64, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x1a, 0x13, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3c, 0x0a, 0x0c, + 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x06, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, + 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, + 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x91, 0x02, 0x0a, 0x08, 0x44, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x29, 0x0a, 0x10, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x72, + 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x33, 0x0a, 0x15, 0x63, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x63, 0x61, 0x70, 0x61, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x33, 0x0a, 0x15, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, + 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, + 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x76, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x7c, + 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, + 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, + 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x3b, + 0x64, 0x69, 0x64, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x69, + 0x64, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, + 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4961,28 +1740,19 @@ func file_did_v1_genesis_proto_rawDescGZIP() []byte { return file_did_v1_genesis_proto_rawDescData } -var file_did_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_did_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_did_v1_genesis_proto_goTypes = []interface{}{ (*GenesisState)(nil), // 0: did.v1.GenesisState - (*Params)(nil), // 1: did.v1.Params - (*KeyInfo)(nil), // 2: did.v1.KeyInfo - (*Keyshares)(nil), // 3: did.v1.Keyshares - (*PubKey)(nil), // 4: did.v1.PubKey - (*JSONWebKey)(nil), // 5: did.v1.JSONWebKey - (*RawKey)(nil), // 6: did.v1.RawKey - nil, // 7: did.v1.Params.AllowedPublicKeysEntry + (*Document)(nil), // 1: did.v1.Document + (*Params)(nil), // 2: did.v1.Params } var file_did_v1_genesis_proto_depIdxs = []int32{ - 1, // 0: did.v1.GenesisState.params:type_name -> did.v1.Params - 7, // 1: did.v1.Params.allowed_public_keys:type_name -> did.v1.Params.AllowedPublicKeysEntry - 6, // 2: did.v1.PubKey.raw_key:type_name -> did.v1.RawKey - 5, // 3: did.v1.PubKey.jwk:type_name -> did.v1.JSONWebKey - 2, // 4: did.v1.Params.AllowedPublicKeysEntry.value:type_name -> did.v1.KeyInfo - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 2, // 0: did.v1.GenesisState.params:type_name -> did.v1.Params + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_did_v1_genesis_proto_init() } @@ -4990,6 +1760,7 @@ func file_did_v1_genesis_proto_init() { if File_did_v1_genesis_proto != nil { return } + file_did_v1_params_proto_init() if !protoimpl.UnsafeEnabled { file_did_v1_genesis_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GenesisState); i { @@ -5004,67 +1775,7 @@ func file_did_v1_genesis_proto_init() { } } file_did_v1_genesis_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Params); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_did_v1_genesis_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_did_v1_genesis_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Keyshares); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_did_v1_genesis_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PubKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_did_v1_genesis_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*JSONWebKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_did_v1_genesis_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RawKey); i { + switch v := v.(*Document); i { case 0: return &v.state case 1: @@ -5082,7 +1793,7 @@ func file_did_v1_genesis_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_did_v1_genesis_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/api/did/v1/params.pulsar.go b/api/did/v1/params.pulsar.go new file mode 100644 index 000000000..e3667ff35 --- /dev/null +++ b/api/did/v1/params.pulsar.go @@ -0,0 +1,1750 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package didv1 + +import ( + _ "cosmossdk.io/api/amino" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sort "sort" + sync "sync" +) + +var _ protoreflect.Map = (*_Params_2_map)(nil) + +type _Params_2_map struct { + m *map[string]*KeyInfo +} + +func (x *_Params_2_map) Len() int { + if x.m == nil { + return 0 + } + return len(*x.m) +} + +func (x *_Params_2_map) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { + if x.m == nil { + return + } + for k, v := range *x.m { + mapKey := (protoreflect.MapKey)(protoreflect.ValueOfString(k)) + mapValue := protoreflect.ValueOfMessage(v.ProtoReflect()) + if !f(mapKey, mapValue) { + break + } + } +} + +func (x *_Params_2_map) Has(key protoreflect.MapKey) bool { + if x.m == nil { + return false + } + keyUnwrapped := key.String() + concreteValue := keyUnwrapped + _, ok := (*x.m)[concreteValue] + return ok +} + +func (x *_Params_2_map) Clear(key protoreflect.MapKey) { + if x.m == nil { + return + } + keyUnwrapped := key.String() + concreteKey := keyUnwrapped + delete(*x.m, concreteKey) +} + +func (x *_Params_2_map) Get(key protoreflect.MapKey) protoreflect.Value { + if x.m == nil { + return protoreflect.Value{} + } + keyUnwrapped := key.String() + concreteKey := keyUnwrapped + v, ok := (*x.m)[concreteKey] + if !ok { + return protoreflect.Value{} + } + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_Params_2_map) Set(key protoreflect.MapKey, value protoreflect.Value) { + if !key.IsValid() || !value.IsValid() { + panic("invalid key or value provided") + } + keyUnwrapped := key.String() + concreteKey := keyUnwrapped + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*KeyInfo) + (*x.m)[concreteKey] = concreteValue +} + +func (x *_Params_2_map) Mutable(key protoreflect.MapKey) protoreflect.Value { + keyUnwrapped := key.String() + concreteKey := keyUnwrapped + v, ok := (*x.m)[concreteKey] + if ok { + return protoreflect.ValueOfMessage(v.ProtoReflect()) + } + newValue := new(KeyInfo) + (*x.m)[concreteKey] = newValue + return protoreflect.ValueOfMessage(newValue.ProtoReflect()) +} + +func (x *_Params_2_map) NewValue() protoreflect.Value { + v := new(KeyInfo) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_Params_2_map) IsValid() bool { + return x.m != nil +} + +var _ protoreflect.List = (*_Params_4_list)(nil) + +type _Params_4_list struct { + list *[]string +} + +func (x *_Params_4_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Params_4_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Params_4_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Params_4_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Params_4_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Params at list field AttestationFormats as it is not of Message kind")) +} + +func (x *_Params_4_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Params_4_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Params_4_list) IsValid() bool { + return x.list != nil +} + +var ( + md_Params protoreflect.MessageDescriptor + fd_Params_allowed_public_keys protoreflect.FieldDescriptor + fd_Params_conveyance_preference protoreflect.FieldDescriptor + fd_Params_attestation_formats protoreflect.FieldDescriptor +) + +func init() { + file_did_v1_params_proto_init() + md_Params = File_did_v1_params_proto.Messages().ByName("Params") + fd_Params_allowed_public_keys = md_Params.Fields().ByName("allowed_public_keys") + fd_Params_conveyance_preference = md_Params.Fields().ByName("conveyance_preference") + fd_Params_attestation_formats = md_Params.Fields().ByName("attestation_formats") +} + +var _ protoreflect.Message = (*fastReflection_Params)(nil) + +type fastReflection_Params Params + +func (x *Params) ProtoReflect() protoreflect.Message { + return (*fastReflection_Params)(x) +} + +func (x *Params) slowProtoReflect() protoreflect.Message { + mi := &file_did_v1_params_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Params_messageType fastReflection_Params_messageType +var _ protoreflect.MessageType = fastReflection_Params_messageType{} + +type fastReflection_Params_messageType struct{} + +func (x fastReflection_Params_messageType) Zero() protoreflect.Message { + return (*fastReflection_Params)(nil) +} +func (x fastReflection_Params_messageType) New() protoreflect.Message { + return new(fastReflection_Params) +} +func (x fastReflection_Params_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Params) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Params) Type() protoreflect.MessageType { + return _fastReflection_Params_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Params) New() protoreflect.Message { + return new(fastReflection_Params) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { + return (*Params)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.AllowedPublicKeys) != 0 { + value := protoreflect.ValueOfMap(&_Params_2_map{m: &x.AllowedPublicKeys}) + if !f(fd_Params_allowed_public_keys, value) { + return + } + } + if x.ConveyancePreference != "" { + value := protoreflect.ValueOfString(x.ConveyancePreference) + if !f(fd_Params_conveyance_preference, value) { + return + } + } + if len(x.AttestationFormats) != 0 { + value := protoreflect.ValueOfList(&_Params_4_list{list: &x.AttestationFormats}) + if !f(fd_Params_attestation_formats, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "did.v1.Params.allowed_public_keys": + return len(x.AllowedPublicKeys) != 0 + case "did.v1.Params.conveyance_preference": + return x.ConveyancePreference != "" + case "did.v1.Params.attestation_formats": + return len(x.AttestationFormats) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + } + panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "did.v1.Params.allowed_public_keys": + x.AllowedPublicKeys = nil + case "did.v1.Params.conveyance_preference": + x.ConveyancePreference = "" + case "did.v1.Params.attestation_formats": + x.AttestationFormats = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + } + panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "did.v1.Params.allowed_public_keys": + if len(x.AllowedPublicKeys) == 0 { + return protoreflect.ValueOfMap(&_Params_2_map{}) + } + mapValue := &_Params_2_map{m: &x.AllowedPublicKeys} + return protoreflect.ValueOfMap(mapValue) + case "did.v1.Params.conveyance_preference": + value := x.ConveyancePreference + return protoreflect.ValueOfString(value) + case "did.v1.Params.attestation_formats": + if len(x.AttestationFormats) == 0 { + return protoreflect.ValueOfList(&_Params_4_list{}) + } + listValue := &_Params_4_list{list: &x.AttestationFormats} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + } + panic(fmt.Errorf("message did.v1.Params does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "did.v1.Params.allowed_public_keys": + mv := value.Map() + cmv := mv.(*_Params_2_map) + x.AllowedPublicKeys = *cmv.m + case "did.v1.Params.conveyance_preference": + x.ConveyancePreference = value.Interface().(string) + case "did.v1.Params.attestation_formats": + lv := value.List() + clv := lv.(*_Params_4_list) + x.AttestationFormats = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + } + panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "did.v1.Params.allowed_public_keys": + if x.AllowedPublicKeys == nil { + x.AllowedPublicKeys = make(map[string]*KeyInfo) + } + value := &_Params_2_map{m: &x.AllowedPublicKeys} + return protoreflect.ValueOfMap(value) + case "did.v1.Params.attestation_formats": + if x.AttestationFormats == nil { + x.AttestationFormats = []string{} + } + value := &_Params_4_list{list: &x.AttestationFormats} + return protoreflect.ValueOfList(value) + case "did.v1.Params.conveyance_preference": + panic(fmt.Errorf("field conveyance_preference of message did.v1.Params is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + } + panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "did.v1.Params.allowed_public_keys": + m := make(map[string]*KeyInfo) + return protoreflect.ValueOfMap(&_Params_2_map{m: &m}) + case "did.v1.Params.conveyance_preference": + return protoreflect.ValueOfString("") + case "did.v1.Params.attestation_formats": + list := []string{} + return protoreflect.ValueOfList(&_Params_4_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Params")) + } + panic(fmt.Errorf("message did.v1.Params does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in did.v1.Params", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Params) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Params) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.AllowedPublicKeys) > 0 { + SiZeMaP := func(k string, v *KeyInfo) { + l := 0 + if v != nil { + l = options.Size(v) + } + l += 1 + runtime.Sov(uint64(l)) + mapEntrySize := 1 + len(k) + runtime.Sov(uint64(len(k))) + l + n += mapEntrySize + 1 + runtime.Sov(uint64(mapEntrySize)) + } + if options.Deterministic { + sortme := make([]string, 0, len(x.AllowedPublicKeys)) + for k := range x.AllowedPublicKeys { + sortme = append(sortme, k) + } + sort.Strings(sortme) + for _, k := range sortme { + v := x.AllowedPublicKeys[k] + SiZeMaP(k, v) + } + } else { + for k, v := range x.AllowedPublicKeys { + SiZeMaP(k, v) + } + } + } + l = len(x.ConveyancePreference) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.AttestationFormats) > 0 { + for _, s := range x.AttestationFormats { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.AttestationFormats) > 0 { + for iNdEx := len(x.AttestationFormats) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.AttestationFormats[iNdEx]) + copy(dAtA[i:], x.AttestationFormats[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.AttestationFormats[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if len(x.ConveyancePreference) > 0 { + i -= len(x.ConveyancePreference) + copy(dAtA[i:], x.ConveyancePreference) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ConveyancePreference))) + i-- + dAtA[i] = 0x1a + } + if len(x.AllowedPublicKeys) > 0 { + MaRsHaLmAp := func(k string, v *KeyInfo) (protoiface.MarshalOutput, error) { + baseI := i + encoded, err := options.Marshal(v) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = runtime.EncodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = runtime.EncodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x12 + return protoiface.MarshalOutput{}, nil + } + if options.Deterministic { + keysForAllowedPublicKeys := make([]string, 0, len(x.AllowedPublicKeys)) + for k := range x.AllowedPublicKeys { + keysForAllowedPublicKeys = append(keysForAllowedPublicKeys, string(k)) + } + sort.Slice(keysForAllowedPublicKeys, func(i, j int) bool { + return keysForAllowedPublicKeys[i] < keysForAllowedPublicKeys[j] + }) + for iNdEx := len(keysForAllowedPublicKeys) - 1; iNdEx >= 0; iNdEx-- { + v := x.AllowedPublicKeys[string(keysForAllowedPublicKeys[iNdEx])] + out, err := MaRsHaLmAp(keysForAllowedPublicKeys[iNdEx], v) + if err != nil { + return out, err + } + } + } else { + for k := range x.AllowedPublicKeys { + v := x.AllowedPublicKeys[k] + out, err := MaRsHaLmAp(k, v) + if err != nil { + return out, err + } + } + } + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AllowedPublicKeys", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.AllowedPublicKeys == nil { + x.AllowedPublicKeys = make(map[string]*KeyInfo) + } + var mapkey string + var mapvalue *KeyInfo + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postStringIndexmapkey > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postmsgIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + mapvalue = &KeyInfo{} + if err := options.Unmarshal(dAtA[iNdEx:postmsgIndex], mapvalue); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + x.AllowedPublicKeys[mapkey] = mapvalue + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ConveyancePreference", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.ConveyancePreference = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AttestationFormats", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.AttestationFormats = append(x.AttestationFormats, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_KeyInfo protoreflect.MessageDescriptor + fd_KeyInfo_role protoreflect.FieldDescriptor + fd_KeyInfo_algorithm protoreflect.FieldDescriptor + fd_KeyInfo_encoding protoreflect.FieldDescriptor + fd_KeyInfo_curve protoreflect.FieldDescriptor +) + +func init() { + file_did_v1_params_proto_init() + md_KeyInfo = File_did_v1_params_proto.Messages().ByName("KeyInfo") + fd_KeyInfo_role = md_KeyInfo.Fields().ByName("role") + fd_KeyInfo_algorithm = md_KeyInfo.Fields().ByName("algorithm") + fd_KeyInfo_encoding = md_KeyInfo.Fields().ByName("encoding") + fd_KeyInfo_curve = md_KeyInfo.Fields().ByName("curve") +} + +var _ protoreflect.Message = (*fastReflection_KeyInfo)(nil) + +type fastReflection_KeyInfo KeyInfo + +func (x *KeyInfo) ProtoReflect() protoreflect.Message { + return (*fastReflection_KeyInfo)(x) +} + +func (x *KeyInfo) slowProtoReflect() protoreflect.Message { + mi := &file_did_v1_params_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_KeyInfo_messageType fastReflection_KeyInfo_messageType +var _ protoreflect.MessageType = fastReflection_KeyInfo_messageType{} + +type fastReflection_KeyInfo_messageType struct{} + +func (x fastReflection_KeyInfo_messageType) Zero() protoreflect.Message { + return (*fastReflection_KeyInfo)(nil) +} +func (x fastReflection_KeyInfo_messageType) New() protoreflect.Message { + return new(fastReflection_KeyInfo) +} +func (x fastReflection_KeyInfo_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_KeyInfo +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_KeyInfo) Descriptor() protoreflect.MessageDescriptor { + return md_KeyInfo +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_KeyInfo) Type() protoreflect.MessageType { + return _fastReflection_KeyInfo_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_KeyInfo) New() protoreflect.Message { + return new(fastReflection_KeyInfo) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_KeyInfo) Interface() protoreflect.ProtoMessage { + return (*KeyInfo)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_KeyInfo) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Role != "" { + value := protoreflect.ValueOfString(x.Role) + if !f(fd_KeyInfo_role, value) { + return + } + } + if x.Algorithm != "" { + value := protoreflect.ValueOfString(x.Algorithm) + if !f(fd_KeyInfo_algorithm, value) { + return + } + } + if x.Encoding != "" { + value := protoreflect.ValueOfString(x.Encoding) + if !f(fd_KeyInfo_encoding, value) { + return + } + } + if x.Curve != "" { + value := protoreflect.ValueOfString(x.Curve) + if !f(fd_KeyInfo_curve, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_KeyInfo) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "did.v1.KeyInfo.role": + return x.Role != "" + case "did.v1.KeyInfo.algorithm": + return x.Algorithm != "" + case "did.v1.KeyInfo.encoding": + return x.Encoding != "" + case "did.v1.KeyInfo.curve": + return x.Curve != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) + } + panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_KeyInfo) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "did.v1.KeyInfo.role": + x.Role = "" + case "did.v1.KeyInfo.algorithm": + x.Algorithm = "" + case "did.v1.KeyInfo.encoding": + x.Encoding = "" + case "did.v1.KeyInfo.curve": + x.Curve = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) + } + panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_KeyInfo) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "did.v1.KeyInfo.role": + value := x.Role + return protoreflect.ValueOfString(value) + case "did.v1.KeyInfo.algorithm": + value := x.Algorithm + return protoreflect.ValueOfString(value) + case "did.v1.KeyInfo.encoding": + value := x.Encoding + return protoreflect.ValueOfString(value) + case "did.v1.KeyInfo.curve": + value := x.Curve + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) + } + panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_KeyInfo) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "did.v1.KeyInfo.role": + x.Role = value.Interface().(string) + case "did.v1.KeyInfo.algorithm": + x.Algorithm = value.Interface().(string) + case "did.v1.KeyInfo.encoding": + x.Encoding = value.Interface().(string) + case "did.v1.KeyInfo.curve": + x.Curve = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) + } + panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_KeyInfo) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "did.v1.KeyInfo.role": + panic(fmt.Errorf("field role of message did.v1.KeyInfo is not mutable")) + case "did.v1.KeyInfo.algorithm": + panic(fmt.Errorf("field algorithm of message did.v1.KeyInfo is not mutable")) + case "did.v1.KeyInfo.encoding": + panic(fmt.Errorf("field encoding of message did.v1.KeyInfo is not mutable")) + case "did.v1.KeyInfo.curve": + panic(fmt.Errorf("field curve of message did.v1.KeyInfo is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) + } + panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_KeyInfo) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "did.v1.KeyInfo.role": + return protoreflect.ValueOfString("") + case "did.v1.KeyInfo.algorithm": + return protoreflect.ValueOfString("") + case "did.v1.KeyInfo.encoding": + return protoreflect.ValueOfString("") + case "did.v1.KeyInfo.curve": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.KeyInfo")) + } + panic(fmt.Errorf("message did.v1.KeyInfo does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_KeyInfo) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in did.v1.KeyInfo", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_KeyInfo) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_KeyInfo) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_KeyInfo) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_KeyInfo) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*KeyInfo) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Role) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Algorithm) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Encoding) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Curve) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*KeyInfo) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Curve) > 0 { + i -= len(x.Curve) + copy(dAtA[i:], x.Curve) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Curve))) + i-- + dAtA[i] = 0x22 + } + if len(x.Encoding) > 0 { + i -= len(x.Encoding) + copy(dAtA[i:], x.Encoding) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Encoding))) + i-- + dAtA[i] = 0x1a + } + if len(x.Algorithm) > 0 { + i -= len(x.Algorithm) + copy(dAtA[i:], x.Algorithm) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Algorithm))) + i-- + dAtA[i] = 0x12 + } + if len(x.Role) > 0 { + i -= len(x.Role) + copy(dAtA[i:], x.Role) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Role))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*KeyInfo) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: KeyInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: KeyInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Role = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Algorithm", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Algorithm = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Encoding", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Encoding = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Curve", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Curve = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: did/v1/params.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Params defines the set of module parameters. +type Params struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Whitelisted Key Types + AllowedPublicKeys map[string]*KeyInfo `protobuf:"bytes,2,rep,name=allowed_public_keys,json=allowedPublicKeys,proto3" json:"allowed_public_keys,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // ConveyancePreference defines the conveyance preference + ConveyancePreference string `protobuf:"bytes,3,opt,name=conveyance_preference,json=conveyancePreference,proto3" json:"conveyance_preference,omitempty"` + // AttestationFormats defines the attestation formats + AttestationFormats []string `protobuf:"bytes,4,rep,name=attestation_formats,json=attestationFormats,proto3" json:"attestation_formats,omitempty"` +} + +func (x *Params) Reset() { + *x = Params{} + if protoimpl.UnsafeEnabled { + mi := &file_did_v1_params_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Params) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Params) ProtoMessage() {} + +// Deprecated: Use Params.ProtoReflect.Descriptor instead. +func (*Params) Descriptor() ([]byte, []int) { + return file_did_v1_params_proto_rawDescGZIP(), []int{0} +} + +func (x *Params) GetAllowedPublicKeys() map[string]*KeyInfo { + if x != nil { + return x.AllowedPublicKeys + } + return nil +} + +func (x *Params) GetConveyancePreference() string { + if x != nil { + return x.ConveyancePreference + } + return "" +} + +func (x *Params) GetAttestationFormats() []string { + if x != nil { + return x.AttestationFormats + } + return nil +} + +// KeyInfo defines information for accepted PubKey types +type KeyInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` + Algorithm string `protobuf:"bytes,2,opt,name=algorithm,proto3" json:"algorithm,omitempty"` // e.g., "ES256", "EdDSA", "ES256K" + Encoding string `protobuf:"bytes,3,opt,name=encoding,proto3" json:"encoding,omitempty"` // e.g., "hex", "base64", "multibase" + Curve string `protobuf:"bytes,4,opt,name=curve,proto3" json:"curve,omitempty"` // e.g., "P256", "P384", "P521", "X25519", "X448", +} + +func (x *KeyInfo) Reset() { + *x = KeyInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_did_v1_params_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyInfo) ProtoMessage() {} + +// Deprecated: Use KeyInfo.ProtoReflect.Descriptor instead. +func (*KeyInfo) Descriptor() ([]byte, []int) { + return file_did_v1_params_proto_rawDescGZIP(), []int{1} +} + +func (x *KeyInfo) GetRole() string { + if x != nil { + return x.Role + } + return "" +} + +func (x *KeyInfo) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + +func (x *KeyInfo) GetEncoding() string { + if x != nil { + return x.Encoding + } + return "" +} + +func (x *KeyInfo) GetCurve() string { + if x != nil { + return x.Curve + } + return "" +} + +var File_did_v1_params_proto protoreflect.FileDescriptor + +var file_did_v1_params_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, + 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb5, 0x02, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x12, 0x55, 0x0a, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x41, + 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x33, 0x0a, 0x15, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x79, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x79, 0x61, + 0x6e, 0x63, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2f, 0x0a, + 0x13, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x1a, 0x55, + 0x0a, 0x16, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x69, 0x64, 0x2e, + 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x17, 0x98, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, + 0xe7, 0xb0, 0x2a, 0x0a, 0x64, 0x69, 0x64, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x6d, + 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x1c, 0x0a, + 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x65, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x75, 0x72, 0x76, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x75, 0x72, 0x76, 0x65, 0x42, 0x7b, 0x0a, + 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, + 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, + 0x64, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, + 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, + 0x64, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x07, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_did_v1_params_proto_rawDescOnce sync.Once + file_did_v1_params_proto_rawDescData = file_did_v1_params_proto_rawDesc +) + +func file_did_v1_params_proto_rawDescGZIP() []byte { + file_did_v1_params_proto_rawDescOnce.Do(func() { + file_did_v1_params_proto_rawDescData = protoimpl.X.CompressGZIP(file_did_v1_params_proto_rawDescData) + }) + return file_did_v1_params_proto_rawDescData +} + +var file_did_v1_params_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_did_v1_params_proto_goTypes = []interface{}{ + (*Params)(nil), // 0: did.v1.Params + (*KeyInfo)(nil), // 1: did.v1.KeyInfo + nil, // 2: did.v1.Params.AllowedPublicKeysEntry +} +var file_did_v1_params_proto_depIdxs = []int32{ + 2, // 0: did.v1.Params.allowed_public_keys:type_name -> did.v1.Params.AllowedPublicKeysEntry + 1, // 1: did.v1.Params.AllowedPublicKeysEntry.value:type_name -> did.v1.KeyInfo + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_did_v1_params_proto_init() } +func file_did_v1_params_proto_init() { + if File_did_v1_params_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_did_v1_params_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Params); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_did_v1_params_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_did_v1_params_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_did_v1_params_proto_goTypes, + DependencyIndexes: file_did_v1_params_proto_depIdxs, + MessageInfos: file_did_v1_params_proto_msgTypes, + }.Build() + File_did_v1_params_proto = out.File + file_did_v1_params_proto_rawDesc = nil + file_did_v1_params_proto_goTypes = nil + file_did_v1_params_proto_depIdxs = nil +} diff --git a/api/did/v1/query.pulsar.go b/api/did/v1/query.pulsar.go index 6aff4e648..fea2ff863 100644 --- a/api/did/v1/query.pulsar.go +++ b/api/did/v1/query.pulsar.go @@ -3741,1110 +3741,6 @@ func (x *fastReflection_QueryVerifyResponse) ProtoMethods() *protoiface.Methods } } -var _ protoreflect.List = (*_Document_3_list)(nil) - -type _Document_3_list struct { - list *[]string -} - -func (x *_Document_3_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Document_3_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_Document_3_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_Document_3_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_Document_3_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Document at list field Authentication as it is not of Message kind")) -} - -func (x *_Document_3_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_Document_3_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Document_3_list) IsValid() bool { - return x.list != nil -} - -var _ protoreflect.List = (*_Document_4_list)(nil) - -type _Document_4_list struct { - list *[]string -} - -func (x *_Document_4_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Document_4_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_Document_4_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_Document_4_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_Document_4_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Document at list field AssertionMethod as it is not of Message kind")) -} - -func (x *_Document_4_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_Document_4_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Document_4_list) IsValid() bool { - return x.list != nil -} - -var _ protoreflect.List = (*_Document_5_list)(nil) - -type _Document_5_list struct { - list *[]string -} - -func (x *_Document_5_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Document_5_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_Document_5_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_Document_5_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_Document_5_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Document at list field CapabilityDelegation as it is not of Message kind")) -} - -func (x *_Document_5_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_Document_5_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Document_5_list) IsValid() bool { - return x.list != nil -} - -var _ protoreflect.List = (*_Document_6_list)(nil) - -type _Document_6_list struct { - list *[]string -} - -func (x *_Document_6_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Document_6_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_Document_6_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_Document_6_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_Document_6_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Document at list field CapabilityInvocation as it is not of Message kind")) -} - -func (x *_Document_6_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_Document_6_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Document_6_list) IsValid() bool { - return x.list != nil -} - -var _ protoreflect.List = (*_Document_7_list)(nil) - -type _Document_7_list struct { - list *[]string -} - -func (x *_Document_7_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Document_7_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_Document_7_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_Document_7_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_Document_7_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Document at list field Service as it is not of Message kind")) -} - -func (x *_Document_7_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_Document_7_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Document_7_list) IsValid() bool { - return x.list != nil -} - -var ( - md_Document protoreflect.MessageDescriptor - fd_Document_id protoreflect.FieldDescriptor - fd_Document_controller protoreflect.FieldDescriptor - fd_Document_authentication protoreflect.FieldDescriptor - fd_Document_assertion_method protoreflect.FieldDescriptor - fd_Document_capability_delegation protoreflect.FieldDescriptor - fd_Document_capability_invocation protoreflect.FieldDescriptor - fd_Document_service protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_query_proto_init() - md_Document = File_did_v1_query_proto.Messages().ByName("Document") - fd_Document_id = md_Document.Fields().ByName("id") - fd_Document_controller = md_Document.Fields().ByName("controller") - fd_Document_authentication = md_Document.Fields().ByName("authentication") - fd_Document_assertion_method = md_Document.Fields().ByName("assertion_method") - fd_Document_capability_delegation = md_Document.Fields().ByName("capability_delegation") - fd_Document_capability_invocation = md_Document.Fields().ByName("capability_invocation") - fd_Document_service = md_Document.Fields().ByName("service") -} - -var _ protoreflect.Message = (*fastReflection_Document)(nil) - -type fastReflection_Document Document - -func (x *Document) ProtoReflect() protoreflect.Message { - return (*fastReflection_Document)(x) -} - -func (x *Document) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_query_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Document_messageType fastReflection_Document_messageType -var _ protoreflect.MessageType = fastReflection_Document_messageType{} - -type fastReflection_Document_messageType struct{} - -func (x fastReflection_Document_messageType) Zero() protoreflect.Message { - return (*fastReflection_Document)(nil) -} -func (x fastReflection_Document_messageType) New() protoreflect.Message { - return new(fastReflection_Document) -} -func (x fastReflection_Document_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Document -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Document) Descriptor() protoreflect.MessageDescriptor { - return md_Document -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Document) Type() protoreflect.MessageType { - return _fastReflection_Document_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Document) New() protoreflect.Message { - return new(fastReflection_Document) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Document) Interface() protoreflect.ProtoMessage { - return (*Document)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Document) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != "" { - value := protoreflect.ValueOfString(x.Id) - if !f(fd_Document_id, value) { - return - } - } - if x.Controller != "" { - value := protoreflect.ValueOfString(x.Controller) - if !f(fd_Document_controller, value) { - return - } - } - if len(x.Authentication) != 0 { - value := protoreflect.ValueOfList(&_Document_3_list{list: &x.Authentication}) - if !f(fd_Document_authentication, value) { - return - } - } - if len(x.AssertionMethod) != 0 { - value := protoreflect.ValueOfList(&_Document_4_list{list: &x.AssertionMethod}) - if !f(fd_Document_assertion_method, value) { - return - } - } - if len(x.CapabilityDelegation) != 0 { - value := protoreflect.ValueOfList(&_Document_5_list{list: &x.CapabilityDelegation}) - if !f(fd_Document_capability_delegation, value) { - return - } - } - if len(x.CapabilityInvocation) != 0 { - value := protoreflect.ValueOfList(&_Document_6_list{list: &x.CapabilityInvocation}) - if !f(fd_Document_capability_invocation, value) { - return - } - } - if len(x.Service) != 0 { - value := protoreflect.ValueOfList(&_Document_7_list{list: &x.Service}) - if !f(fd_Document_service, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Document) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.Document.id": - return x.Id != "" - case "did.v1.Document.controller": - return x.Controller != "" - case "did.v1.Document.authentication": - return len(x.Authentication) != 0 - case "did.v1.Document.assertion_method": - return len(x.AssertionMethod) != 0 - case "did.v1.Document.capability_delegation": - return len(x.CapabilityDelegation) != 0 - case "did.v1.Document.capability_invocation": - return len(x.CapabilityInvocation) != 0 - case "did.v1.Document.service": - return len(x.Service) != 0 - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) - } - panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Document) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.Document.id": - x.Id = "" - case "did.v1.Document.controller": - x.Controller = "" - case "did.v1.Document.authentication": - x.Authentication = nil - case "did.v1.Document.assertion_method": - x.AssertionMethod = nil - case "did.v1.Document.capability_delegation": - x.CapabilityDelegation = nil - case "did.v1.Document.capability_invocation": - x.CapabilityInvocation = nil - case "did.v1.Document.service": - x.Service = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) - } - panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Document) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.Document.id": - value := x.Id - return protoreflect.ValueOfString(value) - case "did.v1.Document.controller": - value := x.Controller - return protoreflect.ValueOfString(value) - case "did.v1.Document.authentication": - if len(x.Authentication) == 0 { - return protoreflect.ValueOfList(&_Document_3_list{}) - } - listValue := &_Document_3_list{list: &x.Authentication} - return protoreflect.ValueOfList(listValue) - case "did.v1.Document.assertion_method": - if len(x.AssertionMethod) == 0 { - return protoreflect.ValueOfList(&_Document_4_list{}) - } - listValue := &_Document_4_list{list: &x.AssertionMethod} - return protoreflect.ValueOfList(listValue) - case "did.v1.Document.capability_delegation": - if len(x.CapabilityDelegation) == 0 { - return protoreflect.ValueOfList(&_Document_5_list{}) - } - listValue := &_Document_5_list{list: &x.CapabilityDelegation} - return protoreflect.ValueOfList(listValue) - case "did.v1.Document.capability_invocation": - if len(x.CapabilityInvocation) == 0 { - return protoreflect.ValueOfList(&_Document_6_list{}) - } - listValue := &_Document_6_list{list: &x.CapabilityInvocation} - return protoreflect.ValueOfList(listValue) - case "did.v1.Document.service": - if len(x.Service) == 0 { - return protoreflect.ValueOfList(&_Document_7_list{}) - } - listValue := &_Document_7_list{list: &x.Service} - return protoreflect.ValueOfList(listValue) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) - } - panic(fmt.Errorf("message did.v1.Document does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Document) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.Document.id": - x.Id = value.Interface().(string) - case "did.v1.Document.controller": - x.Controller = value.Interface().(string) - case "did.v1.Document.authentication": - lv := value.List() - clv := lv.(*_Document_3_list) - x.Authentication = *clv.list - case "did.v1.Document.assertion_method": - lv := value.List() - clv := lv.(*_Document_4_list) - x.AssertionMethod = *clv.list - case "did.v1.Document.capability_delegation": - lv := value.List() - clv := lv.(*_Document_5_list) - x.CapabilityDelegation = *clv.list - case "did.v1.Document.capability_invocation": - lv := value.List() - clv := lv.(*_Document_6_list) - x.CapabilityInvocation = *clv.list - case "did.v1.Document.service": - lv := value.List() - clv := lv.(*_Document_7_list) - x.Service = *clv.list - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) - } - panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Document) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Document.authentication": - if x.Authentication == nil { - x.Authentication = []string{} - } - value := &_Document_3_list{list: &x.Authentication} - return protoreflect.ValueOfList(value) - case "did.v1.Document.assertion_method": - if x.AssertionMethod == nil { - x.AssertionMethod = []string{} - } - value := &_Document_4_list{list: &x.AssertionMethod} - return protoreflect.ValueOfList(value) - case "did.v1.Document.capability_delegation": - if x.CapabilityDelegation == nil { - x.CapabilityDelegation = []string{} - } - value := &_Document_5_list{list: &x.CapabilityDelegation} - return protoreflect.ValueOfList(value) - case "did.v1.Document.capability_invocation": - if x.CapabilityInvocation == nil { - x.CapabilityInvocation = []string{} - } - value := &_Document_6_list{list: &x.CapabilityInvocation} - return protoreflect.ValueOfList(value) - case "did.v1.Document.service": - if x.Service == nil { - x.Service = []string{} - } - value := &_Document_7_list{list: &x.Service} - return protoreflect.ValueOfList(value) - case "did.v1.Document.id": - panic(fmt.Errorf("field id of message did.v1.Document is not mutable")) - case "did.v1.Document.controller": - panic(fmt.Errorf("field controller of message did.v1.Document is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) - } - panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Document) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Document.id": - return protoreflect.ValueOfString("") - case "did.v1.Document.controller": - return protoreflect.ValueOfString("") - case "did.v1.Document.authentication": - list := []string{} - return protoreflect.ValueOfList(&_Document_3_list{list: &list}) - case "did.v1.Document.assertion_method": - list := []string{} - return protoreflect.ValueOfList(&_Document_4_list{list: &list}) - case "did.v1.Document.capability_delegation": - list := []string{} - return protoreflect.ValueOfList(&_Document_5_list{list: &list}) - case "did.v1.Document.capability_invocation": - list := []string{} - return protoreflect.ValueOfList(&_Document_6_list{list: &list}) - case "did.v1.Document.service": - list := []string{} - return protoreflect.ValueOfList(&_Document_7_list{list: &list}) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Document")) - } - panic(fmt.Errorf("message did.v1.Document does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Document) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Document", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Document) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Document) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Document) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Document) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Document) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Id) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Controller) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if len(x.Authentication) > 0 { - for _, s := range x.Authentication { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if len(x.AssertionMethod) > 0 { - for _, s := range x.AssertionMethod { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if len(x.CapabilityDelegation) > 0 { - for _, s := range x.CapabilityDelegation { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if len(x.CapabilityInvocation) > 0 { - for _, s := range x.CapabilityInvocation { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if len(x.Service) > 0 { - for _, s := range x.Service { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Document) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Service) > 0 { - for iNdEx := len(x.Service) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.Service[iNdEx]) - copy(dAtA[i:], x.Service[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Service[iNdEx]))) - i-- - dAtA[i] = 0x3a - } - } - if len(x.CapabilityInvocation) > 0 { - for iNdEx := len(x.CapabilityInvocation) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.CapabilityInvocation[iNdEx]) - copy(dAtA[i:], x.CapabilityInvocation[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.CapabilityInvocation[iNdEx]))) - i-- - dAtA[i] = 0x32 - } - } - if len(x.CapabilityDelegation) > 0 { - for iNdEx := len(x.CapabilityDelegation) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.CapabilityDelegation[iNdEx]) - copy(dAtA[i:], x.CapabilityDelegation[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.CapabilityDelegation[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } - if len(x.AssertionMethod) > 0 { - for iNdEx := len(x.AssertionMethod) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.AssertionMethod[iNdEx]) - copy(dAtA[i:], x.AssertionMethod[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.AssertionMethod[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } - if len(x.Authentication) > 0 { - for iNdEx := len(x.Authentication) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.Authentication[iNdEx]) - copy(dAtA[i:], x.Authentication[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authentication[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(x.Controller) > 0 { - i -= len(x.Controller) - copy(dAtA[i:], x.Controller) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) - i-- - dAtA[i] = 0x12 - } - if len(x.Id) > 0 { - i -= len(x.Id) - copy(dAtA[i:], x.Id) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Id))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Document) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Document: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Document: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authentication", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Authentication = append(x.Authentication, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AssertionMethod", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.AssertionMethod = append(x.AssertionMethod, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 5: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CapabilityDelegation", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.CapabilityDelegation = append(x.CapabilityDelegation, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 6: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CapabilityInvocation", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.CapabilityInvocation = append(x.CapabilityInvocation, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 7: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Service = append(x.Service, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.0 @@ -5210,185 +4106,80 @@ func (x *QueryVerifyResponse) GetValid() bool { return false } -// Document defines a DID document -type Document struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` // The DID of the controller - Authentication []string `protobuf:"bytes,3,rep,name=authentication,proto3" json:"authentication,omitempty"` - AssertionMethod []string `protobuf:"bytes,4,rep,name=assertion_method,json=assertionMethod,proto3" json:"assertion_method,omitempty"` - CapabilityDelegation []string `protobuf:"bytes,5,rep,name=capability_delegation,json=capabilityDelegation,proto3" json:"capability_delegation,omitempty"` - CapabilityInvocation []string `protobuf:"bytes,6,rep,name=capability_invocation,json=capabilityInvocation,proto3" json:"capability_invocation,omitempty"` - Service []string `protobuf:"bytes,7,rep,name=service,proto3" json:"service,omitempty"` -} - -func (x *Document) Reset() { - *x = Document{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_query_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Document) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Document) ProtoMessage() {} - -// Deprecated: Use Document.ProtoReflect.Descriptor instead. -func (*Document) Descriptor() ([]byte, []int) { - return file_did_v1_query_proto_rawDescGZIP(), []int{7} -} - -func (x *Document) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Document) GetController() string { - if x != nil { - return x.Controller - } - return "" -} - -func (x *Document) GetAuthentication() []string { - if x != nil { - return x.Authentication - } - return nil -} - -func (x *Document) GetAssertionMethod() []string { - if x != nil { - return x.AssertionMethod - } - return nil -} - -func (x *Document) GetCapabilityDelegation() []string { - if x != nil { - return x.CapabilityDelegation - } - return nil -} - -func (x *Document) GetCapabilityInvocation() []string { - if x != nil { - return x.CapabilityInvocation - } - return nil -} - -func (x *Document) GetService() []string { - if x != nil { - return x.Service - } - return nil -} - var File_did_v1_query_proto protoreflect.FileDescriptor var file_did_v1_query_proto_rawDesc = []byte{ 0x0a, 0x12, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x1a, 0x14, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x60, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x74, 0x6f, 0x1a, 0x13, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x22, 0x3d, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, + 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x44, 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, + 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x08, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x7e, 0x0a, 0x10, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x22, 0x3d, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, 0x64, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x22, 0x44, 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x64, 0x69, - 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x64, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x7e, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, - 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x31, 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x12, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x64, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x2b, 0x0a, 0x13, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x22, 0x91, 0x02, 0x0a, 0x08, 0x44, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, - 0x10, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, - 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x33, 0x0a, 0x15, 0x63, 0x61, 0x70, 0x61, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, - 0x15, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x76, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x63, 0x61, - 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0xec, 0x02, 0x0a, - 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x53, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x12, 0x14, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x64, 0x69, - 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x54, 0x0a, 0x07, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x12, 0x14, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x64, - 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x64, 0x69, 0x64, - 0x7d, 0x12, 0x57, 0x0a, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x18, 0x2e, 0x64, 0x69, 0x64, 0x2e, - 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x22, 0x12, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, - 0x7b, 0x64, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x5f, 0x0a, 0x06, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x79, 0x12, 0x1a, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1b, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x7b, - 0x64, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x42, 0x7a, 0x0a, 0x0a, 0x63, - 0x6f, 0x6d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, 0x31, - 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, 0xca, - 0x02, 0x06, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, 0x56, - 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, - 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x31, 0x0a, 0x11, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, + 0x9e, 0x01, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x22, 0x2b, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x32, 0x93, 0x02, + 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x53, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x12, 0x14, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x64, + 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x54, 0x0a, 0x07, + 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x12, 0x14, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, + 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x64, 0x69, + 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x06, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1a, 0x2e, 0x64, + 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, + 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x64, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, + 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, + 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, + 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, + 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, + 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5403,7 +4194,7 @@ func file_did_v1_query_proto_rawDescGZIP() []byte { return file_did_v1_query_proto_rawDescData } -var file_did_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_did_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_did_v1_query_proto_goTypes = []interface{}{ (*QueryRequest)(nil), // 0: did.v1.QueryRequest (*QueryParamsResponse)(nil), // 1: did.v1.QueryParamsResponse @@ -5412,22 +4203,20 @@ var file_did_v1_query_proto_goTypes = []interface{}{ (*QuerySignResponse)(nil), // 4: did.v1.QuerySignResponse (*QueryVerifyRequest)(nil), // 5: did.v1.QueryVerifyRequest (*QueryVerifyResponse)(nil), // 6: did.v1.QueryVerifyResponse - (*Document)(nil), // 7: did.v1.Document - (*Params)(nil), // 8: did.v1.Params + (*Params)(nil), // 7: did.v1.Params + (*Document)(nil), // 8: did.v1.Document } var file_did_v1_query_proto_depIdxs = []int32{ - 8, // 0: did.v1.QueryParamsResponse.params:type_name -> did.v1.Params - 7, // 1: did.v1.QueryResolveResponse.document:type_name -> did.v1.Document + 7, // 0: did.v1.QueryParamsResponse.params:type_name -> did.v1.Params + 8, // 1: did.v1.QueryResolveResponse.document:type_name -> did.v1.Document 0, // 2: did.v1.Query.Params:input_type -> did.v1.QueryRequest 0, // 3: did.v1.Query.Resolve:input_type -> did.v1.QueryRequest - 3, // 4: did.v1.Query.Sign:input_type -> did.v1.QuerySignRequest - 5, // 5: did.v1.Query.Verify:input_type -> did.v1.QueryVerifyRequest - 1, // 6: did.v1.Query.Params:output_type -> did.v1.QueryParamsResponse - 2, // 7: did.v1.Query.Resolve:output_type -> did.v1.QueryResolveResponse - 4, // 8: did.v1.Query.Sign:output_type -> did.v1.QuerySignResponse - 6, // 9: did.v1.Query.Verify:output_type -> did.v1.QueryVerifyResponse - 6, // [6:10] is the sub-list for method output_type - 2, // [2:6] is the sub-list for method input_type + 5, // 4: did.v1.Query.Verify:input_type -> did.v1.QueryVerifyRequest + 1, // 5: did.v1.Query.Params:output_type -> did.v1.QueryParamsResponse + 2, // 6: did.v1.Query.Resolve:output_type -> did.v1.QueryResolveResponse + 6, // 7: did.v1.Query.Verify:output_type -> did.v1.QueryVerifyResponse + 5, // [5:8] is the sub-list for method output_type + 2, // [2:5] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name 2, // [2:2] is the sub-list for extension extendee 0, // [0:2] is the sub-list for field type_name @@ -5439,6 +4228,7 @@ func file_did_v1_query_proto_init() { return } file_did_v1_genesis_proto_init() + file_did_v1_params_proto_init() if !protoimpl.UnsafeEnabled { file_did_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryRequest); i { @@ -5524,18 +4314,6 @@ func file_did_v1_query_proto_init() { return nil } } - file_did_v1_query_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Document); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } type x struct{} out := protoimpl.TypeBuilder{ @@ -5543,7 +4321,7 @@ func file_did_v1_query_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_did_v1_query_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 7, NumExtensions: 0, NumServices: 1, }, diff --git a/api/did/v1/query_grpc.pb.go b/api/did/v1/query_grpc.pb.go index 3aaa5ebbb..1d4d55b41 100644 --- a/api/did/v1/query_grpc.pb.go +++ b/api/did/v1/query_grpc.pb.go @@ -21,7 +21,6 @@ const _ = grpc.SupportPackageIsVersion9 const ( Query_Params_FullMethodName = "/did.v1.Query/Params" Query_Resolve_FullMethodName = "/did.v1.Query/Resolve" - Query_Sign_FullMethodName = "/did.v1.Query/Sign" Query_Verify_FullMethodName = "/did.v1.Query/Verify" ) @@ -35,8 +34,6 @@ type QueryClient interface { Params(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) // Resolve queries the DID document by its id. Resolve(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryResolveResponse, error) - // Sign signs a message with the DID document - Sign(ctx context.Context, in *QuerySignRequest, opts ...grpc.CallOption) (*QuerySignResponse, error) // Verify verifies a message with the DID document Verify(ctx context.Context, in *QueryVerifyRequest, opts ...grpc.CallOption) (*QueryVerifyResponse, error) } @@ -69,16 +66,6 @@ func (c *queryClient) Resolve(ctx context.Context, in *QueryRequest, opts ...grp return out, nil } -func (c *queryClient) Sign(ctx context.Context, in *QuerySignRequest, opts ...grpc.CallOption) (*QuerySignResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QuerySignResponse) - err := c.cc.Invoke(ctx, Query_Sign_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *queryClient) Verify(ctx context.Context, in *QueryVerifyRequest, opts ...grpc.CallOption) (*QueryVerifyResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(QueryVerifyResponse) @@ -99,8 +86,6 @@ type QueryServer interface { Params(context.Context, *QueryRequest) (*QueryParamsResponse, error) // Resolve queries the DID document by its id. Resolve(context.Context, *QueryRequest) (*QueryResolveResponse, error) - // Sign signs a message with the DID document - Sign(context.Context, *QuerySignRequest) (*QuerySignResponse, error) // Verify verifies a message with the DID document Verify(context.Context, *QueryVerifyRequest) (*QueryVerifyResponse, error) mustEmbedUnimplementedQueryServer() @@ -119,9 +104,6 @@ func (UnimplementedQueryServer) Params(context.Context, *QueryRequest) (*QueryPa func (UnimplementedQueryServer) Resolve(context.Context, *QueryRequest) (*QueryResolveResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Resolve not implemented") } -func (UnimplementedQueryServer) Sign(context.Context, *QuerySignRequest) (*QuerySignResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Sign not implemented") -} func (UnimplementedQueryServer) Verify(context.Context, *QueryVerifyRequest) (*QueryVerifyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Verify not implemented") } @@ -182,24 +164,6 @@ func _Query_Resolve_Handler(srv interface{}, ctx context.Context, dec func(inter return interceptor(ctx, in, info, handler) } -func _Query_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QuerySignRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Sign(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Query_Sign_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Sign(ctx, req.(*QuerySignRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _Query_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryVerifyRequest) if err := dec(in); err != nil { @@ -233,10 +197,6 @@ var Query_ServiceDesc = grpc.ServiceDesc{ MethodName: "Resolve", Handler: _Query_Resolve_Handler, }, - { - MethodName: "Sign", - Handler: _Query_Sign_Handler, - }, { MethodName: "Verify", Handler: _Query_Verify_Handler, diff --git a/api/did/v1/state.cosmos_orm.go b/api/did/v1/state.cosmos_orm.go index 96239bc31..39ed930dc 100644 --- a/api/did/v1/state.cosmos_orm.go +++ b/api/did/v1/state.cosmos_orm.go @@ -323,6 +323,173 @@ func NewAuthenticationTable(db ormtable.Schema) (AuthenticationTable, error) { return authenticationTable{table}, nil } +type BiscuitTable interface { + Insert(ctx context.Context, biscuit *Biscuit) error + InsertReturningId(ctx context.Context, biscuit *Biscuit) (uint64, error) + LastInsertedSequence(ctx context.Context) (uint64, error) + Update(ctx context.Context, biscuit *Biscuit) error + Save(ctx context.Context, biscuit *Biscuit) error + Delete(ctx context.Context, biscuit *Biscuit) error + Has(ctx context.Context, id uint64) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, id uint64) (*Biscuit, error) + HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) + // GetBySubjectOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Biscuit, error) + List(ctx context.Context, prefixKey BiscuitIndexKey, opts ...ormlist.Option) (BiscuitIterator, error) + ListRange(ctx context.Context, from, to BiscuitIndexKey, opts ...ormlist.Option) (BiscuitIterator, error) + DeleteBy(ctx context.Context, prefixKey BiscuitIndexKey) error + DeleteRange(ctx context.Context, from, to BiscuitIndexKey) error + + doNotImplement() +} + +type BiscuitIterator struct { + ormtable.Iterator +} + +func (i BiscuitIterator) Value() (*Biscuit, error) { + var biscuit Biscuit + err := i.UnmarshalMessage(&biscuit) + return &biscuit, err +} + +type BiscuitIndexKey interface { + id() uint32 + values() []interface{} + biscuitIndexKey() +} + +// primary key starting index.. +type BiscuitPrimaryKey = BiscuitIdIndexKey + +type BiscuitIdIndexKey struct { + vs []interface{} +} + +func (x BiscuitIdIndexKey) id() uint32 { return 0 } +func (x BiscuitIdIndexKey) values() []interface{} { return x.vs } +func (x BiscuitIdIndexKey) biscuitIndexKey() {} + +func (this BiscuitIdIndexKey) WithId(id uint64) BiscuitIdIndexKey { + this.vs = []interface{}{id} + return this +} + +type BiscuitSubjectOriginIndexKey struct { + vs []interface{} +} + +func (x BiscuitSubjectOriginIndexKey) id() uint32 { return 1 } +func (x BiscuitSubjectOriginIndexKey) values() []interface{} { return x.vs } +func (x BiscuitSubjectOriginIndexKey) biscuitIndexKey() {} + +func (this BiscuitSubjectOriginIndexKey) WithSubject(subject string) BiscuitSubjectOriginIndexKey { + this.vs = []interface{}{subject} + return this +} + +func (this BiscuitSubjectOriginIndexKey) WithSubjectOrigin(subject string, origin string) BiscuitSubjectOriginIndexKey { + this.vs = []interface{}{subject, origin} + return this +} + +type biscuitTable struct { + table ormtable.AutoIncrementTable +} + +func (this biscuitTable) Insert(ctx context.Context, biscuit *Biscuit) error { + return this.table.Insert(ctx, biscuit) +} + +func (this biscuitTable) Update(ctx context.Context, biscuit *Biscuit) error { + return this.table.Update(ctx, biscuit) +} + +func (this biscuitTable) Save(ctx context.Context, biscuit *Biscuit) error { + return this.table.Save(ctx, biscuit) +} + +func (this biscuitTable) Delete(ctx context.Context, biscuit *Biscuit) error { + return this.table.Delete(ctx, biscuit) +} + +func (this biscuitTable) InsertReturningId(ctx context.Context, biscuit *Biscuit) (uint64, error) { + return this.table.InsertReturningPKey(ctx, biscuit) +} + +func (this biscuitTable) LastInsertedSequence(ctx context.Context) (uint64, error) { + return this.table.LastInsertedSequence(ctx) +} + +func (this biscuitTable) Has(ctx context.Context, id uint64) (found bool, err error) { + return this.table.PrimaryKey().Has(ctx, id) +} + +func (this biscuitTable) Get(ctx context.Context, id uint64) (*Biscuit, error) { + var biscuit Biscuit + found, err := this.table.PrimaryKey().Get(ctx, &biscuit, id) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &biscuit, nil +} + +func (this biscuitTable) HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) { + return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, + subject, + origin, + ) +} + +func (this biscuitTable) GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Biscuit, error) { + var biscuit Biscuit + found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &biscuit, + subject, + origin, + ) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &biscuit, nil +} + +func (this biscuitTable) List(ctx context.Context, prefixKey BiscuitIndexKey, opts ...ormlist.Option) (BiscuitIterator, error) { + it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) + return BiscuitIterator{it}, err +} + +func (this biscuitTable) ListRange(ctx context.Context, from, to BiscuitIndexKey, opts ...ormlist.Option) (BiscuitIterator, error) { + it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) + return BiscuitIterator{it}, err +} + +func (this biscuitTable) DeleteBy(ctx context.Context, prefixKey BiscuitIndexKey) error { + return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) +} + +func (this biscuitTable) DeleteRange(ctx context.Context, from, to BiscuitIndexKey) error { + return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) +} + +func (this biscuitTable) doNotImplement() {} + +var _ BiscuitTable = biscuitTable{} + +func NewBiscuitTable(db ormtable.Schema) (BiscuitTable, error) { + table := db.GetTable(&Biscuit{}) + if table == nil { + return nil, ormerrors.TableNotFound.Wrap(string((&Biscuit{}).ProtoReflect().Descriptor().FullName())) + } + return biscuitTable{table.(ormtable.AutoIncrementTable)}, nil +} + type ControllerTable interface { Insert(ctx context.Context, controller *Controller) error InsertReturningNumber(ctx context.Context, controller *Controller) (uint64, error) @@ -591,340 +758,6 @@ func NewControllerTable(db ormtable.Schema) (ControllerTable, error) { return controllerTable{table.(ormtable.AutoIncrementTable)}, nil } -type GrantTable interface { - Insert(ctx context.Context, grant *Grant) error - InsertReturningId(ctx context.Context, grant *Grant) (uint64, error) - LastInsertedSequence(ctx context.Context) (uint64, error) - Update(ctx context.Context, grant *Grant) error - Save(ctx context.Context, grant *Grant) error - Delete(ctx context.Context, grant *Grant) error - Has(ctx context.Context, id uint64) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, id uint64) (*Grant, error) - HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) - // GetBySubjectOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Grant, error) - List(ctx context.Context, prefixKey GrantIndexKey, opts ...ormlist.Option) (GrantIterator, error) - ListRange(ctx context.Context, from, to GrantIndexKey, opts ...ormlist.Option) (GrantIterator, error) - DeleteBy(ctx context.Context, prefixKey GrantIndexKey) error - DeleteRange(ctx context.Context, from, to GrantIndexKey) error - - doNotImplement() -} - -type GrantIterator struct { - ormtable.Iterator -} - -func (i GrantIterator) Value() (*Grant, error) { - var grant Grant - err := i.UnmarshalMessage(&grant) - return &grant, err -} - -type GrantIndexKey interface { - id() uint32 - values() []interface{} - grantIndexKey() -} - -// primary key starting index.. -type GrantPrimaryKey = GrantIdIndexKey - -type GrantIdIndexKey struct { - vs []interface{} -} - -func (x GrantIdIndexKey) id() uint32 { return 0 } -func (x GrantIdIndexKey) values() []interface{} { return x.vs } -func (x GrantIdIndexKey) grantIndexKey() {} - -func (this GrantIdIndexKey) WithId(id uint64) GrantIdIndexKey { - this.vs = []interface{}{id} - return this -} - -type GrantSubjectOriginIndexKey struct { - vs []interface{} -} - -func (x GrantSubjectOriginIndexKey) id() uint32 { return 1 } -func (x GrantSubjectOriginIndexKey) values() []interface{} { return x.vs } -func (x GrantSubjectOriginIndexKey) grantIndexKey() {} - -func (this GrantSubjectOriginIndexKey) WithSubject(subject string) GrantSubjectOriginIndexKey { - this.vs = []interface{}{subject} - return this -} - -func (this GrantSubjectOriginIndexKey) WithSubjectOrigin(subject string, origin string) GrantSubjectOriginIndexKey { - this.vs = []interface{}{subject, origin} - return this -} - -type grantTable struct { - table ormtable.AutoIncrementTable -} - -func (this grantTable) Insert(ctx context.Context, grant *Grant) error { - return this.table.Insert(ctx, grant) -} - -func (this grantTable) Update(ctx context.Context, grant *Grant) error { - return this.table.Update(ctx, grant) -} - -func (this grantTable) Save(ctx context.Context, grant *Grant) error { - return this.table.Save(ctx, grant) -} - -func (this grantTable) Delete(ctx context.Context, grant *Grant) error { - return this.table.Delete(ctx, grant) -} - -func (this grantTable) InsertReturningId(ctx context.Context, grant *Grant) (uint64, error) { - return this.table.InsertReturningPKey(ctx, grant) -} - -func (this grantTable) LastInsertedSequence(ctx context.Context) (uint64, error) { - return this.table.LastInsertedSequence(ctx) -} - -func (this grantTable) Has(ctx context.Context, id uint64) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, id) -} - -func (this grantTable) Get(ctx context.Context, id uint64) (*Grant, error) { - var grant Grant - found, err := this.table.PrimaryKey().Get(ctx, &grant, id) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &grant, nil -} - -func (this grantTable) HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) { - return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, - subject, - origin, - ) -} - -func (this grantTable) GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Grant, error) { - var grant Grant - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &grant, - subject, - origin, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &grant, nil -} - -func (this grantTable) List(ctx context.Context, prefixKey GrantIndexKey, opts ...ormlist.Option) (GrantIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return GrantIterator{it}, err -} - -func (this grantTable) ListRange(ctx context.Context, from, to GrantIndexKey, opts ...ormlist.Option) (GrantIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return GrantIterator{it}, err -} - -func (this grantTable) DeleteBy(ctx context.Context, prefixKey GrantIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this grantTable) DeleteRange(ctx context.Context, from, to GrantIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this grantTable) doNotImplement() {} - -var _ GrantTable = grantTable{} - -func NewGrantTable(db ormtable.Schema) (GrantTable, error) { - table := db.GetTable(&Grant{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Grant{}).ProtoReflect().Descriptor().FullName())) - } - return grantTable{table.(ormtable.AutoIncrementTable)}, nil -} - -type MacaroonTable interface { - Insert(ctx context.Context, macaroon *Macaroon) error - InsertReturningId(ctx context.Context, macaroon *Macaroon) (uint64, error) - LastInsertedSequence(ctx context.Context) (uint64, error) - Update(ctx context.Context, macaroon *Macaroon) error - Save(ctx context.Context, macaroon *Macaroon) error - Delete(ctx context.Context, macaroon *Macaroon) error - Has(ctx context.Context, id uint64) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, id uint64) (*Macaroon, error) - HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) - // GetBySubjectOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Macaroon, error) - List(ctx context.Context, prefixKey MacaroonIndexKey, opts ...ormlist.Option) (MacaroonIterator, error) - ListRange(ctx context.Context, from, to MacaroonIndexKey, opts ...ormlist.Option) (MacaroonIterator, error) - DeleteBy(ctx context.Context, prefixKey MacaroonIndexKey) error - DeleteRange(ctx context.Context, from, to MacaroonIndexKey) error - - doNotImplement() -} - -type MacaroonIterator struct { - ormtable.Iterator -} - -func (i MacaroonIterator) Value() (*Macaroon, error) { - var macaroon Macaroon - err := i.UnmarshalMessage(&macaroon) - return &macaroon, err -} - -type MacaroonIndexKey interface { - id() uint32 - values() []interface{} - macaroonIndexKey() -} - -// primary key starting index.. -type MacaroonPrimaryKey = MacaroonIdIndexKey - -type MacaroonIdIndexKey struct { - vs []interface{} -} - -func (x MacaroonIdIndexKey) id() uint32 { return 0 } -func (x MacaroonIdIndexKey) values() []interface{} { return x.vs } -func (x MacaroonIdIndexKey) macaroonIndexKey() {} - -func (this MacaroonIdIndexKey) WithId(id uint64) MacaroonIdIndexKey { - this.vs = []interface{}{id} - return this -} - -type MacaroonSubjectOriginIndexKey struct { - vs []interface{} -} - -func (x MacaroonSubjectOriginIndexKey) id() uint32 { return 1 } -func (x MacaroonSubjectOriginIndexKey) values() []interface{} { return x.vs } -func (x MacaroonSubjectOriginIndexKey) macaroonIndexKey() {} - -func (this MacaroonSubjectOriginIndexKey) WithSubject(subject string) MacaroonSubjectOriginIndexKey { - this.vs = []interface{}{subject} - return this -} - -func (this MacaroonSubjectOriginIndexKey) WithSubjectOrigin(subject string, origin string) MacaroonSubjectOriginIndexKey { - this.vs = []interface{}{subject, origin} - return this -} - -type macaroonTable struct { - table ormtable.AutoIncrementTable -} - -func (this macaroonTable) Insert(ctx context.Context, macaroon *Macaroon) error { - return this.table.Insert(ctx, macaroon) -} - -func (this macaroonTable) Update(ctx context.Context, macaroon *Macaroon) error { - return this.table.Update(ctx, macaroon) -} - -func (this macaroonTable) Save(ctx context.Context, macaroon *Macaroon) error { - return this.table.Save(ctx, macaroon) -} - -func (this macaroonTable) Delete(ctx context.Context, macaroon *Macaroon) error { - return this.table.Delete(ctx, macaroon) -} - -func (this macaroonTable) InsertReturningId(ctx context.Context, macaroon *Macaroon) (uint64, error) { - return this.table.InsertReturningPKey(ctx, macaroon) -} - -func (this macaroonTable) LastInsertedSequence(ctx context.Context) (uint64, error) { - return this.table.LastInsertedSequence(ctx) -} - -func (this macaroonTable) Has(ctx context.Context, id uint64) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, id) -} - -func (this macaroonTable) Get(ctx context.Context, id uint64) (*Macaroon, error) { - var macaroon Macaroon - found, err := this.table.PrimaryKey().Get(ctx, &macaroon, id) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &macaroon, nil -} - -func (this macaroonTable) HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) { - return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, - subject, - origin, - ) -} - -func (this macaroonTable) GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Macaroon, error) { - var macaroon Macaroon - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &macaroon, - subject, - origin, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &macaroon, nil -} - -func (this macaroonTable) List(ctx context.Context, prefixKey MacaroonIndexKey, opts ...ormlist.Option) (MacaroonIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return MacaroonIterator{it}, err -} - -func (this macaroonTable) ListRange(ctx context.Context, from, to MacaroonIndexKey, opts ...ormlist.Option) (MacaroonIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return MacaroonIterator{it}, err -} - -func (this macaroonTable) DeleteBy(ctx context.Context, prefixKey MacaroonIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this macaroonTable) DeleteRange(ctx context.Context, from, to MacaroonIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this macaroonTable) doNotImplement() {} - -var _ MacaroonTable = macaroonTable{} - -func NewMacaroonTable(db ormtable.Schema) (MacaroonTable, error) { - table := db.GetTable(&Macaroon{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Macaroon{}).ProtoReflect().Descriptor().FullName())) - } - return macaroonTable{table.(ormtable.AutoIncrementTable)}, nil -} - type VerificationTable interface { Insert(ctx context.Context, verification *Verification) error Update(ctx context.Context, verification *Verification) error @@ -1185,9 +1018,8 @@ func NewVerificationTable(db ormtable.Schema) (VerificationTable, error) { type StateStore interface { AssertionTable() AssertionTable AuthenticationTable() AuthenticationTable + BiscuitTable() BiscuitTable ControllerTable() ControllerTable - GrantTable() GrantTable - MacaroonTable() MacaroonTable VerificationTable() VerificationTable doNotImplement() @@ -1196,9 +1028,8 @@ type StateStore interface { type stateStore struct { assertion AssertionTable authentication AuthenticationTable + biscuit BiscuitTable controller ControllerTable - grant GrantTable - macaroon MacaroonTable verification VerificationTable } @@ -1210,18 +1041,14 @@ func (x stateStore) AuthenticationTable() AuthenticationTable { return x.authentication } +func (x stateStore) BiscuitTable() BiscuitTable { + return x.biscuit +} + func (x stateStore) ControllerTable() ControllerTable { return x.controller } -func (x stateStore) GrantTable() GrantTable { - return x.grant -} - -func (x stateStore) MacaroonTable() MacaroonTable { - return x.macaroon -} - func (x stateStore) VerificationTable() VerificationTable { return x.verification } @@ -1241,21 +1068,16 @@ func NewStateStore(db ormtable.Schema) (StateStore, error) { return nil, err } + biscuitTable, err := NewBiscuitTable(db) + if err != nil { + return nil, err + } + controllerTable, err := NewControllerTable(db) if err != nil { return nil, err } - grantTable, err := NewGrantTable(db) - if err != nil { - return nil, err - } - - macaroonTable, err := NewMacaroonTable(db) - if err != nil { - return nil, err - } - verificationTable, err := NewVerificationTable(db) if err != nil { return nil, err @@ -1264,9 +1086,8 @@ func NewStateStore(db ormtable.Schema) (StateStore, error) { return stateStore{ assertionTable, authenticationTable, + biscuitTable, controllerTable, - grantTable, - macaroonTable, verificationTable, }, nil } diff --git a/api/did/v1/state.pulsar.go b/api/did/v1/state.pulsar.go index 11a4d3212..7fe1e9a98 100644 --- a/api/did/v1/state.pulsar.go +++ b/api/did/v1/state.pulsar.go @@ -101,7 +101,7 @@ var ( fd_Assertion_did protoreflect.FieldDescriptor fd_Assertion_controller protoreflect.FieldDescriptor fd_Assertion_subject protoreflect.FieldDescriptor - fd_Assertion_public_key protoreflect.FieldDescriptor + fd_Assertion_public_key_hex protoreflect.FieldDescriptor fd_Assertion_assertion_type protoreflect.FieldDescriptor fd_Assertion_accumulator protoreflect.FieldDescriptor fd_Assertion_creation_block protoreflect.FieldDescriptor @@ -113,7 +113,7 @@ func init() { fd_Assertion_did = md_Assertion.Fields().ByName("did") fd_Assertion_controller = md_Assertion.Fields().ByName("controller") fd_Assertion_subject = md_Assertion.Fields().ByName("subject") - fd_Assertion_public_key = md_Assertion.Fields().ByName("public_key") + fd_Assertion_public_key_hex = md_Assertion.Fields().ByName("public_key_hex") fd_Assertion_assertion_type = md_Assertion.Fields().ByName("assertion_type") fd_Assertion_accumulator = md_Assertion.Fields().ByName("accumulator") fd_Assertion_creation_block = md_Assertion.Fields().ByName("creation_block") @@ -202,9 +202,9 @@ func (x *fastReflection_Assertion) Range(f func(protoreflect.FieldDescriptor, pr return } } - if x.PublicKey != nil { - value := protoreflect.ValueOfMessage(x.PublicKey.ProtoReflect()) - if !f(fd_Assertion_public_key, value) { + if x.PublicKeyHex != "" { + value := protoreflect.ValueOfString(x.PublicKeyHex) + if !f(fd_Assertion_public_key_hex, value) { return } } @@ -247,8 +247,8 @@ func (x *fastReflection_Assertion) Has(fd protoreflect.FieldDescriptor) bool { return x.Controller != "" case "did.v1.Assertion.subject": return x.Subject != "" - case "did.v1.Assertion.public_key": - return x.PublicKey != nil + case "did.v1.Assertion.public_key_hex": + return x.PublicKeyHex != "" case "did.v1.Assertion.assertion_type": return x.AssertionType != "" case "did.v1.Assertion.accumulator": @@ -277,8 +277,8 @@ func (x *fastReflection_Assertion) Clear(fd protoreflect.FieldDescriptor) { x.Controller = "" case "did.v1.Assertion.subject": x.Subject = "" - case "did.v1.Assertion.public_key": - x.PublicKey = nil + case "did.v1.Assertion.public_key_hex": + x.PublicKeyHex = "" case "did.v1.Assertion.assertion_type": x.AssertionType = "" case "did.v1.Assertion.accumulator": @@ -310,9 +310,9 @@ func (x *fastReflection_Assertion) Get(descriptor protoreflect.FieldDescriptor) case "did.v1.Assertion.subject": value := x.Subject return protoreflect.ValueOfString(value) - case "did.v1.Assertion.public_key": - value := x.PublicKey - return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "did.v1.Assertion.public_key_hex": + value := x.PublicKeyHex + return protoreflect.ValueOfString(value) case "did.v1.Assertion.assertion_type": value := x.AssertionType return protoreflect.ValueOfString(value) @@ -351,8 +351,8 @@ func (x *fastReflection_Assertion) Set(fd protoreflect.FieldDescriptor, value pr x.Controller = value.Interface().(string) case "did.v1.Assertion.subject": x.Subject = value.Interface().(string) - case "did.v1.Assertion.public_key": - x.PublicKey = value.Message().Interface().(*PubKey) + case "did.v1.Assertion.public_key_hex": + x.PublicKeyHex = value.Interface().(string) case "did.v1.Assertion.assertion_type": x.AssertionType = value.Interface().(string) case "did.v1.Assertion.accumulator": @@ -381,11 +381,6 @@ func (x *fastReflection_Assertion) Set(fd protoreflect.FieldDescriptor, value pr // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Assertion) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Assertion.public_key": - if x.PublicKey == nil { - x.PublicKey = new(PubKey) - } - return protoreflect.ValueOfMessage(x.PublicKey.ProtoReflect()) case "did.v1.Assertion.accumulator": if x.Accumulator == nil { x.Accumulator = make(map[string][]byte) @@ -398,6 +393,8 @@ func (x *fastReflection_Assertion) Mutable(fd protoreflect.FieldDescriptor) prot panic(fmt.Errorf("field controller of message did.v1.Assertion is not mutable")) case "did.v1.Assertion.subject": panic(fmt.Errorf("field subject of message did.v1.Assertion is not mutable")) + case "did.v1.Assertion.public_key_hex": + panic(fmt.Errorf("field public_key_hex of message did.v1.Assertion is not mutable")) case "did.v1.Assertion.assertion_type": panic(fmt.Errorf("field assertion_type of message did.v1.Assertion is not mutable")) case "did.v1.Assertion.creation_block": @@ -421,9 +418,8 @@ func (x *fastReflection_Assertion) NewField(fd protoreflect.FieldDescriptor) pro return protoreflect.ValueOfString("") case "did.v1.Assertion.subject": return protoreflect.ValueOfString("") - case "did.v1.Assertion.public_key": - m := new(PubKey) - return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "did.v1.Assertion.public_key_hex": + return protoreflect.ValueOfString("") case "did.v1.Assertion.assertion_type": return protoreflect.ValueOfString("") case "did.v1.Assertion.accumulator": @@ -512,8 +508,8 @@ func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if x.PublicKey != nil { - l = options.Size(x.PublicKey) + l = len(x.PublicKeyHex) + if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } l = len(x.AssertionType) @@ -629,17 +625,10 @@ func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { i-- dAtA[i] = 0x2a } - if x.PublicKey != nil { - encoded, err := options.Marshal(x.PublicKey) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + if len(x.PublicKeyHex) > 0 { + i -= len(x.PublicKeyHex) + copy(dAtA[i:], x.PublicKeyHex) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicKeyHex))) i-- dAtA[i] = 0x22 } @@ -811,9 +800,9 @@ func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { iNdEx = postIndex case 4: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -823,27 +812,23 @@ func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - if x.PublicKey == nil { - x.PublicKey = &PubKey{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.PublicKey); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } + x.PublicKeyHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { @@ -1146,7 +1131,7 @@ var ( fd_Authentication_did protoreflect.FieldDescriptor fd_Authentication_controller protoreflect.FieldDescriptor fd_Authentication_subject protoreflect.FieldDescriptor - fd_Authentication_public_key protoreflect.FieldDescriptor + fd_Authentication_public_key_hex protoreflect.FieldDescriptor fd_Authentication_credential_id protoreflect.FieldDescriptor fd_Authentication_metadata protoreflect.FieldDescriptor fd_Authentication_creation_block protoreflect.FieldDescriptor @@ -1158,7 +1143,7 @@ func init() { fd_Authentication_did = md_Authentication.Fields().ByName("did") fd_Authentication_controller = md_Authentication.Fields().ByName("controller") fd_Authentication_subject = md_Authentication.Fields().ByName("subject") - fd_Authentication_public_key = md_Authentication.Fields().ByName("public_key") + fd_Authentication_public_key_hex = md_Authentication.Fields().ByName("public_key_hex") fd_Authentication_credential_id = md_Authentication.Fields().ByName("credential_id") fd_Authentication_metadata = md_Authentication.Fields().ByName("metadata") fd_Authentication_creation_block = md_Authentication.Fields().ByName("creation_block") @@ -1247,9 +1232,9 @@ func (x *fastReflection_Authentication) Range(f func(protoreflect.FieldDescripto return } } - if x.PublicKey != nil { - value := protoreflect.ValueOfMessage(x.PublicKey.ProtoReflect()) - if !f(fd_Authentication_public_key, value) { + if x.PublicKeyHex != "" { + value := protoreflect.ValueOfString(x.PublicKeyHex) + if !f(fd_Authentication_public_key_hex, value) { return } } @@ -1292,8 +1277,8 @@ func (x *fastReflection_Authentication) Has(fd protoreflect.FieldDescriptor) boo return x.Controller != "" case "did.v1.Authentication.subject": return x.Subject != "" - case "did.v1.Authentication.public_key": - return x.PublicKey != nil + case "did.v1.Authentication.public_key_hex": + return x.PublicKeyHex != "" case "did.v1.Authentication.credential_id": return len(x.CredentialId) != 0 case "did.v1.Authentication.metadata": @@ -1322,8 +1307,8 @@ func (x *fastReflection_Authentication) Clear(fd protoreflect.FieldDescriptor) { x.Controller = "" case "did.v1.Authentication.subject": x.Subject = "" - case "did.v1.Authentication.public_key": - x.PublicKey = nil + case "did.v1.Authentication.public_key_hex": + x.PublicKeyHex = "" case "did.v1.Authentication.credential_id": x.CredentialId = nil case "did.v1.Authentication.metadata": @@ -1355,9 +1340,9 @@ func (x *fastReflection_Authentication) Get(descriptor protoreflect.FieldDescrip case "did.v1.Authentication.subject": value := x.Subject return protoreflect.ValueOfString(value) - case "did.v1.Authentication.public_key": - value := x.PublicKey - return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "did.v1.Authentication.public_key_hex": + value := x.PublicKeyHex + return protoreflect.ValueOfString(value) case "did.v1.Authentication.credential_id": value := x.CredentialId return protoreflect.ValueOfBytes(value) @@ -1396,8 +1381,8 @@ func (x *fastReflection_Authentication) Set(fd protoreflect.FieldDescriptor, val x.Controller = value.Interface().(string) case "did.v1.Authentication.subject": x.Subject = value.Interface().(string) - case "did.v1.Authentication.public_key": - x.PublicKey = value.Message().Interface().(*PubKey) + case "did.v1.Authentication.public_key_hex": + x.PublicKeyHex = value.Interface().(string) case "did.v1.Authentication.credential_id": x.CredentialId = value.Bytes() case "did.v1.Authentication.metadata": @@ -1426,11 +1411,6 @@ func (x *fastReflection_Authentication) Set(fd protoreflect.FieldDescriptor, val // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Authentication) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Authentication.public_key": - if x.PublicKey == nil { - x.PublicKey = new(PubKey) - } - return protoreflect.ValueOfMessage(x.PublicKey.ProtoReflect()) case "did.v1.Authentication.metadata": if x.Metadata == nil { x.Metadata = make(map[string]string) @@ -1443,6 +1423,8 @@ func (x *fastReflection_Authentication) Mutable(fd protoreflect.FieldDescriptor) panic(fmt.Errorf("field controller of message did.v1.Authentication is not mutable")) case "did.v1.Authentication.subject": panic(fmt.Errorf("field subject of message did.v1.Authentication is not mutable")) + case "did.v1.Authentication.public_key_hex": + panic(fmt.Errorf("field public_key_hex of message did.v1.Authentication is not mutable")) case "did.v1.Authentication.credential_id": panic(fmt.Errorf("field credential_id of message did.v1.Authentication is not mutable")) case "did.v1.Authentication.creation_block": @@ -1466,9 +1448,8 @@ func (x *fastReflection_Authentication) NewField(fd protoreflect.FieldDescriptor return protoreflect.ValueOfString("") case "did.v1.Authentication.subject": return protoreflect.ValueOfString("") - case "did.v1.Authentication.public_key": - m := new(PubKey) - return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "did.v1.Authentication.public_key_hex": + return protoreflect.ValueOfString("") case "did.v1.Authentication.credential_id": return protoreflect.ValueOfBytes(nil) case "did.v1.Authentication.metadata": @@ -1557,8 +1538,8 @@ func (x *fastReflection_Authentication) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if x.PublicKey != nil { - l = options.Size(x.PublicKey) + l = len(x.PublicKeyHex) + if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } l = len(x.CredentialId) @@ -1673,17 +1654,10 @@ func (x *fastReflection_Authentication) ProtoMethods() *protoiface.Methods { i-- dAtA[i] = 0x2a } - if x.PublicKey != nil { - encoded, err := options.Marshal(x.PublicKey) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + if len(x.PublicKeyHex) > 0 { + i -= len(x.PublicKeyHex) + copy(dAtA[i:], x.PublicKeyHex) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicKeyHex))) i-- dAtA[i] = 0x22 } @@ -1855,9 +1829,9 @@ func (x *fastReflection_Authentication) ProtoMethods() *protoiface.Methods { iNdEx = postIndex case 4: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -1867,27 +1841,23 @@ func (x *fastReflection_Authentication) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - if x.PublicKey == nil { - x.PublicKey = &PubKey{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.PublicKey); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } + x.PublicKeyHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { @@ -2104,6 +2074,714 @@ func (x *fastReflection_Authentication) ProtoMethods() *protoiface.Methods { } } +var ( + md_Biscuit protoreflect.MessageDescriptor + fd_Biscuit_id protoreflect.FieldDescriptor + fd_Biscuit_controller protoreflect.FieldDescriptor + fd_Biscuit_subject protoreflect.FieldDescriptor + fd_Biscuit_origin protoreflect.FieldDescriptor + fd_Biscuit_expiry_height protoreflect.FieldDescriptor + fd_Biscuit_macaroon protoreflect.FieldDescriptor +) + +func init() { + file_did_v1_state_proto_init() + md_Biscuit = File_did_v1_state_proto.Messages().ByName("Biscuit") + fd_Biscuit_id = md_Biscuit.Fields().ByName("id") + fd_Biscuit_controller = md_Biscuit.Fields().ByName("controller") + fd_Biscuit_subject = md_Biscuit.Fields().ByName("subject") + fd_Biscuit_origin = md_Biscuit.Fields().ByName("origin") + fd_Biscuit_expiry_height = md_Biscuit.Fields().ByName("expiry_height") + fd_Biscuit_macaroon = md_Biscuit.Fields().ByName("macaroon") +} + +var _ protoreflect.Message = (*fastReflection_Biscuit)(nil) + +type fastReflection_Biscuit Biscuit + +func (x *Biscuit) ProtoReflect() protoreflect.Message { + return (*fastReflection_Biscuit)(x) +} + +func (x *Biscuit) slowProtoReflect() protoreflect.Message { + mi := &file_did_v1_state_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Biscuit_messageType fastReflection_Biscuit_messageType +var _ protoreflect.MessageType = fastReflection_Biscuit_messageType{} + +type fastReflection_Biscuit_messageType struct{} + +func (x fastReflection_Biscuit_messageType) Zero() protoreflect.Message { + return (*fastReflection_Biscuit)(nil) +} +func (x fastReflection_Biscuit_messageType) New() protoreflect.Message { + return new(fastReflection_Biscuit) +} +func (x fastReflection_Biscuit_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Biscuit +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Biscuit) Descriptor() protoreflect.MessageDescriptor { + return md_Biscuit +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Biscuit) Type() protoreflect.MessageType { + return _fastReflection_Biscuit_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Biscuit) New() protoreflect.Message { + return new(fastReflection_Biscuit) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Biscuit) Interface() protoreflect.ProtoMessage { + return (*Biscuit)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Biscuit) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Id != uint64(0) { + value := protoreflect.ValueOfUint64(x.Id) + if !f(fd_Biscuit_id, value) { + return + } + } + if x.Controller != "" { + value := protoreflect.ValueOfString(x.Controller) + if !f(fd_Biscuit_controller, value) { + return + } + } + if x.Subject != "" { + value := protoreflect.ValueOfString(x.Subject) + if !f(fd_Biscuit_subject, value) { + return + } + } + if x.Origin != "" { + value := protoreflect.ValueOfString(x.Origin) + if !f(fd_Biscuit_origin, value) { + return + } + } + if x.ExpiryHeight != int64(0) { + value := protoreflect.ValueOfInt64(x.ExpiryHeight) + if !f(fd_Biscuit_expiry_height, value) { + return + } + } + if x.Macaroon != "" { + value := protoreflect.ValueOfString(x.Macaroon) + if !f(fd_Biscuit_macaroon, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Biscuit) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "did.v1.Biscuit.id": + return x.Id != uint64(0) + case "did.v1.Biscuit.controller": + return x.Controller != "" + case "did.v1.Biscuit.subject": + return x.Subject != "" + case "did.v1.Biscuit.origin": + return x.Origin != "" + case "did.v1.Biscuit.expiry_height": + return x.ExpiryHeight != int64(0) + case "did.v1.Biscuit.macaroon": + return x.Macaroon != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) + } + panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Biscuit) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "did.v1.Biscuit.id": + x.Id = uint64(0) + case "did.v1.Biscuit.controller": + x.Controller = "" + case "did.v1.Biscuit.subject": + x.Subject = "" + case "did.v1.Biscuit.origin": + x.Origin = "" + case "did.v1.Biscuit.expiry_height": + x.ExpiryHeight = int64(0) + case "did.v1.Biscuit.macaroon": + x.Macaroon = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) + } + panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Biscuit) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "did.v1.Biscuit.id": + value := x.Id + return protoreflect.ValueOfUint64(value) + case "did.v1.Biscuit.controller": + value := x.Controller + return protoreflect.ValueOfString(value) + case "did.v1.Biscuit.subject": + value := x.Subject + return protoreflect.ValueOfString(value) + case "did.v1.Biscuit.origin": + value := x.Origin + return protoreflect.ValueOfString(value) + case "did.v1.Biscuit.expiry_height": + value := x.ExpiryHeight + return protoreflect.ValueOfInt64(value) + case "did.v1.Biscuit.macaroon": + value := x.Macaroon + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) + } + panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Biscuit) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "did.v1.Biscuit.id": + x.Id = value.Uint() + case "did.v1.Biscuit.controller": + x.Controller = value.Interface().(string) + case "did.v1.Biscuit.subject": + x.Subject = value.Interface().(string) + case "did.v1.Biscuit.origin": + x.Origin = value.Interface().(string) + case "did.v1.Biscuit.expiry_height": + x.ExpiryHeight = value.Int() + case "did.v1.Biscuit.macaroon": + x.Macaroon = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) + } + panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Biscuit) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "did.v1.Biscuit.id": + panic(fmt.Errorf("field id of message did.v1.Biscuit is not mutable")) + case "did.v1.Biscuit.controller": + panic(fmt.Errorf("field controller of message did.v1.Biscuit is not mutable")) + case "did.v1.Biscuit.subject": + panic(fmt.Errorf("field subject of message did.v1.Biscuit is not mutable")) + case "did.v1.Biscuit.origin": + panic(fmt.Errorf("field origin of message did.v1.Biscuit is not mutable")) + case "did.v1.Biscuit.expiry_height": + panic(fmt.Errorf("field expiry_height of message did.v1.Biscuit is not mutable")) + case "did.v1.Biscuit.macaroon": + panic(fmt.Errorf("field macaroon of message did.v1.Biscuit is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) + } + panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Biscuit) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "did.v1.Biscuit.id": + return protoreflect.ValueOfUint64(uint64(0)) + case "did.v1.Biscuit.controller": + return protoreflect.ValueOfString("") + case "did.v1.Biscuit.subject": + return protoreflect.ValueOfString("") + case "did.v1.Biscuit.origin": + return protoreflect.ValueOfString("") + case "did.v1.Biscuit.expiry_height": + return protoreflect.ValueOfInt64(int64(0)) + case "did.v1.Biscuit.macaroon": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) + } + panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Biscuit) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in did.v1.Biscuit", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Biscuit) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Biscuit) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Biscuit) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Biscuit) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Biscuit) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Id != 0 { + n += 1 + runtime.Sov(uint64(x.Id)) + } + l = len(x.Controller) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Subject) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Origin) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.ExpiryHeight != 0 { + n += 1 + runtime.Sov(uint64(x.ExpiryHeight)) + } + l = len(x.Macaroon) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Biscuit) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Macaroon) > 0 { + i -= len(x.Macaroon) + copy(dAtA[i:], x.Macaroon) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Macaroon))) + i-- + dAtA[i] = 0x32 + } + if x.ExpiryHeight != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryHeight)) + i-- + dAtA[i] = 0x28 + } + if len(x.Origin) > 0 { + i -= len(x.Origin) + copy(dAtA[i:], x.Origin) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) + i-- + dAtA[i] = 0x22 + } + if len(x.Subject) > 0 { + i -= len(x.Subject) + copy(dAtA[i:], x.Subject) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Subject))) + i-- + dAtA[i] = 0x1a + } + if len(x.Controller) > 0 { + i -= len(x.Controller) + copy(dAtA[i:], x.Controller) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) + i-- + dAtA[i] = 0x12 + } + if x.Id != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Id)) + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Biscuit) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Biscuit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Biscuit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + x.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Controller = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Subject = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Origin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) + } + x.ExpiryHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.ExpiryHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Macaroon", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Macaroon = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + var ( md_Controller protoreflect.MessageDescriptor fd_Controller_number protoreflect.FieldDescriptor @@ -2111,7 +2789,7 @@ var ( fd_Controller_sonr_address protoreflect.FieldDescriptor fd_Controller_eth_address protoreflect.FieldDescriptor fd_Controller_btc_address protoreflect.FieldDescriptor - fd_Controller_public_key protoreflect.FieldDescriptor + fd_Controller_public_key_hex protoreflect.FieldDescriptor fd_Controller_ks_val protoreflect.FieldDescriptor fd_Controller_claimed_block protoreflect.FieldDescriptor fd_Controller_creation_block protoreflect.FieldDescriptor @@ -2125,7 +2803,7 @@ func init() { fd_Controller_sonr_address = md_Controller.Fields().ByName("sonr_address") fd_Controller_eth_address = md_Controller.Fields().ByName("eth_address") fd_Controller_btc_address = md_Controller.Fields().ByName("btc_address") - fd_Controller_public_key = md_Controller.Fields().ByName("public_key") + fd_Controller_public_key_hex = md_Controller.Fields().ByName("public_key_hex") fd_Controller_ks_val = md_Controller.Fields().ByName("ks_val") fd_Controller_claimed_block = md_Controller.Fields().ByName("claimed_block") fd_Controller_creation_block = md_Controller.Fields().ByName("creation_block") @@ -2140,7 +2818,7 @@ func (x *Controller) ProtoReflect() protoreflect.Message { } func (x *Controller) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_state_proto_msgTypes[2] + mi := &file_did_v1_state_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2226,9 +2904,9 @@ func (x *fastReflection_Controller) Range(f func(protoreflect.FieldDescriptor, p return } } - if x.PublicKey != nil { - value := protoreflect.ValueOfMessage(x.PublicKey.ProtoReflect()) - if !f(fd_Controller_public_key, value) { + if x.PublicKeyHex != "" { + value := protoreflect.ValueOfString(x.PublicKeyHex) + if !f(fd_Controller_public_key_hex, value) { return } } @@ -2275,8 +2953,8 @@ func (x *fastReflection_Controller) Has(fd protoreflect.FieldDescriptor) bool { return x.EthAddress != "" case "did.v1.Controller.btc_address": return x.BtcAddress != "" - case "did.v1.Controller.public_key": - return x.PublicKey != nil + case "did.v1.Controller.public_key_hex": + return x.PublicKeyHex != "" case "did.v1.Controller.ks_val": return x.KsVal != "" case "did.v1.Controller.claimed_block": @@ -2309,8 +2987,8 @@ func (x *fastReflection_Controller) Clear(fd protoreflect.FieldDescriptor) { x.EthAddress = "" case "did.v1.Controller.btc_address": x.BtcAddress = "" - case "did.v1.Controller.public_key": - x.PublicKey = nil + case "did.v1.Controller.public_key_hex": + x.PublicKeyHex = "" case "did.v1.Controller.ks_val": x.KsVal = "" case "did.v1.Controller.claimed_block": @@ -2348,9 +3026,9 @@ func (x *fastReflection_Controller) Get(descriptor protoreflect.FieldDescriptor) case "did.v1.Controller.btc_address": value := x.BtcAddress return protoreflect.ValueOfString(value) - case "did.v1.Controller.public_key": - value := x.PublicKey - return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "did.v1.Controller.public_key_hex": + value := x.PublicKeyHex + return protoreflect.ValueOfString(value) case "did.v1.Controller.ks_val": value := x.KsVal return protoreflect.ValueOfString(value) @@ -2390,8 +3068,8 @@ func (x *fastReflection_Controller) Set(fd protoreflect.FieldDescriptor, value p x.EthAddress = value.Interface().(string) case "did.v1.Controller.btc_address": x.BtcAddress = value.Interface().(string) - case "did.v1.Controller.public_key": - x.PublicKey = value.Message().Interface().(*PubKey) + case "did.v1.Controller.public_key_hex": + x.PublicKeyHex = value.Interface().(string) case "did.v1.Controller.ks_val": x.KsVal = value.Interface().(string) case "did.v1.Controller.claimed_block": @@ -2418,11 +3096,6 @@ func (x *fastReflection_Controller) Set(fd protoreflect.FieldDescriptor, value p // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Controller) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Controller.public_key": - if x.PublicKey == nil { - x.PublicKey = new(PubKey) - } - return protoreflect.ValueOfMessage(x.PublicKey.ProtoReflect()) case "did.v1.Controller.number": panic(fmt.Errorf("field number of message did.v1.Controller is not mutable")) case "did.v1.Controller.did": @@ -2433,6 +3106,8 @@ func (x *fastReflection_Controller) Mutable(fd protoreflect.FieldDescriptor) pro panic(fmt.Errorf("field eth_address of message did.v1.Controller is not mutable")) case "did.v1.Controller.btc_address": panic(fmt.Errorf("field btc_address of message did.v1.Controller is not mutable")) + case "did.v1.Controller.public_key_hex": + panic(fmt.Errorf("field public_key_hex of message did.v1.Controller is not mutable")) case "did.v1.Controller.ks_val": panic(fmt.Errorf("field ks_val of message did.v1.Controller is not mutable")) case "did.v1.Controller.claimed_block": @@ -2462,9 +3137,8 @@ func (x *fastReflection_Controller) NewField(fd protoreflect.FieldDescriptor) pr return protoreflect.ValueOfString("") case "did.v1.Controller.btc_address": return protoreflect.ValueOfString("") - case "did.v1.Controller.public_key": - m := new(PubKey) - return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "did.v1.Controller.public_key_hex": + return protoreflect.ValueOfString("") case "did.v1.Controller.ks_val": return protoreflect.ValueOfString("") case "did.v1.Controller.claimed_block": @@ -2559,8 +3233,8 @@ func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if x.PublicKey != nil { - l = options.Size(x.PublicKey) + l = len(x.PublicKeyHex) + if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } l = len(x.KsVal) @@ -2619,17 +3293,10 @@ func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { i-- dAtA[i] = 0x3a } - if x.PublicKey != nil { - encoded, err := options.Marshal(x.PublicKey) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + if len(x.PublicKeyHex) > 0 { + i -= len(x.PublicKeyHex) + copy(dAtA[i:], x.PublicKeyHex) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicKeyHex))) i-- dAtA[i] = 0x32 } @@ -2864,9 +3531,9 @@ func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { iNdEx = postIndex case 6: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -2876,27 +3543,23 @@ func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - if x.PublicKey == nil { - x.PublicKey = &PubKey{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.PublicKey); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } + x.PublicKeyHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 2 { @@ -3003,1358 +3666,6 @@ func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { } } -var ( - md_Grant protoreflect.MessageDescriptor - fd_Grant_id protoreflect.FieldDescriptor - fd_Grant_controller protoreflect.FieldDescriptor - fd_Grant_subject protoreflect.FieldDescriptor - fd_Grant_origin protoreflect.FieldDescriptor - fd_Grant_expiry_height protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_state_proto_init() - md_Grant = File_did_v1_state_proto.Messages().ByName("Grant") - fd_Grant_id = md_Grant.Fields().ByName("id") - fd_Grant_controller = md_Grant.Fields().ByName("controller") - fd_Grant_subject = md_Grant.Fields().ByName("subject") - fd_Grant_origin = md_Grant.Fields().ByName("origin") - fd_Grant_expiry_height = md_Grant.Fields().ByName("expiry_height") -} - -var _ protoreflect.Message = (*fastReflection_Grant)(nil) - -type fastReflection_Grant Grant - -func (x *Grant) ProtoReflect() protoreflect.Message { - return (*fastReflection_Grant)(x) -} - -func (x *Grant) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_state_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Grant_messageType fastReflection_Grant_messageType -var _ protoreflect.MessageType = fastReflection_Grant_messageType{} - -type fastReflection_Grant_messageType struct{} - -func (x fastReflection_Grant_messageType) Zero() protoreflect.Message { - return (*fastReflection_Grant)(nil) -} -func (x fastReflection_Grant_messageType) New() protoreflect.Message { - return new(fastReflection_Grant) -} -func (x fastReflection_Grant_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Grant -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Grant) Descriptor() protoreflect.MessageDescriptor { - return md_Grant -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Grant) Type() protoreflect.MessageType { - return _fastReflection_Grant_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Grant) New() protoreflect.Message { - return new(fastReflection_Grant) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Grant) Interface() protoreflect.ProtoMessage { - return (*Grant)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Grant) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != uint64(0) { - value := protoreflect.ValueOfUint64(x.Id) - if !f(fd_Grant_id, value) { - return - } - } - if x.Controller != "" { - value := protoreflect.ValueOfString(x.Controller) - if !f(fd_Grant_controller, value) { - return - } - } - if x.Subject != "" { - value := protoreflect.ValueOfString(x.Subject) - if !f(fd_Grant_subject, value) { - return - } - } - if x.Origin != "" { - value := protoreflect.ValueOfString(x.Origin) - if !f(fd_Grant_origin, value) { - return - } - } - if x.ExpiryHeight != int64(0) { - value := protoreflect.ValueOfInt64(x.ExpiryHeight) - if !f(fd_Grant_expiry_height, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Grant) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.Grant.id": - return x.Id != uint64(0) - case "did.v1.Grant.controller": - return x.Controller != "" - case "did.v1.Grant.subject": - return x.Subject != "" - case "did.v1.Grant.origin": - return x.Origin != "" - case "did.v1.Grant.expiry_height": - return x.ExpiryHeight != int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Grant")) - } - panic(fmt.Errorf("message did.v1.Grant does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Grant) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.Grant.id": - x.Id = uint64(0) - case "did.v1.Grant.controller": - x.Controller = "" - case "did.v1.Grant.subject": - x.Subject = "" - case "did.v1.Grant.origin": - x.Origin = "" - case "did.v1.Grant.expiry_height": - x.ExpiryHeight = int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Grant")) - } - panic(fmt.Errorf("message did.v1.Grant does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Grant) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.Grant.id": - value := x.Id - return protoreflect.ValueOfUint64(value) - case "did.v1.Grant.controller": - value := x.Controller - return protoreflect.ValueOfString(value) - case "did.v1.Grant.subject": - value := x.Subject - return protoreflect.ValueOfString(value) - case "did.v1.Grant.origin": - value := x.Origin - return protoreflect.ValueOfString(value) - case "did.v1.Grant.expiry_height": - value := x.ExpiryHeight - return protoreflect.ValueOfInt64(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Grant")) - } - panic(fmt.Errorf("message did.v1.Grant does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Grant) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.Grant.id": - x.Id = value.Uint() - case "did.v1.Grant.controller": - x.Controller = value.Interface().(string) - case "did.v1.Grant.subject": - x.Subject = value.Interface().(string) - case "did.v1.Grant.origin": - x.Origin = value.Interface().(string) - case "did.v1.Grant.expiry_height": - x.ExpiryHeight = value.Int() - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Grant")) - } - panic(fmt.Errorf("message did.v1.Grant does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Grant) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Grant.id": - panic(fmt.Errorf("field id of message did.v1.Grant is not mutable")) - case "did.v1.Grant.controller": - panic(fmt.Errorf("field controller of message did.v1.Grant is not mutable")) - case "did.v1.Grant.subject": - panic(fmt.Errorf("field subject of message did.v1.Grant is not mutable")) - case "did.v1.Grant.origin": - panic(fmt.Errorf("field origin of message did.v1.Grant is not mutable")) - case "did.v1.Grant.expiry_height": - panic(fmt.Errorf("field expiry_height of message did.v1.Grant is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Grant")) - } - panic(fmt.Errorf("message did.v1.Grant does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Grant) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Grant.id": - return protoreflect.ValueOfUint64(uint64(0)) - case "did.v1.Grant.controller": - return protoreflect.ValueOfString("") - case "did.v1.Grant.subject": - return protoreflect.ValueOfString("") - case "did.v1.Grant.origin": - return protoreflect.ValueOfString("") - case "did.v1.Grant.expiry_height": - return protoreflect.ValueOfInt64(int64(0)) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Grant")) - } - panic(fmt.Errorf("message did.v1.Grant does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Grant) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Grant", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Grant) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Grant) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Grant) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Grant) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Grant) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Id != 0 { - n += 1 + runtime.Sov(uint64(x.Id)) - } - l = len(x.Controller) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Subject) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Origin) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.ExpiryHeight != 0 { - n += 1 + runtime.Sov(uint64(x.ExpiryHeight)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Grant) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.ExpiryHeight != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryHeight)) - i-- - dAtA[i] = 0x28 - } - if len(x.Origin) > 0 { - i -= len(x.Origin) - copy(dAtA[i:], x.Origin) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) - i-- - dAtA[i] = 0x22 - } - if len(x.Subject) > 0 { - i -= len(x.Subject) - copy(dAtA[i:], x.Subject) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Subject))) - i-- - dAtA[i] = 0x1a - } - if len(x.Controller) > 0 { - i -= len(x.Controller) - copy(dAtA[i:], x.Controller) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) - i-- - dAtA[i] = 0x12 - } - if x.Id != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Id)) - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Grant) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Grant: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Grant: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - x.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) - } - x.ExpiryHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.ExpiryHeight |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_Macaroon protoreflect.MessageDescriptor - fd_Macaroon_id protoreflect.FieldDescriptor - fd_Macaroon_controller protoreflect.FieldDescriptor - fd_Macaroon_subject protoreflect.FieldDescriptor - fd_Macaroon_origin protoreflect.FieldDescriptor - fd_Macaroon_expiry_height protoreflect.FieldDescriptor - fd_Macaroon_macaroon protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_state_proto_init() - md_Macaroon = File_did_v1_state_proto.Messages().ByName("Macaroon") - fd_Macaroon_id = md_Macaroon.Fields().ByName("id") - fd_Macaroon_controller = md_Macaroon.Fields().ByName("controller") - fd_Macaroon_subject = md_Macaroon.Fields().ByName("subject") - fd_Macaroon_origin = md_Macaroon.Fields().ByName("origin") - fd_Macaroon_expiry_height = md_Macaroon.Fields().ByName("expiry_height") - fd_Macaroon_macaroon = md_Macaroon.Fields().ByName("macaroon") -} - -var _ protoreflect.Message = (*fastReflection_Macaroon)(nil) - -type fastReflection_Macaroon Macaroon - -func (x *Macaroon) ProtoReflect() protoreflect.Message { - return (*fastReflection_Macaroon)(x) -} - -func (x *Macaroon) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_state_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Macaroon_messageType fastReflection_Macaroon_messageType -var _ protoreflect.MessageType = fastReflection_Macaroon_messageType{} - -type fastReflection_Macaroon_messageType struct{} - -func (x fastReflection_Macaroon_messageType) Zero() protoreflect.Message { - return (*fastReflection_Macaroon)(nil) -} -func (x fastReflection_Macaroon_messageType) New() protoreflect.Message { - return new(fastReflection_Macaroon) -} -func (x fastReflection_Macaroon_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Macaroon -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Macaroon) Descriptor() protoreflect.MessageDescriptor { - return md_Macaroon -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Macaroon) Type() protoreflect.MessageType { - return _fastReflection_Macaroon_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Macaroon) New() protoreflect.Message { - return new(fastReflection_Macaroon) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Macaroon) Interface() protoreflect.ProtoMessage { - return (*Macaroon)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Macaroon) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != uint64(0) { - value := protoreflect.ValueOfUint64(x.Id) - if !f(fd_Macaroon_id, value) { - return - } - } - if x.Controller != "" { - value := protoreflect.ValueOfString(x.Controller) - if !f(fd_Macaroon_controller, value) { - return - } - } - if x.Subject != "" { - value := protoreflect.ValueOfString(x.Subject) - if !f(fd_Macaroon_subject, value) { - return - } - } - if x.Origin != "" { - value := protoreflect.ValueOfString(x.Origin) - if !f(fd_Macaroon_origin, value) { - return - } - } - if x.ExpiryHeight != int64(0) { - value := protoreflect.ValueOfInt64(x.ExpiryHeight) - if !f(fd_Macaroon_expiry_height, value) { - return - } - } - if x.Macaroon != "" { - value := protoreflect.ValueOfString(x.Macaroon) - if !f(fd_Macaroon_macaroon, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Macaroon) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.Macaroon.id": - return x.Id != uint64(0) - case "did.v1.Macaroon.controller": - return x.Controller != "" - case "did.v1.Macaroon.subject": - return x.Subject != "" - case "did.v1.Macaroon.origin": - return x.Origin != "" - case "did.v1.Macaroon.expiry_height": - return x.ExpiryHeight != int64(0) - case "did.v1.Macaroon.macaroon": - return x.Macaroon != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Macaroon")) - } - panic(fmt.Errorf("message did.v1.Macaroon does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Macaroon) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.Macaroon.id": - x.Id = uint64(0) - case "did.v1.Macaroon.controller": - x.Controller = "" - case "did.v1.Macaroon.subject": - x.Subject = "" - case "did.v1.Macaroon.origin": - x.Origin = "" - case "did.v1.Macaroon.expiry_height": - x.ExpiryHeight = int64(0) - case "did.v1.Macaroon.macaroon": - x.Macaroon = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Macaroon")) - } - panic(fmt.Errorf("message did.v1.Macaroon does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Macaroon) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.Macaroon.id": - value := x.Id - return protoreflect.ValueOfUint64(value) - case "did.v1.Macaroon.controller": - value := x.Controller - return protoreflect.ValueOfString(value) - case "did.v1.Macaroon.subject": - value := x.Subject - return protoreflect.ValueOfString(value) - case "did.v1.Macaroon.origin": - value := x.Origin - return protoreflect.ValueOfString(value) - case "did.v1.Macaroon.expiry_height": - value := x.ExpiryHeight - return protoreflect.ValueOfInt64(value) - case "did.v1.Macaroon.macaroon": - value := x.Macaroon - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Macaroon")) - } - panic(fmt.Errorf("message did.v1.Macaroon does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Macaroon) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.Macaroon.id": - x.Id = value.Uint() - case "did.v1.Macaroon.controller": - x.Controller = value.Interface().(string) - case "did.v1.Macaroon.subject": - x.Subject = value.Interface().(string) - case "did.v1.Macaroon.origin": - x.Origin = value.Interface().(string) - case "did.v1.Macaroon.expiry_height": - x.ExpiryHeight = value.Int() - case "did.v1.Macaroon.macaroon": - x.Macaroon = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Macaroon")) - } - panic(fmt.Errorf("message did.v1.Macaroon does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Macaroon) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Macaroon.id": - panic(fmt.Errorf("field id of message did.v1.Macaroon is not mutable")) - case "did.v1.Macaroon.controller": - panic(fmt.Errorf("field controller of message did.v1.Macaroon is not mutable")) - case "did.v1.Macaroon.subject": - panic(fmt.Errorf("field subject of message did.v1.Macaroon is not mutable")) - case "did.v1.Macaroon.origin": - panic(fmt.Errorf("field origin of message did.v1.Macaroon is not mutable")) - case "did.v1.Macaroon.expiry_height": - panic(fmt.Errorf("field expiry_height of message did.v1.Macaroon is not mutable")) - case "did.v1.Macaroon.macaroon": - panic(fmt.Errorf("field macaroon of message did.v1.Macaroon is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Macaroon")) - } - panic(fmt.Errorf("message did.v1.Macaroon does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Macaroon) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Macaroon.id": - return protoreflect.ValueOfUint64(uint64(0)) - case "did.v1.Macaroon.controller": - return protoreflect.ValueOfString("") - case "did.v1.Macaroon.subject": - return protoreflect.ValueOfString("") - case "did.v1.Macaroon.origin": - return protoreflect.ValueOfString("") - case "did.v1.Macaroon.expiry_height": - return protoreflect.ValueOfInt64(int64(0)) - case "did.v1.Macaroon.macaroon": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Macaroon")) - } - panic(fmt.Errorf("message did.v1.Macaroon does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Macaroon) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Macaroon", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Macaroon) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Macaroon) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Macaroon) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Macaroon) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Macaroon) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Id != 0 { - n += 1 + runtime.Sov(uint64(x.Id)) - } - l = len(x.Controller) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Subject) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Origin) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.ExpiryHeight != 0 { - n += 1 + runtime.Sov(uint64(x.ExpiryHeight)) - } - l = len(x.Macaroon) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Macaroon) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Macaroon) > 0 { - i -= len(x.Macaroon) - copy(dAtA[i:], x.Macaroon) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Macaroon))) - i-- - dAtA[i] = 0x32 - } - if x.ExpiryHeight != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryHeight)) - i-- - dAtA[i] = 0x28 - } - if len(x.Origin) > 0 { - i -= len(x.Origin) - copy(dAtA[i:], x.Origin) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) - i-- - dAtA[i] = 0x22 - } - if len(x.Subject) > 0 { - i -= len(x.Subject) - copy(dAtA[i:], x.Subject) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Subject))) - i-- - dAtA[i] = 0x1a - } - if len(x.Controller) > 0 { - i -= len(x.Controller) - copy(dAtA[i:], x.Controller) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) - i-- - dAtA[i] = 0x12 - } - if x.Id != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Id)) - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Macaroon) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Macaroon: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Macaroon: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - x.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) - } - x.ExpiryHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.ExpiryHeight |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Macaroon", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Macaroon = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - var _ protoreflect.Map = (*_Verification_8_map)(nil) type _Verification_8_map struct { @@ -4444,7 +3755,7 @@ var ( fd_Verification_did_method protoreflect.FieldDescriptor fd_Verification_issuer protoreflect.FieldDescriptor fd_Verification_subject protoreflect.FieldDescriptor - fd_Verification_public_key protoreflect.FieldDescriptor + fd_Verification_public_key_hex protoreflect.FieldDescriptor fd_Verification_verification_type protoreflect.FieldDescriptor fd_Verification_metadata protoreflect.FieldDescriptor fd_Verification_creation_block protoreflect.FieldDescriptor @@ -4458,7 +3769,7 @@ func init() { fd_Verification_did_method = md_Verification.Fields().ByName("did_method") fd_Verification_issuer = md_Verification.Fields().ByName("issuer") fd_Verification_subject = md_Verification.Fields().ByName("subject") - fd_Verification_public_key = md_Verification.Fields().ByName("public_key") + fd_Verification_public_key_hex = md_Verification.Fields().ByName("public_key_hex") fd_Verification_verification_type = md_Verification.Fields().ByName("verification_type") fd_Verification_metadata = md_Verification.Fields().ByName("metadata") fd_Verification_creation_block = md_Verification.Fields().ByName("creation_block") @@ -4473,7 +3784,7 @@ func (x *Verification) ProtoReflect() protoreflect.Message { } func (x *Verification) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_state_proto_msgTypes[5] + mi := &file_did_v1_state_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4559,9 +3870,9 @@ func (x *fastReflection_Verification) Range(f func(protoreflect.FieldDescriptor, return } } - if x.PublicKey != nil { - value := protoreflect.ValueOfMessage(x.PublicKey.ProtoReflect()) - if !f(fd_Verification_public_key, value) { + if x.PublicKeyHex != "" { + value := protoreflect.ValueOfString(x.PublicKeyHex) + if !f(fd_Verification_public_key_hex, value) { return } } @@ -4608,8 +3919,8 @@ func (x *fastReflection_Verification) Has(fd protoreflect.FieldDescriptor) bool return x.Issuer != "" case "did.v1.Verification.subject": return x.Subject != "" - case "did.v1.Verification.public_key": - return x.PublicKey != nil + case "did.v1.Verification.public_key_hex": + return x.PublicKeyHex != "" case "did.v1.Verification.verification_type": return x.VerificationType != "" case "did.v1.Verification.metadata": @@ -4642,8 +3953,8 @@ func (x *fastReflection_Verification) Clear(fd protoreflect.FieldDescriptor) { x.Issuer = "" case "did.v1.Verification.subject": x.Subject = "" - case "did.v1.Verification.public_key": - x.PublicKey = nil + case "did.v1.Verification.public_key_hex": + x.PublicKeyHex = "" case "did.v1.Verification.verification_type": x.VerificationType = "" case "did.v1.Verification.metadata": @@ -4681,9 +3992,9 @@ func (x *fastReflection_Verification) Get(descriptor protoreflect.FieldDescripto case "did.v1.Verification.subject": value := x.Subject return protoreflect.ValueOfString(value) - case "did.v1.Verification.public_key": - value := x.PublicKey - return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "did.v1.Verification.public_key_hex": + value := x.PublicKeyHex + return protoreflect.ValueOfString(value) case "did.v1.Verification.verification_type": value := x.VerificationType return protoreflect.ValueOfString(value) @@ -4726,8 +4037,8 @@ func (x *fastReflection_Verification) Set(fd protoreflect.FieldDescriptor, value x.Issuer = value.Interface().(string) case "did.v1.Verification.subject": x.Subject = value.Interface().(string) - case "did.v1.Verification.public_key": - x.PublicKey = value.Message().Interface().(*PubKey) + case "did.v1.Verification.public_key_hex": + x.PublicKeyHex = value.Interface().(string) case "did.v1.Verification.verification_type": x.VerificationType = value.Interface().(string) case "did.v1.Verification.metadata": @@ -4756,11 +4067,6 @@ func (x *fastReflection_Verification) Set(fd protoreflect.FieldDescriptor, value // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Verification) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Verification.public_key": - if x.PublicKey == nil { - x.PublicKey = new(PubKey) - } - return protoreflect.ValueOfMessage(x.PublicKey.ProtoReflect()) case "did.v1.Verification.metadata": if x.Metadata == nil { x.Metadata = make(map[string]string) @@ -4777,6 +4083,8 @@ func (x *fastReflection_Verification) Mutable(fd protoreflect.FieldDescriptor) p panic(fmt.Errorf("field issuer of message did.v1.Verification is not mutable")) case "did.v1.Verification.subject": panic(fmt.Errorf("field subject of message did.v1.Verification is not mutable")) + case "did.v1.Verification.public_key_hex": + panic(fmt.Errorf("field public_key_hex of message did.v1.Verification is not mutable")) case "did.v1.Verification.verification_type": panic(fmt.Errorf("field verification_type of message did.v1.Verification is not mutable")) case "did.v1.Verification.creation_block": @@ -4804,9 +4112,8 @@ func (x *fastReflection_Verification) NewField(fd protoreflect.FieldDescriptor) return protoreflect.ValueOfString("") case "did.v1.Verification.subject": return protoreflect.ValueOfString("") - case "did.v1.Verification.public_key": - m := new(PubKey) - return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "did.v1.Verification.public_key_hex": + return protoreflect.ValueOfString("") case "did.v1.Verification.verification_type": return protoreflect.ValueOfString("") case "did.v1.Verification.metadata": @@ -4903,8 +4210,8 @@ func (x *fastReflection_Verification) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if x.PublicKey != nil { - l = options.Size(x.PublicKey) + l = len(x.PublicKeyHex) + if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } l = len(x.VerificationType) @@ -5019,17 +4326,10 @@ func (x *fastReflection_Verification) ProtoMethods() *protoiface.Methods { i-- dAtA[i] = 0x3a } - if x.PublicKey != nil { - encoded, err := options.Marshal(x.PublicKey) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + if len(x.PublicKeyHex) > 0 { + i -= len(x.PublicKeyHex) + copy(dAtA[i:], x.PublicKeyHex) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicKeyHex))) i-- dAtA[i] = 0x32 } @@ -5279,9 +4579,9 @@ func (x *fastReflection_Verification) ProtoMethods() *protoiface.Methods { iNdEx = postIndex case 6: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -5291,27 +4591,23 @@ func (x *fastReflection_Verification) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - if x.PublicKey == nil { - x.PublicKey = &PubKey{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.PublicKey); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } + x.PublicKeyHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 2 { @@ -5550,8 +4846,8 @@ type Assertion struct { Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` // Origin of the authentication Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - // PubKey is the verification method - PublicKey *PubKey `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // string is the verification method + PublicKeyHex string `protobuf:"bytes,4,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` // AssertionType is the assertion type AssertionType string `protobuf:"bytes,5,opt,name=assertion_type,json=assertionType,proto3" json:"assertion_type,omitempty"` // Metadata of the authentication @@ -5601,11 +4897,11 @@ func (x *Assertion) GetSubject() string { return "" } -func (x *Assertion) GetPublicKey() *PubKey { +func (x *Assertion) GetPublicKeyHex() string { if x != nil { - return x.PublicKey + return x.PublicKeyHex } - return nil + return "" } func (x *Assertion) GetAssertionType() string { @@ -5640,8 +4936,8 @@ type Authentication struct { Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` // Origin of the authentication Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - // PubKey is the verification method - PublicKey *PubKey `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // string is the verification method + PublicKeyHex string `protobuf:"bytes,4,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` // CredentialID is the byte representation of the credential ID CredentialId []byte `protobuf:"bytes,5,opt,name=credential_id,json=credentialId,proto3" json:"credential_id,omitempty"` // Metadata of the authentication @@ -5691,11 +4987,11 @@ func (x *Authentication) GetSubject() string { return "" } -func (x *Authentication) GetPublicKey() *PubKey { +func (x *Authentication) GetPublicKeyHex() string { if x != nil { - return x.PublicKey + return x.PublicKeyHex } - return nil + return "" } func (x *Authentication) GetCredentialId() []byte { @@ -5719,6 +5015,82 @@ func (x *Authentication) GetCreationBlock() int64 { return 0 } +// Macaroon is a Macaroon message type. +type Biscuit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` + Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` + Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` + ExpiryHeight int64 `protobuf:"varint,5,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` + Macaroon string `protobuf:"bytes,6,opt,name=macaroon,proto3" json:"macaroon,omitempty"` +} + +func (x *Biscuit) Reset() { + *x = Biscuit{} + if protoimpl.UnsafeEnabled { + mi := &file_did_v1_state_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Biscuit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Biscuit) ProtoMessage() {} + +// Deprecated: Use Biscuit.ProtoReflect.Descriptor instead. +func (*Biscuit) Descriptor() ([]byte, []int) { + return file_did_v1_state_proto_rawDescGZIP(), []int{2} +} + +func (x *Biscuit) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Biscuit) GetController() string { + if x != nil { + return x.Controller + } + return "" +} + +func (x *Biscuit) GetSubject() string { + if x != nil { + return x.Subject + } + return "" +} + +func (x *Biscuit) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *Biscuit) GetExpiryHeight() int64 { + if x != nil { + return x.ExpiryHeight + } + return 0 +} + +func (x *Biscuit) GetMacaroon() string { + if x != nil { + return x.Macaroon + } + return "" +} + // Controller represents a Sonr DWN Vault type Controller struct { state protoimpl.MessageState @@ -5735,8 +5107,8 @@ type Controller struct { EthAddress string `protobuf:"bytes,4,opt,name=eth_address,json=ethAddress,proto3" json:"eth_address,omitempty"` // The DID of the controller BtcAddress string `protobuf:"bytes,5,opt,name=btc_address,json=btcAddress,proto3" json:"btc_address,omitempty"` - // PubKey is the verification method - PublicKey *PubKey `protobuf:"bytes,6,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // string is the verification method + PublicKeyHex string `protobuf:"bytes,6,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` // Pointer to the Keyshares KsVal string `protobuf:"bytes,7,opt,name=ks_val,json=ksVal,proto3" json:"ks_val,omitempty"` // The block number of when a user claimed the controller @@ -5748,7 +5120,7 @@ type Controller struct { func (x *Controller) Reset() { *x = Controller{} if protoimpl.UnsafeEnabled { - mi := &file_did_v1_state_proto_msgTypes[2] + mi := &file_did_v1_state_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5762,7 +5134,7 @@ func (*Controller) ProtoMessage() {} // Deprecated: Use Controller.ProtoReflect.Descriptor instead. func (*Controller) Descriptor() ([]byte, []int) { - return file_did_v1_state_proto_rawDescGZIP(), []int{2} + return file_did_v1_state_proto_rawDescGZIP(), []int{3} } func (x *Controller) GetNumber() uint64 { @@ -5800,11 +5172,11 @@ func (x *Controller) GetBtcAddress() string { return "" } -func (x *Controller) GetPublicKey() *PubKey { +func (x *Controller) GetPublicKeyHex() string { if x != nil { - return x.PublicKey + return x.PublicKeyHex } - return nil + return "" } func (x *Controller) GetKsVal() string { @@ -5828,150 +5200,6 @@ func (x *Controller) GetCreationBlock() int64 { return 0 } -// Grant is a Grant message type. -type Grant struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` - ExpiryHeight int64 `protobuf:"varint,5,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` -} - -func (x *Grant) Reset() { - *x = Grant{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_state_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Grant) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Grant) ProtoMessage() {} - -// Deprecated: Use Grant.ProtoReflect.Descriptor instead. -func (*Grant) Descriptor() ([]byte, []int) { - return file_did_v1_state_proto_rawDescGZIP(), []int{3} -} - -func (x *Grant) GetId() uint64 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *Grant) GetController() string { - if x != nil { - return x.Controller - } - return "" -} - -func (x *Grant) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *Grant) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *Grant) GetExpiryHeight() int64 { - if x != nil { - return x.ExpiryHeight - } - return 0 -} - -// Macaroon is a Macaroon message type. -type Macaroon struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` - ExpiryHeight int64 `protobuf:"varint,5,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` - Macaroon string `protobuf:"bytes,6,opt,name=macaroon,proto3" json:"macaroon,omitempty"` -} - -func (x *Macaroon) Reset() { - *x = Macaroon{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_state_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Macaroon) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Macaroon) ProtoMessage() {} - -// Deprecated: Use Macaroon.ProtoReflect.Descriptor instead. -func (*Macaroon) Descriptor() ([]byte, []int) { - return file_did_v1_state_proto_rawDescGZIP(), []int{4} -} - -func (x *Macaroon) GetId() uint64 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *Macaroon) GetController() string { - if x != nil { - return x.Controller - } - return "" -} - -func (x *Macaroon) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *Macaroon) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *Macaroon) GetExpiryHeight() int64 { - if x != nil { - return x.ExpiryHeight - } - return 0 -} - -func (x *Macaroon) GetMacaroon() string { - if x != nil { - return x.Macaroon - } - return "" -} - // Verification represents a verification method type Verification struct { state protoimpl.MessageState @@ -5989,7 +5217,7 @@ type Verification struct { // The subject of the verification Subject string `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"` // The public key of the verification - PublicKey *PubKey `protobuf:"bytes,6,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + PublicKeyHex string `protobuf:"bytes,6,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` // The verification method type VerificationType string `protobuf:"bytes,7,opt,name=verification_type,json=verificationType,proto3" json:"verification_type,omitempty"` // Metadata of the verification @@ -6001,7 +5229,7 @@ type Verification struct { func (x *Verification) Reset() { *x = Verification{} if protoimpl.UnsafeEnabled { - mi := &file_did_v1_state_proto_msgTypes[5] + mi := &file_did_v1_state_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6015,7 +5243,7 @@ func (*Verification) ProtoMessage() {} // Deprecated: Use Verification.ProtoReflect.Descriptor instead. func (*Verification) Descriptor() ([]byte, []int) { - return file_did_v1_state_proto_rawDescGZIP(), []int{5} + return file_did_v1_state_proto_rawDescGZIP(), []int{4} } func (x *Verification) GetDid() string { @@ -6053,11 +5281,11 @@ func (x *Verification) GetSubject() string { return "" } -func (x *Verification) GetPublicKey() *PubKey { +func (x *Verification) GetPublicKeyHex() string { if x != nil { - return x.PublicKey + return x.PublicKeyHex } - return nil + return "" } func (x *Verification) GetVerificationType() string { @@ -6088,146 +5316,132 @@ var file_did_v1_state_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, - 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x85, 0x03, 0x0a, 0x09, + 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfc, 0x02, 0x0a, 0x09, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, 0x64, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x73, - 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x61, - 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, - 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x75, - 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x29, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x23, - 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x01, 0x18, - 0x01, 0x18, 0x01, 0x22, 0x81, 0x03, 0x0a, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x2d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, - 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, - 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, 0x12, 0x25, 0x0a, 0x0e, 0x61, + 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, + 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, + 0x2e, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x63, 0x75, 0x6d, + 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x63, 0x63, + 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, - 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x29, 0xf2, 0x9e, - 0xd3, 0x8e, 0x03, 0x23, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x12, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x10, 0x01, 0x18, 0x01, 0x18, 0x02, 0x22, 0x88, 0x03, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x10, - 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, - 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x6e, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x6e, 0x72, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x74, 0x68, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x74, 0x68, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x74, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x74, 0x63, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, 0x64, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x73, 0x56, 0x61, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x63, - 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x3a, 0x59, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x53, 0x0a, - 0x0a, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0c, 0x73, - 0x6f, 0x6e, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x01, 0x18, 0x01, 0x12, - 0x11, 0x0a, 0x0b, 0x65, 0x74, 0x68, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x02, - 0x18, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x62, 0x74, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x10, 0x03, 0x18, 0x01, 0x12, 0x09, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x10, 0x04, 0x18, 0x01, - 0x18, 0x03, 0x22, 0xb6, 0x01, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x23, - 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x48, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x3a, 0x26, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x20, 0x0a, 0x06, 0x0a, 0x02, 0x69, - 0x64, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x6f, - 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x04, 0x22, 0xd5, 0x01, 0x0a, 0x08, - 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, - 0x70, 0x69, 0x72, 0x79, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x3a, 0x26, 0xf2, 0x9e, 0xd3, - 0x8e, 0x03, 0x20, 0x0a, 0x06, 0x0a, 0x02, 0x69, 0x64, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x0e, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, - 0x01, 0x18, 0x05, 0x22, 0x84, 0x04, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x69, 0x64, 0x5f, 0x6d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x64, 0x4d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, - 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x10, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x71, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x6b, 0x0a, - 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x0e, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, - 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x01, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x1c, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x64, 0x69, 0x64, 0x5f, 0x6d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x2c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x10, 0x02, 0x18, 0x01, - 0x12, 0x26, 0x0a, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x69, 0x73, - 0x73, 0x75, 0x65, 0x72, 0x10, 0x03, 0x18, 0x01, 0x18, 0x06, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, - 0x6d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, 0x31, 0xa2, - 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, 0xca, 0x02, - 0x06, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, - 0x69, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x3e, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, + 0x29, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x23, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x18, + 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x10, 0x01, 0x18, 0x01, 0x18, 0x01, 0x22, 0xf8, 0x02, 0x0a, 0x0e, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, + 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, 0x12, + 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x3b, 0x0a, + 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x29, 0xf2, 0x9e, 0xd3, 0x8e, + 0x03, 0x23, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x12, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, + 0x01, 0x18, 0x01, 0x18, 0x02, 0x22, 0xd4, 0x01, 0x0a, 0x07, 0x42, 0x69, 0x73, 0x63, 0x75, 0x69, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x3a, 0x26, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x20, 0x0a, 0x06, 0x0a, 0x02, + 0x69, 0x64, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, + 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x05, 0x22, 0xff, 0x02, 0x0a, + 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x6e, 0x72, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x6e, + 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x74, 0x68, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, + 0x74, 0x68, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x74, 0x63, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x62, 0x74, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, + 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6b, 0x73, 0x56, 0x61, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x61, 0x69, 0x6d, + 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x25, 0x0a, 0x0e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x3a, 0x59, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x53, 0x0a, 0x0a, 0x0a, 0x06, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0c, 0x73, 0x6f, 0x6e, 0x72, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x01, 0x18, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x65, + 0x74, 0x68, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x02, 0x18, 0x01, 0x12, 0x11, + 0x0a, 0x0b, 0x62, 0x74, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x03, 0x18, + 0x01, 0x12, 0x09, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x10, 0x04, 0x18, 0x01, 0x18, 0x03, 0x22, 0xfb, + 0x03, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, + 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x69, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, + 0x5f, 0x68, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, 0x12, 0x2b, 0x0a, 0x11, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, + 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x3b, 0x0a, 0x0d, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x71, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, + 0x6b, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x0e, 0x69, 0x73, 0x73, 0x75, + 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x01, 0x18, 0x01, 0x12, 0x22, + 0x0a, 0x1c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x64, 0x69, 0x64, + 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x2c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x10, 0x02, + 0x18, 0x01, 0x12, 0x26, 0x0a, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, + 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x10, 0x03, 0x18, 0x01, 0x18, 0x06, 0x42, 0x7a, 0x0a, 0x0a, + 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, + 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, + 0xca, 0x02, 0x06, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, + 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x07, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -6242,32 +5456,26 @@ func file_did_v1_state_proto_rawDescGZIP() []byte { return file_did_v1_state_proto_rawDescData } -var file_did_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_did_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_did_v1_state_proto_goTypes = []interface{}{ (*Assertion)(nil), // 0: did.v1.Assertion (*Authentication)(nil), // 1: did.v1.Authentication - (*Controller)(nil), // 2: did.v1.Controller - (*Grant)(nil), // 3: did.v1.Grant - (*Macaroon)(nil), // 4: did.v1.Macaroon - (*Verification)(nil), // 5: did.v1.Verification - nil, // 6: did.v1.Assertion.AccumulatorEntry - nil, // 7: did.v1.Authentication.MetadataEntry - nil, // 8: did.v1.Verification.MetadataEntry - (*PubKey)(nil), // 9: did.v1.PubKey + (*Biscuit)(nil), // 2: did.v1.Biscuit + (*Controller)(nil), // 3: did.v1.Controller + (*Verification)(nil), // 4: did.v1.Verification + nil, // 5: did.v1.Assertion.AccumulatorEntry + nil, // 6: did.v1.Authentication.MetadataEntry + nil, // 7: did.v1.Verification.MetadataEntry } var file_did_v1_state_proto_depIdxs = []int32{ - 9, // 0: did.v1.Assertion.public_key:type_name -> did.v1.PubKey - 6, // 1: did.v1.Assertion.accumulator:type_name -> did.v1.Assertion.AccumulatorEntry - 9, // 2: did.v1.Authentication.public_key:type_name -> did.v1.PubKey - 7, // 3: did.v1.Authentication.metadata:type_name -> did.v1.Authentication.MetadataEntry - 9, // 4: did.v1.Controller.public_key:type_name -> did.v1.PubKey - 9, // 5: did.v1.Verification.public_key:type_name -> did.v1.PubKey - 8, // 6: did.v1.Verification.metadata:type_name -> did.v1.Verification.MetadataEntry - 7, // [7:7] is the sub-list for method output_type - 7, // [7:7] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 5, // 0: did.v1.Assertion.accumulator:type_name -> did.v1.Assertion.AccumulatorEntry + 6, // 1: did.v1.Authentication.metadata:type_name -> did.v1.Authentication.MetadataEntry + 7, // 2: did.v1.Verification.metadata:type_name -> did.v1.Verification.MetadataEntry + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_did_v1_state_proto_init() } @@ -6302,7 +5510,7 @@ func file_did_v1_state_proto_init() { } } file_did_v1_state_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Controller); i { + switch v := v.(*Biscuit); i { case 0: return &v.state case 1: @@ -6314,7 +5522,7 @@ func file_did_v1_state_proto_init() { } } file_did_v1_state_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Grant); i { + switch v := v.(*Controller); i { case 0: return &v.state case 1: @@ -6326,18 +5534,6 @@ func file_did_v1_state_proto_init() { } } file_did_v1_state_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Macaroon); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_did_v1_state_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Verification); i { case 0: return &v.state @@ -6356,7 +5552,7 @@ func file_did_v1_state_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_did_v1_state_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 8, NumExtensions: 0, NumServices: 0, }, diff --git a/api/did/v1/tx.pulsar.go b/api/did/v1/tx.pulsar.go index d74584bec..e8fdc7d63 100644 --- a/api/did/v1/tx.pulsar.go +++ b/api/did/v1/tx.pulsar.go @@ -7128,148 +7128,149 @@ var file_did_v1_tx_proto_rawDesc = []byte{ 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x01, 0x0a, 0x15, 0x4d, 0x73, - 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, - 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x72, - 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, - 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x22, 0x4b, 0x0a, 0x1d, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, - 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, - 0xbc, 0x01, 0x0a, 0x10, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, - 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, - 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, - 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x0f, 0x82, - 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, 0x46, - 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0xfd, 0x01, 0x0a, 0x0c, 0x4d, 0x73, 0x67, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, - 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, - 0x72, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, - 0x6f, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, 0x49, 0x0a, 0x14, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, - 0x68, 0x22, 0xab, 0x01, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, - 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, + 0x6f, 0x74, 0x6f, 0x1a, 0x13, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, + 0x01, 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x73, 0x73, 0x65, 0x72, - 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x63, 0x61, 0x72, - 0x6f, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x0f, - 0x82, 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, - 0x48, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, - 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0xba, 0x01, 0x0a, 0x17, 0x4d, 0x73, - 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, - 0x2d, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x61, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x64, 0x12, 0x25, - 0x0a, 0x0e, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, 0x4d, 0x0a, 0x1f, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, + 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, + 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, + 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, 0x4b, 0x0a, 0x1d, 0x4d, 0x73, 0x67, 0x4c, 0x69, + 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x64, 0x69, 0x64, 0x22, 0xbc, 0x01, 0x0a, 0x10, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, + 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, + 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x6d, + 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x22, 0x46, 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x73, + 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0xfd, 0x01, 0x0a, 0x0c, + 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x12, 0x38, 0x0a, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, + 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x3b, 0x0a, + 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, 0x49, 0x0a, 0x14, 0x4d, + 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, + 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0xab, 0x01, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x55, 0x6e, + 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x73, 0x73, 0x65, 0x72, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, + 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x22, 0x48, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, + 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, + 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0xba, + 0x01, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, + 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x44, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x61, 0x63, + 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, 0x4d, 0x0a, 0x1f, 0x4d, + 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0x9d, 0x01, 0x0a, 0x0f, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, + 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, + 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf5, 0x03, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x3f, 0x0a, + 0x09, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x12, 0x14, 0x2e, 0x64, 0x69, 0x64, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, + 0x1a, 0x1c, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, + 0x0a, 0x0d, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x18, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, + 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x20, 0x2e, 0x64, 0x69, 0x64, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x12, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0x9d, 0x01, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, - 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x32, 0xf5, 0x03, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x3f, 0x0a, 0x09, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x54, 0x78, 0x12, 0x14, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x78, 0x1a, 0x1c, 0x2e, 0x64, 0x69, - 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, - 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0d, 0x4c, 0x69, 0x6e, - 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e, 0x64, 0x69, 0x64, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, - 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x20, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x12, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x64, - 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x25, 0x2e, 0x64, 0x69, - 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, - 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, - 0x6e, 0x1a, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, - 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x14, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, - 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, - 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x27, - 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, + 0x6e, 0x12, 0x1d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x69, + 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x1a, 0x25, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x17, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x1a, 0x1f, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x77, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, - 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, - 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, - 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, - 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x69, 0x64, 0x5c, - 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x56, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x55, 0x6e, 0x6c, 0x69, 0x6e, + 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x2e, 0x64, 0x69, 0x64, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, + 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x14, 0x55, 0x6e, + 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, + 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x1a, 0x27, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, + 0x55, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0c, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x17, 0x2e, 0x64, + 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1f, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x77, 0x0a, + 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x06, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, + 0x69, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -7329,6 +7330,7 @@ func file_did_v1_tx_proto_init() { return } file_did_v1_genesis_proto_init() + file_did_v1_params_proto_init() if !protoimpl.UnsafeEnabled { file_did_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MsgLinkAuthentication); i { diff --git a/api/service/module/v1/module.pulsar.go b/api/service/module/v1/module.pulsar.go index 26e888436..0f7d12fc7 100644 --- a/api/service/module/v1/module.pulsar.go +++ b/api/service/module/v1/module.pulsar.go @@ -104,9 +104,9 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.service.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.service.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -120,9 +120,9 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.service.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.service.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -136,9 +136,9 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro switch descriptor.FullName() { default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.service.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.service.module.v1.Module does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", descriptor.FullName())) } } @@ -156,9 +156,9 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.service.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.service.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -176,9 +176,9 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.service.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.service.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -189,9 +189,9 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.service.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.service.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -201,7 +201,7 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in onsonr.sonr.service.module.v1.Module", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in service.module.v1.Module", d.FullName())) } panic("unreachable") } @@ -415,30 +415,25 @@ var File_service_module_v1_module_proto protoreflect.FileDescriptor var file_service_module_v1_module_proto_rawDesc = []byte{ 0x0a, 0x1e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x1d, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, - 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x32, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x28, 0xba, 0xc0, 0x96, - 0xda, 0x01, 0x22, 0x0a, 0x20, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x78, 0x2f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x80, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x6f, 0x6e, - 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, - 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x6d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, - 0x31, 0xa2, 0x02, 0x04, 0x4f, 0x53, 0x53, 0x4d, 0xaa, 0x02, 0x1d, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, - 0x72, 0x2e, 0x53, 0x6f, 0x6e, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1d, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, - 0x72, 0x5c, 0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x29, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, - 0x72, 0x5c, 0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x21, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x53, - 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x4d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x11, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, + 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a, 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, + 0xc1, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x53, 0x4d, 0x58, 0xaa, 0x02, 0x11, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x11, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1d, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -455,7 +450,7 @@ func file_service_module_v1_module_proto_rawDescGZIP() []byte { var file_service_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_service_module_v1_module_proto_goTypes = []interface{}{ - (*Module)(nil), // 0: onsonr.sonr.service.module.v1.Module + (*Module)(nil), // 0: service.module.v1.Module } var file_service_module_v1_module_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type diff --git a/api/service/v1/state.pulsar.go b/api/service/v1/state.pulsar.go index 7dd02efe5..c40f31343 100644 --- a/api/service/v1/state.pulsar.go +++ b/api/service/v1/state.pulsar.go @@ -177,8 +177,8 @@ func (x *fastReflection_Metadata) Range(f func(protoreflect.FieldDescriptor, pro return } } - if x.Icon != nil { - value := protoreflect.ValueOfMessage(x.Icon.ProtoReflect()) + if x.Icon != "" { + value := protoreflect.ValueOfString(x.Icon) if !f(fd_Metadata_icon, value) { return } @@ -215,7 +215,7 @@ func (x *fastReflection_Metadata) Has(fd protoreflect.FieldDescriptor) bool { case "service.v1.Metadata.category": return x.Category != "" case "service.v1.Metadata.icon": - return x.Icon != nil + return x.Icon != "" case "service.v1.Metadata.tags": return len(x.Tags) != 0 default: @@ -245,7 +245,7 @@ func (x *fastReflection_Metadata) Clear(fd protoreflect.FieldDescriptor) { case "service.v1.Metadata.category": x.Category = "" case "service.v1.Metadata.icon": - x.Icon = nil + x.Icon = "" case "service.v1.Metadata.tags": x.Tags = nil default: @@ -281,7 +281,7 @@ func (x *fastReflection_Metadata) Get(descriptor protoreflect.FieldDescriptor) p return protoreflect.ValueOfString(value) case "service.v1.Metadata.icon": value := x.Icon - return protoreflect.ValueOfMessage(value.ProtoReflect()) + return protoreflect.ValueOfString(value) case "service.v1.Metadata.tags": if len(x.Tags) == 0 { return protoreflect.ValueOfList(&_Metadata_7_list{}) @@ -319,7 +319,7 @@ func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value pro case "service.v1.Metadata.category": x.Category = value.Interface().(string) case "service.v1.Metadata.icon": - x.Icon = value.Message().Interface().(*URI) + x.Icon = value.Interface().(string) case "service.v1.Metadata.tags": lv := value.List() clv := lv.(*_Metadata_7_list) @@ -344,11 +344,6 @@ func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value pro // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Metadata) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "service.v1.Metadata.icon": - if x.Icon == nil { - x.Icon = new(URI) - } - return protoreflect.ValueOfMessage(x.Icon.ProtoReflect()) case "service.v1.Metadata.tags": if x.Tags == nil { x.Tags = []string{} @@ -365,6 +360,8 @@ func (x *fastReflection_Metadata) Mutable(fd protoreflect.FieldDescriptor) proto panic(fmt.Errorf("field description of message service.v1.Metadata is not mutable")) case "service.v1.Metadata.category": panic(fmt.Errorf("field category of message service.v1.Metadata is not mutable")) + case "service.v1.Metadata.icon": + panic(fmt.Errorf("field icon of message service.v1.Metadata is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Metadata")) @@ -389,8 +386,7 @@ func (x *fastReflection_Metadata) NewField(fd protoreflect.FieldDescriptor) prot case "service.v1.Metadata.category": return protoreflect.ValueOfString("") case "service.v1.Metadata.icon": - m := new(URI) - return protoreflect.ValueOfMessage(m.ProtoReflect()) + return protoreflect.ValueOfString("") case "service.v1.Metadata.tags": list := []string{} return protoreflect.ValueOfList(&_Metadata_7_list{list: &list}) @@ -482,8 +478,8 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if x.Icon != nil { - l = options.Size(x.Icon) + l = len(x.Icon) + if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } if len(x.Tags) > 0 { @@ -530,17 +526,10 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { dAtA[i] = 0x3a } } - if x.Icon != nil { - encoded, err := options.Marshal(x.Icon) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + if len(x.Icon) > 0 { + i -= len(x.Icon) + copy(dAtA[i:], x.Icon) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Icon))) i-- dAtA[i] = 0x32 } @@ -777,7 +766,7 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Icon", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -787,27 +776,23 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - if x.Icon == nil { - x.Icon = &URI{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Icon); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } + x.Icon = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 2 { @@ -1488,474 +1473,6 @@ func (x *fastReflection_Profile) ProtoMethods() *protoiface.Methods { } } -var ( - md_URI protoreflect.MessageDescriptor - fd_URI_protocol protoreflect.FieldDescriptor - fd_URI_uri protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_state_proto_init() - md_URI = File_service_v1_state_proto.Messages().ByName("URI") - fd_URI_protocol = md_URI.Fields().ByName("protocol") - fd_URI_uri = md_URI.Fields().ByName("uri") -} - -var _ protoreflect.Message = (*fastReflection_URI)(nil) - -type fastReflection_URI URI - -func (x *URI) ProtoReflect() protoreflect.Message { - return (*fastReflection_URI)(x) -} - -func (x *URI) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_state_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_URI_messageType fastReflection_URI_messageType -var _ protoreflect.MessageType = fastReflection_URI_messageType{} - -type fastReflection_URI_messageType struct{} - -func (x fastReflection_URI_messageType) Zero() protoreflect.Message { - return (*fastReflection_URI)(nil) -} -func (x fastReflection_URI_messageType) New() protoreflect.Message { - return new(fastReflection_URI) -} -func (x fastReflection_URI_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_URI -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_URI) Descriptor() protoreflect.MessageDescriptor { - return md_URI -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_URI) Type() protoreflect.MessageType { - return _fastReflection_URI_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_URI) New() protoreflect.Message { - return new(fastReflection_URI) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_URI) Interface() protoreflect.ProtoMessage { - return (*URI)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_URI) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Protocol != 0 { - value := protoreflect.ValueOfEnum((protoreflect.EnumNumber)(x.Protocol)) - if !f(fd_URI_protocol, value) { - return - } - } - if x.Uri != "" { - value := protoreflect.ValueOfString(x.Uri) - if !f(fd_URI_uri, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_URI) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.URI.protocol": - return x.Protocol != 0 - case "service.v1.URI.uri": - return x.Uri != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.URI")) - } - panic(fmt.Errorf("message service.v1.URI does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_URI) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.URI.protocol": - x.Protocol = 0 - case "service.v1.URI.uri": - x.Uri = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.URI")) - } - panic(fmt.Errorf("message service.v1.URI does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_URI) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.URI.protocol": - value := x.Protocol - return protoreflect.ValueOfEnum((protoreflect.EnumNumber)(value)) - case "service.v1.URI.uri": - value := x.Uri - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.URI")) - } - panic(fmt.Errorf("message service.v1.URI does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_URI) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.URI.protocol": - x.Protocol = (URI_Protocol)(value.Enum()) - case "service.v1.URI.uri": - x.Uri = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.URI")) - } - panic(fmt.Errorf("message service.v1.URI does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_URI) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.URI.protocol": - panic(fmt.Errorf("field protocol of message service.v1.URI is not mutable")) - case "service.v1.URI.uri": - panic(fmt.Errorf("field uri of message service.v1.URI is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.URI")) - } - panic(fmt.Errorf("message service.v1.URI does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_URI) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.URI.protocol": - return protoreflect.ValueOfEnum(0) - case "service.v1.URI.uri": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.URI")) - } - panic(fmt.Errorf("message service.v1.URI does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_URI) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.URI", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_URI) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_URI) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_URI) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_URI) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*URI) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Protocol != 0 { - n += 1 + runtime.Sov(uint64(x.Protocol)) - } - l = len(x.Uri) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*URI) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Uri) > 0 { - i -= len(x.Uri) - copy(dAtA[i:], x.Uri) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Uri))) - i-- - dAtA[i] = 0x12 - } - if x.Protocol != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Protocol)) - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*URI) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: URI: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: URI: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) - } - x.Protocol = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.Protocol |= URI_Protocol(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Uri", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Uri = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.0 @@ -1969,52 +1486,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type URI_Protocol int32 - -const ( - URI_HTTPS URI_Protocol = 0 - URI_IPFS URI_Protocol = 1 -) - -// Enum value maps for URI_Protocol. -var ( - URI_Protocol_name = map[int32]string{ - 0: "HTTPS", - 1: "IPFS", - } - URI_Protocol_value = map[string]int32{ - "HTTPS": 0, - "IPFS": 1, - } -) - -func (x URI_Protocol) Enum() *URI_Protocol { - p := new(URI_Protocol) - *p = x - return p -} - -func (x URI_Protocol) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (URI_Protocol) Descriptor() protoreflect.EnumDescriptor { - return file_service_v1_state_proto_enumTypes[0].Descriptor() -} - -func (URI_Protocol) Type() protoreflect.EnumType { - return &file_service_v1_state_proto_enumTypes[0] -} - -func (x URI_Protocol) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use URI_Protocol.Descriptor instead. -func (URI_Protocol) EnumDescriptor() ([]byte, []int) { - return file_service_v1_state_proto_rawDescGZIP(), []int{2, 0} -} - type Metadata struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2025,7 +1496,7 @@ type Metadata struct { Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` Category string `protobuf:"bytes,5,opt,name=category,proto3" json:"category,omitempty"` - Icon *URI `protobuf:"bytes,6,opt,name=icon,proto3" json:"icon,omitempty"` + Icon string `protobuf:"bytes,6,opt,name=icon,proto3" json:"icon,omitempty"` Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` } @@ -2084,11 +1555,11 @@ func (x *Metadata) GetCategory() string { return "" } -func (x *Metadata) GetIcon() *URI { +func (x *Metadata) GetIcon() string { if x != nil { return x.Icon } - return nil + return "" } func (x *Metadata) GetTags() []string { @@ -2162,56 +1633,13 @@ func (x *Profile) GetController() string { return "" } -type URI struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Protocol URI_Protocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=service.v1.URI_Protocol" json:"protocol,omitempty"` - Uri string `protobuf:"bytes,2,opt,name=uri,proto3" json:"uri,omitempty"` -} - -func (x *URI) Reset() { - *x = URI{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_state_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *URI) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*URI) ProtoMessage() {} - -// Deprecated: Use URI.ProtoReflect.Descriptor instead. -func (*URI) Descriptor() ([]byte, []int) { - return file_service_v1_state_proto_rawDescGZIP(), []int{2} -} - -func (x *URI) GetProtocol() URI_Protocol { - if x != nil { - return x.Protocol - } - return URI_HTTPS -} - -func (x *URI) GetUri() string { - if x != nil { - return x.Uri - } - return "" -} - var File_service_v1_state_proto protoreflect.FileDescriptor var file_service_v1_state_proto_rawDesc = []byte{ 0x0a, 0x16, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, - 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdd, 0x01, + 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcc, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, @@ -2220,39 +1648,31 @@ var file_service_v1_state_proto_rawDesc = []byte{ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, - 0x67, 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x52, 0x49, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, - 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x3a, 0x1e, 0xf2, - 0x9e, 0xd3, 0x8e, 0x03, 0x18, 0x0a, 0x06, 0x0a, 0x02, 0x69, 0x64, 0x10, 0x01, 0x12, 0x0c, 0x0a, - 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x01, 0x22, 0x91, 0x01, - 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x3a, 0x24, 0xf2, 0x9e, 0xd3, - 0x8e, 0x03, 0x1e, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, - 0x02, 0x22, 0x6e, 0x0a, 0x03, 0x55, 0x52, 0x49, 0x12, 0x34, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x52, 0x49, 0x2e, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x10, - 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, - 0x22, 0x1f, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x09, 0x0a, 0x05, - 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x50, 0x46, 0x53, 0x10, - 0x01, 0x42, 0x96, 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, - 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0b, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x3a, 0x1e, 0xf2, 0x9e, + 0xd3, 0x8e, 0x03, 0x18, 0x0a, 0x06, 0x0a, 0x02, 0x69, 0x64, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x06, + 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x01, 0x22, 0x91, 0x01, 0x0a, + 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x3a, 0x24, 0xf2, 0x9e, 0xd3, 0x8e, + 0x03, 0x1e, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x2c, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x02, + 0x42, 0x96, 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, + 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0b, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -2267,22 +1687,17 @@ func file_service_v1_state_proto_rawDescGZIP() []byte { return file_service_v1_state_proto_rawDescData } -var file_service_v1_state_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_service_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_service_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_service_v1_state_proto_goTypes = []interface{}{ - (URI_Protocol)(0), // 0: service.v1.URI.Protocol - (*Metadata)(nil), // 1: service.v1.Metadata - (*Profile)(nil), // 2: service.v1.Profile - (*URI)(nil), // 3: service.v1.URI + (*Metadata)(nil), // 0: service.v1.Metadata + (*Profile)(nil), // 1: service.v1.Profile } var file_service_v1_state_proto_depIdxs = []int32{ - 3, // 0: service.v1.Metadata.icon:type_name -> service.v1.URI - 0, // 1: service.v1.URI.protocol:type_name -> service.v1.URI.Protocol - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_service_v1_state_proto_init() } @@ -2315,32 +1730,19 @@ func file_service_v1_state_proto_init() { return nil } } - file_service_v1_state_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*URI); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_service_v1_state_proto_rawDesc, - NumEnums: 1, - NumMessages: 3, + NumEnums: 0, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, GoTypes: file_service_v1_state_proto_goTypes, DependencyIndexes: file_service_v1_state_proto_depIdxs, - EnumInfos: file_service_v1_state_proto_enumTypes, MessageInfos: file_service_v1_state_proto_msgTypes, }.Build() File_service_v1_state_proto = out.File diff --git a/api/vault/module/v1/module.pulsar.go b/api/vault/module/v1/module.pulsar.go index 35d8ea019..1789eae62 100644 --- a/api/vault/module/v1/module.pulsar.go +++ b/api/vault/module/v1/module.pulsar.go @@ -104,9 +104,9 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.vault.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.vault.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -120,9 +120,9 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.vault.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.vault.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -136,9 +136,9 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro switch descriptor.FullName() { default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.vault.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.vault.module.v1.Module does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", descriptor.FullName())) } } @@ -156,9 +156,9 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.vault.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.vault.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -176,9 +176,9 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.vault.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.vault.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -189,9 +189,9 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: onsonr.sonr.vault.module.v1.Module")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) } - panic(fmt.Errorf("message onsonr.sonr.vault.module.v1.Module does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) } } @@ -201,7 +201,7 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in onsonr.sonr.vault.module.v1.Module", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in vault.module.v1.Module", d.FullName())) } panic("unreachable") } @@ -414,30 +414,25 @@ var File_vault_module_v1_module_proto protoreflect.FileDescriptor var file_vault_module_v1_module_proto_rawDesc = []byte{ 0x0a, 0x1c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, - 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, - 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x76, 0x61, 0x75, 0x6c, - 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x30, 0x0a, - 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x26, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x20, 0x0a, - 0x1e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, - 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x78, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x42, - 0xf4, 0x01, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x73, - 0x6f, 0x6e, 0x72, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, + 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, + 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, + 0xda, 0x01, 0x18, 0x0a, 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, 0xb5, 0x01, 0x0a, 0x13, + 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x04, 0x4f, 0x53, 0x56, 0x4d, 0xaa, 0x02, - 0x1b, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2e, 0x53, 0x6f, 0x6e, 0x72, 0x2e, 0x56, 0x61, 0x75, - 0x6c, 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1b, 0x4f, - 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x5c, 0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x56, 0x61, 0x75, 0x6c, 0x74, - 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x27, 0x4f, 0x6e, 0x73, - 0x6f, 0x6e, 0x72, 0x5c, 0x53, 0x6f, 0x6e, 0x72, 0x5c, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x4f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x53, - 0x6f, 0x6e, 0x72, 0x3a, 0x3a, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, - 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x56, 0x4d, 0x58, 0xaa, 0x02, 0x0f, + 0x56, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, + 0x02, 0x0f, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x1b, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x11, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -454,7 +449,7 @@ func file_vault_module_v1_module_proto_rawDescGZIP() []byte { var file_vault_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_vault_module_v1_module_proto_goTypes = []interface{}{ - (*Module)(nil), // 0: onsonr.sonr.vault.module.v1.Module + (*Module)(nil), // 0: vault.module.v1.Module } var file_vault_module_v1_module_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type diff --git a/buf.work.yaml b/buf.work.yaml new file mode 100644 index 000000000..494296bfa --- /dev/null +++ b/buf.work.yaml @@ -0,0 +1,4 @@ +version: v1 +directories: + - proto + - third_party/proto diff --git a/internal/dwn/fetch/serve.go b/cmd/dwn/main.go similarity index 69% rename from internal/dwn/fetch/serve.go rename to cmd/dwn/main.go index 8e44b86ea..f46fc5d0c 100644 --- a/internal/dwn/fetch/serve.go +++ b/cmd/dwn/main.go @@ -1,20 +1,64 @@ //go:build js && wasm // +build js,wasm -package fetch +package main import ( "bytes" + "encoding/json" "fmt" "io" "net/http" "net/http/httptest" + "os" "strings" "syscall/js" + "github.com/labstack/echo/v4" promise "github.com/nlepage/go-js-promise" + + "github.com/onsonr/sonr/pkg/common/ctx" + dwngen "github.com/onsonr/sonr/pkg/motr/config" + "github.com/onsonr/sonr/pkg/motr/routes" ) +const FileNameConfigJSON = "dwn.json" + +var config *dwngen.Config + +func main() { + // Load dwn config + if err := loadDwnConfig(); err != nil { + panic(err) + } + + // Setup HTTP server + e := echo.New() + e.Use(ctx.DWNSessionMiddleware(config)) + routes.RegisterWebNodeAPI(e) + routes.RegisterWebNodeViews(e) + Serve(e) +} + +func loadDwnConfig() error { + // Read dwn.json config + dwnBz, err := os.ReadFile(FileNameConfigJSON) + if err != nil { + return err + } + dwnConfig := new(dwngen.Config) + err = json.Unmarshal(dwnBz, dwnConfig) + if err != nil { + return err + } + config = dwnConfig + return nil +} + +// ╭───────────────────────────────────────────────────────╮ +// │ Serve HTTP Requests │ +// ╰───────────────────────────────────────────────────────╯ + // Serve serves HTTP requests using handler or http.DefaultServeMux if handler is nil. func Serve(handler http.Handler) func() { h := handler diff --git a/cmd/hway/bun.lockb b/cmd/gateway/bun.lockb similarity index 100% rename from cmd/hway/bun.lockb rename to cmd/gateway/bun.lockb diff --git a/cmd/hway/main.go b/cmd/gateway/main.go similarity index 66% rename from cmd/hway/main.go rename to cmd/gateway/main.go index 9d42bd747..ec0b98bb9 100644 --- a/cmd/hway/main.go +++ b/cmd/gateway/main.go @@ -4,15 +4,16 @@ package main import ( "github.com/labstack/echo/v4" - "github.com/onsonr/sonr/internal/ctx" - "github.com/onsonr/sonr/pkg/workers/routes" "github.com/syumai/workers" + + "github.com/onsonr/sonr/pkg/common/ctx" + "github.com/onsonr/sonr/pkg/hway/routes" ) func main() { s := echo.New() s.Use(ctx.HighwaySessionMiddleware) routes.RegisterGatewayViews(s) - routes.RegisterGatewayAPI(s) + routes.RegisterGatewayViews(s) workers.Serve(s) } diff --git a/cmd/hway/wrangler.toml b/cmd/gateway/wrangler.toml similarity index 100% rename from cmd/hway/wrangler.toml rename to cmd/gateway/wrangler.toml diff --git a/go.mod b/go.mod index 725f90638..dc18d913d 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,6 @@ replace ( // dgrijalva/jwt-go is deprecated and doesn't receive security updates. // See: https://github.com/cosmos/cosmos-sdk/issues/13134 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 - // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. // See: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 @@ -87,7 +86,6 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 google.golang.org/grpc v1.64.1 google.golang.org/protobuf v1.34.2 - gopkg.in/macaroon.v2 v2.1.0 ) require ( diff --git a/go.sum b/go.sum index 79ce9d6d6..65a70efb4 100644 --- a/go.sum +++ b/go.sum @@ -1121,7 +1121,6 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/frankban/quicktest v1.0.0/go.mod h1:R98jIehRai+d1/3Hv2//jOVCTJhW1VBavT6B6CuGq2k= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= @@ -2149,7 +2148,6 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= go4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU= -golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/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= @@ -2975,8 +2973,6 @@ 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/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/macaroon.v2 v2.1.0 h1:HZcsjBCzq9t0eBPMKqTN/uSN6JOm78ZJ2INbqcBQOUI= -gopkg.in/macaroon.v2 v2.1.0/go.mod h1:OUb+TQP/OP0WOerC2Jp/3CwhIKyIa9kQjuc7H24e6/o= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/internal/dwn/app.wasm b/internal/dwn/app.wasm deleted file mode 100755 index 023b7384d3bf070ae4d160fc09efb2f38ced7704..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11003100 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
KbA&HO^h`Fh5oIm}p#_8}%WW(4AVfxn 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

#efFJUrmwZC7VO0HX+?!?MZ`4lU|i~syk)@OIw ze1d@kl$S(~-Si)e!P(?>S*Ci)5=|Xq-gRb0Bz7D5`vuS#HMTo zd1V!0mAcK=dr4bCj!zg6z#Ny6W+!MJvWSTD$1-w{a_pe!<#MJVF5D(>@pjF%&iCH8 zv>jIg`&?;M_6ENCS9v2}8W29NSDa(p33omvB~KrU9^#d*@k)1S&qoc~UJA-ACItk+ zq;NmVB#%o5tpd2G=mc*OQHvI}qCoX-uJdl5(y>v0C<~~UNiVedErsT3VF-igNE28F zoR2GTL!kv>1o8ci{@&muNB&AYWUYF8c4Ih}2g++dH&eKTXsfq&lR{mnJE?e}Sn-xZ zML*V=xtQfSVJtY1n|bz6CC~n~^mjpz89X&<+?O$Ce8Jw0W)vPNGP#^)$O_>2A3E|HnULqL4p!@=v-q0Jrdi8 zNSHjv@k-XBVY~D-u3GMTfvc2?b_c$ z=3?8(i|x=y<^U6gF<%rYNp;3uzAJG(9#iC|7*nj6;A6=I4G`*L!jhTiM&=n$pD5Ac zK#?q{*b&Ny3$|P}+y!x$*<_Rn2NO8vfhB8yhl4~FWdn!W2qwF2{6C)bNchF|!$LqQ z;pNB0-B+ymU0L=cIn>Hc@?i{c?|cSWwsVRVRcLn~;DT1^$z({$Dpkpu-^j`LIi=aY zl3s|AKmt{#DcEc~mhgfF&E~0+e$4p<@OTTCMkC4;?yFO6SHJ~T_Gt;$sX{gDSuigT?e&z-2`VSTc@Pidy1K>o_z&=$T z3j3^p_5%BTwxVAn4ei(M7S*6$V874(C-wX77pmWPxu95p?0i1yKFH31++{-3G=M{t z@e5MLzMBk>>^P5lDRD2T`ObaCT}2+l4y*a;1vkH^T+^FV1=^JK6qXU2OWbxDj%I^T zcF~0{I4oW0(9myl#kgNQ^gA>ab4$fIMf|*&D(0bqb!)|NUp%lbi0rl}!*i;Rev3rw zSy1ykDw_{-4h8|Q{dj_#ncNQspvWo*+TTfGox}Q^368d>YQ<8o!e#?`aV>f-(2;tnt!?l$Sh>$ z$~kc$yeqsn9}loJ&myxjMemKqP*fzlVQ^C>K|vBT&$pSN(iWjB@eiWc@NMv90Adn9 z!?zkg!?!V@ba_qUXU5<{(fAp@wSZDq5v7=|Gq6E1TQ}Ij8^Rr38j-)T6X&h59O|ur zPD@7(U4ZN*7g#E)H~X-J5&XKaL^)TbofhIu*=Z)ubX4_y_B86z6JrYs-nb_1lnP1+ z-WX{}n#=_TPkiD;(9Gfmgg~Z##{anAAcddJkOK0QW?Y(f9RK8#U-q&eIOUX6PHnYD zmMlH(^fS&JU3S*l=bU@qdFP#f{@C)Dzv6-mFS>aAm9KjBB|muSYbGY!KlI;z_(y(p z#gD!A$A98=)nv6dA*`W} z?c(@IV{?#?@WNJu(Ur_vh#*KI!cLv>k&NZ(N3hQT{#!Kp3UssrvkOsSTk2Op@kK>= zB&`=T*+zn4iOGDa6qoWg0(5{DIha=O8%cW1BJ!gcx-@|6#QAIt&whl{VWz~3qz0O7 zT+x2b#&&%QodGB@TMNx=S?W&{Dqh=(%k!$GHRMzLVKgi>0pMZql0TNgqyG&(%3MJF z%WD@Q-u75LZAI&TflWllh;6mzT=Rru<%p-#^G^I8g)%3PjMG7)G!JfXh^JOlcE$T%4!*Zno%e zcM)%Muqac!B!DF_MGo=R>~&Y0(`TnEsv!`Hb%WCU%CMt2d@-H^W9FF6j&wE`r?X+G z+(kYc^X`L6i;FqGVMd~2=1Ex*8>0=mlU)G|Y>xizyL`Ngl&{FZIUwgefNjcM*(@-o z#KHaCj)G@=r;o!t<6{BO1baA_RGi-Db$0X!MV%*gLi(iq{2k+VdA;pg@0@wnd(i9M zqV>+2SG|Y4p7l41dW%QkMHy)I3V-@c4OnqHo({D7gkbmc!D-U`qKgr6+uy=$$gG;e ztS-gdrFe_@aUskvvG@|!C*?10^~%$y_;f@XL8_by(D=X=5aZyYtsc^9YcY6OFR>=X zn-gS+T8{(^9*yq~x)1nN6kS>Yy)!)QNp@>-&gk?lWXlpfC1Ih=6KesTM)qu$2EFb#>Uo-q!dLknmG}!Fp8-_j)v<3w% zf650E?c7>?G2@j9-NWKxA9Ju=B#8LZ02cBv@ZV3fOAC@-02Ed$+yD&1WYq}H(=8%2 z7qu3*dp5Rl2j?P5FaC10&M;~$yr2_*OSn_}zz3Do`mpqnF>kZ*9j-IcKtvhQAhYH{ zhSAiDULyyTxKPRnWe1Uk?DffCJt(u+u&7Z95fZ^h5%dH>Ako;$#^=MI+5c+AAnmk_ zzXUERh376dpMJZSA^t_CG?+l+vknboO0pkmX*t~^q$fH)=XH!h$UcPF8T(1=e8KA& zGm`l0Tpguqr`|7m9UGgRgUV5V+RvYP9UGelBxYfd*7f#Ex+AMcEMo0ne|=2L_EMBZ(z}bjdyro48Y3vV#L=R9HLq zg(;Y|<4hvyUf-6jOkz0Jbz%(*e>!szQX1!DbZd??70~msyBX<~9oOkl1ll)Ebq3xF z8QN_1h+M=mvmVL{$op0w#5@kDwHn;L5n-uWG|&Pojr6taBmH7}fXu|!VTzIekUXgO zR)`ur*@%7@QA*x>GMeq<^S(i1BirLKRZ%i1p#d8aubNC^=iA?GbydfxI3 z^vd&34zfmA{Kc3wls&2h1T)k$)uOnAqY&n5Hd=$SCU3oBNdzA15owM93>OOwX#(IG zDI6rEVtIrxxHIvP2cvpggH$NV3|*m=C8hOX2}6loEiGe4rd&*f>Yksqqm>Ha3RIf)rQ@ONTj$A&%1)Q=zVj ziPiEo3F~It^3rvasYXVZW&zsi^D^eB!n~W(@E)&YLRN)&P~VBusbId}>&#o2Kj3u= z!hFXO;K03y%z>55!jCOHwx<{O`hd^&58!H_#bC9AgGb1zSt>UrtFud5vRap)8qJW?2WCjMV%y&L`&)l}b_RYY@H;1jS3Z_oDkn2E zCz3h-Mi$H>76z;lq! zdKi4Bw|RdS9(SbR$f!(hf1KJFe#b=%>L(8d87!%Pws(IhsH2={zij_;q#lg1ePI1N z27)iR&WfS|nnW*nDksy2f03;OYR5q~r4qMSjy_RT zP>ELNOKUV4U|&Lm@AR1(T0nsIVdZ&<9?aEYa!(~>HFOmd5}P*$yOH`FcdZC7P)JTC@bS)y=c zfcl_!v{UV05SQiEB<}8CvcWBl3I2iOBM+B+!1YnPf|o1S;u5{=%{>ddf=2FAf zth;1Z#QlBUu2(ydh;X_ppwhxWq+5`*xD$r@x?lRE?imp9w}Zv}I2 z!a%nKd&sve=}&0wn$9y}K@F@pnb=P=_LBbg_iIxl19j{Macmo3u!ZOqTP8&T4=Z9D zw_yp*vb_+>Z$23v^|w23o08)F*q-#r)>fnkceIEJsKZUCUbGe-(CpUNZouG)HX2tz zD)B~K$fh@AYm!m#x!()w7|lRo@8|Ok=X2?~p^(b3#M^v^|I{x#Ls8rvKkx7Y-_`=6 zrF(%py@0hKb`dXdw->leG2AU6cMJe`1{R1r%888|zp_@VH^Qx&P{65!D-Q8~O@7pM zee{rhjyV>(`0+34s)-*At8VrV(Zn-Z6eBir;mj(|bg}e;_Dn57S}xciuu6QbIR;{9{A?o+K{=? zZU}lqWx_t5s0-hWUQ9}S#fBTb3C;FSj^Y7>W_Gn-Mi7v3Gt1IQ14JMXTMcm(EtPU8 zs83DR19yx#PkIkHAGRHLIRLKJZHFqPhzALM+A+pxHjyS1`Ej>5^PnDgrFoVkL8nk< zbg|+V>mDzDy<1zu&ViecP?5U;&3q6j7ka!6rF8LO!vbt*umDv1S`Bh8E(X@0%q!tr z_xV6<{i$cl`uCNr|A4GNBNAxYh23fcR)0WOADzV22PWw1_sQy0eI_&L#hAd&+Q_BV zD~yS%pVR-NJ{Y6_ghA{n6mSOdt+_5JgCMc{6rqpN&e=}|xk4*@HlgcW-f3*}5-_go z#0myRRzNvK>x}|ai3<3Y#mNMLHh2pUC<0+2q*e%(3mCh}OP(rxSoM77o<2THRzMq7 z4HShG4`rW19~DiRT#_DB971GNPjsA(63?)_F$Tm&4@P7ZRVL|)tx_{n+Gwsc`-0vb zsbh@-I860gpQ;&)e7(mq=N_@Nb-ND=(-eVk1Q$hHZSd=TkRbC(2I*3x{2O}vp<4I= zmqgQ}*&OB^20%e@9&zN6M;&$4(GVras1$)g2cHv8IFX;>;g_Ct(#f>&R$$+^6YM($ zMeRJCphTJpXSx$>82YgW!si4h>QfLlWZ~qP%4E6va4?g{O61SUvG|GYQ&sWcP0{V+ z#RmEVC{1H>qkXLWW*#Owl^gA2#K=K=wwZ*7xp%WhVZcHSDM5?2rN$Ztw+JO5*&6NR zqy){%mbPLTCJ1Xntue!NAlVa`SsLvVWEc#Vp-gGCUm{IVow6KO!)@XwkDm38M)kp6uE96@v^Fs|C@^yOJfX*kH}zL;JR1}9|HC@Git7M_ zG*%({{fvQ`IU4*c!@z`nfq#K_ky})(*LRck;!R9(TMG%8EZ4eDtYFKfS2u|;%c#g8 zFHqMju@H1}LB$C?s-9tJU{R5wQ4dFV`Bg_nXJ}+tS%yaCJj>9GU9~a{P1uz)G-Fq- z3_}CI$}%*G0l_ew_i*FM2hK{cPs}njCfUm}G)t=2$}lwAJadf-zjB6V{3_Ec*j1LH z$<8i63ezE+p$X=bZ&68TXetk2we)PFeSnHUqQ*Sx3uGOsX;VSE^XVWL7oyo?&^1U0Nyet2AaT#32NlJApKZPtZT-PFCBwpD{?V zO4B@pr$*qh7pwcB}5bGiJPvv(GBA_L}vQJx<0vPF z=)U$}s>_A!nliYT1JWHd1WaH1%leu-YT1i$pQNvWbUoZ0V|yaf_jnW$hEG>-h$AEJ zVc!`P;ux4hJXD-4SBG;UM^-T6|IH5Jf`a>xy@$l=fo7*EmI`w1+SD)+|mCpjFBcBBx^E=E9u_<&|XzDI+>dOPtlqTSFo{*1#4zv-+@=kBS z!k>Ll_f$QzMQcp(59o|6Fsi3iW9+5`W2soh1R`8cP0Q%4ZCxi;*`}3VDY8!ovBfVo{c3b(altLH!9j~JSsF(^}iQX<*C zwLm1e(IWIfqNLj3^ zL))NYshgc3ZZwF62$-~dmA7oTq6&Z_2{|pgVSG-@4l$M30}5<)wrt@eBny1u*E9B0 zVE|3YpgMY{4>cc1aAjvlSX5gO9U+D*#j!5Kl$wg&Nq&Q`F9rWObjMvl!T(zSLTlMu z2R!AYT-6GVWEv!EW|Vr!#Yg!Fb>V)*euV@;^eHwU7vBr8E2k3%FnW8 za)S2!v9Yn`{Jb2eX!)^|w6A{kCCOo0oTmMW*Zt({U;p}*E8l?68{hb*H~-X6U$*LJ ze&%O>mY<*dx&Qw2{QScISpAE?^vl2UtH1W^YkuQ5|Bv7LpTGS(m;dhn38c`S0)s+d zm&c7xXC~l=5&Z9=_~hQYSqqmn_wgidmWxk$6+L0&D>6x|C-Rbn5UZ3#IH#e8Q-f>@^p+U(DSW?^?{REEhCIfb{1!-CnphX!?pu^g1UOn|J02|1YcQ!Gcr zJ6z7l%Xb}iGj9bh(17yTT~T8;0%JffhS9v{Vy1uxgY``&=>cM*xCUx6d%4>od= zug4_SqRrz6i{vQg)qL@jGJ9On1ES^mua#149B$qw;vBg@1Y~f5NK=f005*aWGpbQf zViEkJ)0SBTd8!|i;QvOY+fD5DC)h2oG~zpkR3fU4o_BN@Y~!33*JBo>jCVbv(!m0G z8pnWY`@`{H*|;X-c)Bo-AD4ymjVt-X9yX!W6Ez9EI?*q_=Ivi3dvsRJ9^!b0 zt^IJe=^v8Nz!ZqcGjm!3$8UJs7U}RqXq*?xge8f~Ww^4Fff_8bFASUOlUk0SEwtNC zfP$-L5H3QjrK@c{k;V@C&!!ChAH6XXF%vS#S;@&@%oy8zIyoVoCa2gKa|6gY3+wgI z-rN?|1TW2uO$|12>D9yfJRz(J1TgcpKnsmFcC7l2H>y~r*#KfYj`o0K`L7J?OW#FQ@9zk5$c)Z+rXu=EK&e&37hR5evV z`Bb6Q16bU`O>=M;hE<8DbBR3wL(Le26i+%_cV*N{lmIReK)_ChO_-pMwEYU5_(}37mFB=Ns7h%LgYv%Y|Hy>O864(4S-ZpXW>CA^{GYyR#p)rBv@8d~$Y7sT0gts8izUz0PZyr+1k`Y=s!l1!5|QvRV*?4#JH{sfd^) zKt(groRfewXp7x{B1!Gh!lP<0xU5AX+_vwS_5 z{JG29SMp=Uto*r~t-+P+P4k!`QzNJlDFbNAgYNZCOb}@sGlwaN?k}`UXL0~HN0}Ey zAK_fgTU-!C4|!uIhLvZzk8g%FD+%Ogg`%MWMn} zV1B?`)p0Vir)r!+;Nz4cvus&26JV^C(?OYQB1QDXyfe)Yd54O|v}Hv!rV=7;n~if- znH2dbJ6}9Fc|HH7`ACjl>QD8#<0Pj3RCD1ACq-5W?&w5QjrJ2hGZP_VO3W$p*a6hC zBINNx9k(JrOe1sod5FdY|6mZ&n~z`&;Rh$p`I#dM^X|m7Kr3%1cOLd-&=jaDGa`*X zU;Iu@&C{LOicz3010#ZtXAHK)#syuFi%M^#xcAU_V!F7h(3mbFljpH93FmgTlJ^PG z*UVuiEnQb=iR({Wb=EB-HM38e(4`S5CY}ZwAuL7=F~MQ;S!ybjmNWRk0ohM5{g6r_ zT0U>~!QH9)t~&V`dK?Krt$n54X@t7zLM0_Mg5t^fJGc#fENmC2X7wZS698L#0x;IT6631_Q|qZ}>5R=^gJKZC&$&N&Qb zKMoN^;nM!XsZsRGt|!7ZLnVb3o1eY-|A%&NW$ypg{}1kRCA=SX{}`ju_$*rK847s} zK4Pe+ss04m=_QPt$t_`}hl##5GO`5uEl)#+OEJ^KMt|1XXPBc`h%+=c0@G ziTN%kCMG5&=j9LoFw$QB=!z9T_G7Po?T^!1|GJ-qy zvR8AxnCgG&mwx$|f8|$x6`x=GwO{}BH5sG*|N6b(|G)lV?H~Tp|NWLL-ukvq{mS~f z`c!?ozP`SpzOlZkepUVI`Ze{<^=s?b)vur9Z%h4#`i=FQ>RanK*KetBt8cHry?$%` z9rCxM9{z5t-(J7N{$}bk^*b|vch&j#&idW;d+_%z`@6S(Z+&O{dw2ak_514g*LTU^ z1NHFtV4Z)v>krxAd+QJ5?~&Z!qxDDYe~iCBk-t6l_u1e3>mR5;hQANSzYo{+_6Ry8dMSGx+<{`e*UCul_mweZKw${5@6wA{}HE z(&qla*v${}XDsVk8O*eKIn|XfQ5*bHT{VL>2?NGWuAwDkz$i%`ba_&6V^zU5WWgCf zid4?B<-mk7lrM59m=*+sS<|25lc(fKduSDke1Q+Xpbv&Qe0lJBeQ;8I@Hu^OoP^N* zBdsR;^vN+SA{NKb>VsqXfEjE4)T)TjLi+s-pJ1+QV99^EjvHU7#xr{BNqc)a-ohBB z#l%#^x1SDmb$1V=IJTEPlN%d&_bGyKSG$w3(wCnB2bf_XKnw!(taeidwgmO}hPLq% z;b}TDekCYTG^1PPHWkZjYt1WaYDfD{U$q(4C?40bnQ;nJ{W^j7$vD@nLP+%wA#pfw zAXcnV6#PUi$Z_{f@=U|W>fBmWX(Nm>4fLXcUTL6D8aN+?Kbo1_IMO50sWU4LK=R|@ zpa9{oIHnJyq|}!+rkCbJtlMjjDLQsOm}v}&l;JVN!w+DF+TY{$(?&)JTABBuOs~cA z@fZbu$3mQzH1sD@NW=L)#-{KfmWoY1Dy7ufBpu>GvDCu`BY~()Nb)Yemt{j>qBs;E zvf4xph9-WM9Y2UZbPc{@Kc$CUnO!Io!V@KJB_705KrwCUJ}ISh`U|#&2eDM_@7+>L z=OjJiL9x`mGAFSYXN_Y4Jw6 z5ILb+IXz7XJz;}G4)J&F^iE7utVGZ8*Bu;});c^Y{D;DnrRkt5Q&Bc{(RG$sUBR43 z$Rc-eMc}X&dif5A`wm+pnWeaW|Amil%`Dx7KYqJBo)6sSW@I4qrV-P>v&&mDT@t6h z$A??vf<~Zb_}Cms^Zfz@Z^|N#aF_QIEH_3VWcW}+8JPg@8kV|&r2^S)&htJNdaIX#0Mq{7!ZJEb>FzBhW&Vhi$k5t_$h(KGjOvWZyFWw= zPH2-4b4Y(6L@qBVqvs&H69sQR#fraAi4-Ed-_Iw%rz0oLaS=brXAEJ9Yy%YnIK({n zyZNa;&I*YC2;lgn{+1R3@TJWEJQQ&3Er5ezBF0c7SX5^yWt!n2kElz(>2san3^~3D zYD=HzpcynGRs(@WVk&sj2cp*0H8PI8VIwvQJmDzKV`qN&RcKwcoyoZI{!H5JuV@X`?d%n2%<+Rz$GR+b!;veX6>^~hyCBeni9{5#n zQgIQ{M3HJm=1FsJW^-^MVzfv-!>=6p00+Jh-uYMFoAFK!Hp-y>_leDKWOvZ(V9=xi z`%2C zfc`;mU!l)>L6l_7o8M!buQi~EE~jfT6jox0Jo4XJ3h_03C_s{cLG0NhGy4bc&$i+# zq_kk+lAdHg{!eA4n@|R7?E&))V2n7=mOkpK#_~e7 z)0IKxj>Kuyg2Q}jUDOxMH6=klxjJdG&-H~myvhU1Iz~naX+`d@n|A6i4Vn)a{?}tk z%Kv`@<5#GsP|+#;D(r=`z)S7}E3lhC@=0{m*=GKB2^jx-n(TfD!Udc??_F z0u&-{ihIZheF=XTVD3s(y$iM#HLpn7_`@RaG2WLTG5a%unR&JRl0_Kd}NMS5QnI zJjVx2IE@TmS74p{x!ed9ZS`IuGIM}8QS{>`3gm}0)cAW=VeCmn4a`Yrgv4Q-5i*Av zb|4&6*8Q`rgDWt&=J;=5@@YOm3`ZWXr0i4rN>FKF@{9a+3a1FarJxc5Nc)jDS-S!v zHj%v=W9q$K9xt>xu{JYn& zo;2JcKc}>(&Qz2{){_T3+&zEabz=hlrI*y?6A%7dvN@nig*Rb$@Bx@NfhX^y?>e8_ z1t)%aMtFc?F7@V4bz(!N!LT8eg9JLU-3nH{yF@p`BaKIxu0lO_iIq#DZ5 z9Oer^W=(iMF|i8#d?dk7hDA&s3@OO5<4ly}b)8tl;L93nEE|&4wUf*WfS`x=fsftH z7*Xt&>ft-o0fxPZSm#k7G8dl8)?)&MGZIiporWZcK-fb#9K!q% zpYDFQdgmq%oUwnS(It`%gu-M55*>ggs346!328tda@O5e7&#=?bz=GH`qCQATU=d| zMk+6-yyVA}`SqbB%1O=wZU`7Pq>?S|Wxdz^h{9VVx*(S$yn*5ogNU$UHMtI5nUscm z{c~J!RtPIz!qqfhWIHZ#Spbop@p=U81%m`LS+}Nrpk{K7NrOe& z&6y&6eJ6HvxB784lFR7P01Jap4i%r+5~zXs{LHB;7U3tsI(?+_BcLTCw!J2!l!MgNpK>VGiSN zQL>GR@;?>OQF+WZY*untxJGssqC}$^IyuiHK30x2* z?BoV-X+i8HW(pI2vy$9nzU<^C?=od4tMcqbng#i+g0-C5Y+xtXEdo1PNCvt*a{*Ji zC~Qjg-Zy5|kGH=ui7j&2YV0F}ADIn(&YOuoo^TzSXW}J=*hb+jy$0Mvxrc}Kc*c3W z1aqRrCOBo6W>BiL) zjs`<|1Tpd4BpEBFbvl$EA2E+klD)d@1#>2{|%%@gWiM3Or!h)v|YH!UEHmQX|85uWaBa zcZ}cc1vVpy zCo^K89JjbM51)us{F-)R36cTSr)i`&^N3WD1%qlve1bI=n@^?#Yfds(!+^vAz!2NO ze^5ih&Xciqv^Jn2n1BNYKo2>28iSDGX41!*Wk5H7y15HtsC*THEL2*Gy3r#JNn>VN zT^~A18}~>JkWuZ|+oe<)8oH!5w-WTIw{2X@w@%mh&0DP?oJT)3g030sz08lD6 zReKZ0LJZ3?7HTLoAegC&jK*?a!%UzdS=9a1mPta+XnI6d`w4+AE0vJP`cCZs-LC8h zv|`_xd`2l|Z}iGW9zcpf9uc$2-V__%K0(|Ur?D}Mz#oKJDCa0AaZD&-XqyXz;I_1k zMk8yQcW-QGVeq`(M{}3LQ`L8nY}Cz++Mp&bboM1Qaf5eQK@%q%P3-=jD3$XS<2QQ4 z1%h~zwuGwGYaoGn*b<&h&|Yi_n(dEJXWAuh{JCvaGdLe6$UD`Ettf9-SVLzfXqCll zm7y~0Pzf~Gdy8{G^V181<_2%L0L^dCb;gkD4WNok9%#i>#?m#D-M$34+`v!n4>nA~ z_wodkxUM$Td6(iXNtq=rJAv%Nz+QQk+ssDZb9&~6Y^yk zSBe=BKql>(F9%Bk2&H|r)f`p+wc37ijg^djVC#Kg_vyg&kQikVh)*>x?)KGGNqU5F zHSjn)7?~bg*yxQKkAqaqY`ux37bx6Be238fx!H^#->bI8EcH2tIa+-a~sIk9cx`gc-^W$eB``kSzfEo{{lLmOLWwO zt~j*l_Y6U^=4GF_>Qg>)q9~hMeR8OnYU`yM4 zEKl~r@RaOPRZQNhmRLi0KOm`~tB^8F^;na@K&krUXMrj2@Npj)kbRE0sVf#W(}X4O z+G^`kzOp30MD3dK4h>LbwwC`P><+{J0Qjqh=#yClzdFsS>1iBA0(N&9VniO|USRj- zBV@Y;mVi4v18!M5>N2ZrM+O1fR)GNe()?&L8O8U=Z{J;LF>9Sw+2Sq5ZLD$fG`onU zmk@2c{gtm~#omxnor%3pAfqu|e-+>Ap7_$YgRxND6HxagFrl~uON9q6E)C!@_nZ2E ztK4t40!rIyW4OUIG=WD8z{{RUs~1mM(N4f6j+l~l455a&jTH3o58Er%MnSOM| zfvIuw039LcqnheG9l&jz0TU#YC6y}AA7YjSj-`P0w5r)waBpd7r7*V#s$H4$LWcvP z-I z2VI@Yx?Vm&cPX64G^V1M@eX<^W#jllT{m!p56Xn7L`^uG*y;reIDfco_1g*jMasU2 zY&G_031?J}zR+wn_ELb?i-g9{Ct!TB(KznH1RcIUw6qe=2 z!&DZ(8@kSF2Mf8kp6oTS5!x@KvM7wCpbp0Vwr1rSHoH^|6q~h9sS(pjdwnOiRDj9h zl6GeoHz0mn*NaWsvA>(MFnOU#JN8n5*VYm#`@)F-=>W+@{8RnQsK$mRVrJom?IQa> zTr#Q`M)q&29#uiVpYD{DrhY&71P&JsH-}+nN%KXNFtI-~AG|mcCiYT5!*^vDygA_} zSg1!mvgw_tE~*-zZs2&1M6?3iz(uP?u&|VG$fi150`v>x?6R)nxtNDPXlrQPmR9^h zy2s$)8J=KqyxejRAb)N{QV1}3OH?S$FbGF43&ZRi-wONH7J#8GQOnb9d+-QyTbf!n zraN(L7l~y}u|W6fF!ORl+%&}w9DCe%wv`D2@9VArV|C#~woe^Kc1tK(t@>_Hphqp) z4pm^jYGCTzdxUTm{iTiw`K}5+;|HLw${wFSU-(1hs<4r!T^|e8wW;bW?<~#k)vxQs z{*9|KSOCj33I|JF(F$K&RBf>e#T#v^DXhKw?{9@chAWj?V5zHX$RgHmG;fF<<(%R3 z+{4YYAotXfFGKnWugto;UE@mO=UobP$VqOk@Y$0cqY=kes|ifdcB6M=(rZVlmVc(e;k#bx1Rx%pOpky)AN zVUC3aXFLvXL;|nTzbvx zm`({7F`YTO?5t{P*qKnnIVkFZ1&O;_=NKx-Ijqn*jAL|6|F46F4X2NOW!|fL8iz%a=i64_CAEw3j$`It zc`08isUxIq=9ZfSVRMlB-A9ECwP94-)Ska23o)GGDnM99x4d>S`-ZOpN97qwfD_Zb zJX0U85~h8*xL(C-rkz-XU8R=L6iZVX<8?3D&mpCN@S^|x} zbDq1N$817&z0*;J{`>w2%Gs}X1?9~?v$rcKqYGadC>MxP0pi350F7TWw9$O{8l#3e zwr9I9+jj5EmW`?K1ELr9PjC0)26Pk`|45F7=79T-O5kRr2GEt9VWo!ul0k7V)9b&h zy@|eiI}2VG8WPKx->I|=E~girnrm^aE?7LF9C`b?ew7^_q6(aP< zDMIDLoftkiM@$t`4i)s{BYNZ!a`B<$Q`Th4LA*k^Qo168^696aaV8K8-iXo0P+1(* z{el0Rwz&+YJr0T?4yJB0MJWUz7kek3f%3`FB$eoyOdJQql;g4T-gK_;fMEy-Lemni zPTJm&+Tj=epfyM$k0R&J>@u@YKP{Sq=;$s~0x|TA@>&XC zDzczDK^5)M&Uh%C?GZkD=L)zB4hS)M+2!~L3KFAwQE766*i$(OZu^3ID4@LrL(n`W=wY5wZ@Q;N`4|W! zR(=oh1pnoL12-SjpJ59{%M#v(EtGn^1G9HU?EStPAJu)63f4UgqQWE?7z9wNNGOk{ z+SO*^kkqfdO#aAhd&}*G1P&kcftVLZ4k;uRJH?70E>x6Ywvu@5k9tWnm&7fpFt&T! zFtEspkUfuC^gBVgdOjyYKIU!P@I@Y$jN+4C(ndiuPjKF3&!udBU_mkXk9)&eKUf06 z=WZ*2{)s|GmzN(o4)XFp^WI`e)XOMQRg9`A&01r4BLU)vAwF?uFd~O>4ME(Wo(>Tz zmj$1R4{i%S%Wex^j%$K>MKIuQ(sj5PWxP9)uCGFAzc9gf$mcvwN)IpJ7L$;(B;^znrcCDUEYL_XWGe)~gWTc4TkX1u|fC=SfF}7?- z^#x8X0)fK#f?$a46VuMiW!DQ)ihfc#aZ@Kw(HQZ|RZi%BE_6&r2rAegf(mVud_aEZ z_8m7{gGH{)ivuG=gs6E1Mmh#?K;68|_EJoQe?A{6KNjb1igHqe}nLRdQm4Vqb#H(W&?ZP3wR%^Y-Y zuY`_TI@Bt}E$_=QDw;2J>_i%hXQ~9y*75*4(0yZjm(RmCwraTu01~vJW^=lAXN&Pg zsx>rKjPfgfPvz<4XYqr4j8*D zfx)v3E>Os(oG(qvHPLF{m=h`ia<*eFg`8+jvw=Gpx7Ztg8$ImP->!E&;uF4C^^Rc~ zG^jvSG!7XG4!?`7AG!~}Ljfbp=oN~%2y100q}4#)JIT8js7{j3!Sa+p8heyG5abBN zuJ&^@3kMD-Ka{40yYe^DC|6r<(dOBQUg$$7F6p!V#ghIu&&dwpf=*2%W*iyAXZj(I znHNjro=+T9e8SGt3|=pM+?ztr41{h@yG!-op$4otSG6P_ql{ z9NJGfwBMu9R-1+(K)1zhs4b$I7$W3~2&A8CHNY?kDsCmnq(060iT=fLuGVSbf<%>j z)a}DmIIS=hLz2iuIW??DjCkkt@H-+Ir-u@pc z7h!pTt!cev#-HPiB!LTWO;nM;8WLY-%E%UDF5RFQ%9t8mPDUjrkEeWibC^87R4C~x z-1o9BxaLG7{z0{3m`Zn_anDI=5l@^31SkveE_lEdA%rIeaI8#qodzKeXQPq*|YvYJ!gV zx;)43boL~Wk#m#bUcKVcV`R7r6^zBR0?NUKr)WiM=oo>*%m^@}&}cz_1?UNkLOtu; zv5+;ij6p^=0h&;d<~T<@RN|b&xxzI*qEE>w#3OY-q?!or!%G_EzRQ{|`hxYI7akvH z2nB=+#?BFQm^9tQ$hC1WjRY&UcvpKgX%`jW$r3ku3l{W^;T$LMq&-vIu-xRW*-po? zeK*sA%(dE11I2H^gfj&X1Q&n|nNy34GdYK7u)`d515rSZ$HH2hZH@vL)}pw3Sdmyo zraG~PVFzn4*(4It0@hsTah`y(1@~3F%4>dJSCQF981)hYhw0>@n?hJM@e2|R`n9A8 zJV8(k=!FGF+n3bN#R7C5Qj==-@Q!E@L^_n3Ia9` zQv&X60>UiCm_!yYubpdqBtDYEg);A?j~l&@FQ^1Nc2K}UEKJJY;$;mYdP-2aP6P}0 z1nO-!USwdQ!}q8ZEaxp8EIWJ{1{U=bbOXx>`leikmUEtgg^xs{0vP~Hgk=haPf#>6*FsF ztEJ7{<;{Fio1tLMH>2E#-as+?7s%iqZ{w5NhC16#)CdA9W8>JOJ`9CYvqnZnDiH%g zOA*x&;HU}pmYrkO+L6z)cKpHG!7f(q+y9%c2b2bD@~Mjj1W>8qH?s-9Apq?-0~c;M zVK?hKv4XLie)<8VXtKsgV;0&rYN85|gMoB;-2LD37@Vx?0{w89@>KZ2{rKC9pDRuTBM23@Y-tOIW6Cyu= z36u#DMhj$xNY>&+!#0gc)ajJFQ@sN?;pR2bs3~v=E~aOa?MJ)w-Ipd~yxYfUy7oX7 z72oScpHdlZaj;D3TrE>v&3KPD@GWhC8XT5Kh!Ahd*ph{5kCU3y_?r7A&)d%V1x6R8M5E;qfCP}jvQPbAw0bz!KsEQX2lp|Bj zY)mc!0AMhhD8M*pMcUOa!uU2HjlozA)2i_bjOi9Ap?W1E{}C@}BL5}XWzngFCvdvKyhb~@C|RVR)%j?D)vn;= z7PpvdOij_map{h%kJ5J*mmPoK=OZ%BLgM|}MbqG8Ued;{u?99=+iEiMBO*b@awy6p zV^k0mpPz&AIs`X3a`72Q-#+kAdTQb$g<OhA(XCn)I%VF-900O2 z&rW$)Te=E3DiJ%uZZXSF%x+QEgYJmG-w(Ah9L~vl2D+($Q2tJ<$)}D_*!@EB6V;C! zVA}#?9V;~FeL*?1O)rDCGFeR1EW}7R7%CW+A0M_kV~LWo!Hb&Waa=|)W4URA0AJLD z0o<&TS#kR+sr{H@LE^MZxEHeLg;8|jUM=HZv`MCvNYi+kUTw$%OkrIsO>9Mtt@WGB58 zVKdIdPc&TpmjJRYJRnTmBKPBp5#owMw*0zIb1uI!fa%4Dy>A3N7*%$F|AQZNbC*y} zs$dCE1==!}Kz**eza-W$p1>OO^OwY$hBxYI$#3v@(xc4kbs{%<&CIssko+Za1g1ag zxeVXisTv3A1`SsIC5$(gD=OSy!bhssao!0dys;Deu-)2makr-UAm3M3m=ka4njNS7GM;hO{EP@}s>I!#L6=_L=x0rO68W)24o zPkNL)VBY0zJo#VC0rO|w57>*z|5!3N>O0_X%&E+);jktZ+-!eXKI3LwK2vb;4KgyZ zCm_vVsA1e}QI*)+=tYfK^`L7)tQ2kHrqB6g_*C8WkjBI)8H|Y&2Gx$>v9LU=gSZcFKq}Vt>99(+uGCn%uWPJf>lzL8spg6lhN1E9>Wn0_fOg~|7l3EU zT5@SqPJg|3GUsyIVxg6mA;>(|YvF73S0@~{3es)2GWR=R!LNe2m9CApdGDizdJMsa z%}ZZk!`2VO%wNhtbDo5bq2^~W!h9Jm+2@>d?z!ilci#EupFg(z<@$L=5^i3I7C8`> z-tg*G#H(oFF4>H%>%=Oy8F^)PNNaZo(Z-Zr#OqvX6-uB>@`y`RZn}LU(^G5 z7o!z9`iy^fwNWF`fA}!~nbJ1(VI3pxk#GM+3Qzl%&M-uTyI zj(k^-`q(t2wlU%I+Pd1wG;j53nr?bl)J<0>WpDSgw!F*AmX}K3Xm0ZAN#GU|cbVr^ zcIc)g2pE;RD`r~?ByhKn#uol`8BJ#4dDKfH=TpU%8{ie7!MsECUT@JbA15F~tfM5^ z$y*`ADwYZB`@JpW?&{~jz9I-1- zU?ZCBdBeMIcyQ6KQq<(vX;D3iSk=Rgp#DBwr@{w)T!vbyQ(-^5HK)RP>Qs;;ywzTX zS#PtuSK%XGaNb^pk8wEBt&rUPsEP;geuP&XoF5AzkMeE>CHAcNalZaZAJQCdg-?0O zjA0HdPh=^RglmQO%3?@D}Iea(K#%8#NbQ4u6(&IV9vf!5OK`p@N)Q z!iY;OElOZnzW`UZ;0*bT!pNX(mw+_o2w(Mj#u2oujC>6o;cJ{2H&CT4p(nBgLmNgt zVm;U39|@_%V90lqC4DB-ze;^Zl9+WL6@o!k1UG&w_CY!Q0VMBx+^;AavA7&&R`lY2bEqj00d zR3}z3G-MT?5y?b&tjH|CbC#>Ts;LxoghN@1suaWC=-1X&&Ie4tjEl@G?yyLDFpn{* z>2)#Q+ZON5l%10jQRQW~dRZHp%78?drKU$YkPeT!p~Twdh8Hb|a@~fBe4?f3KZTgG zcla2Ln;xH))(Jn=^BW9;)5vY8C%fx;W*J1mZk&_N$^ud*pq>@is@ym{W_&Eh>~M4{ zac@$?V*sA4J@|rXG@Ra8ei)>pP>R~@kk#P#VSXRy@PcBfFB3w&$A@E9GIH@yQ|_1uaT3vO5umqw-U>7KHPJ0u3|vg?qpovtVp`TyqAUhVw^G#?f~$ey(9b(Vcl zO`X`kv6e+ya!yzamPY!=vMQHhKsnrjif%3Z1AS{aPvpb4rY*&bVOPv#smDY%knsdW zpq7<#o$Gv<#&!C#!<79>@EpcLVxP@MlU$lZ7!L-_nM9tWUjg6pJ1fhcnzQZ&IN5Z1 z4WD4h)`LyK&~*&VTz0XspKF2(t|+XZP0&uyHo34a(DS-ZtYV0#E;pguAp`@0lup3v z#yiqATH|)|4Vo70L z(%p@E{cTHYBlX5aenGL21G0<^>HyFx)R1q7!JGGj+vj*hd|9(qSi4xk){YejuRvx3 zuS*-EsvSWCwS0GYO?P4od-cdGiHEm$^27|a5}|{#BjMSOyupp$;8VT@FRQN*`ws6# zT{Op$awmuv<{MVyVqJ|8WD`Yq?ubP;Ij?*cAfmxIddI}Cs^+|@qT89k$;{uJOBcs(UD zSUFY2W+->&mxl(*qM02xLOUzdp0_qp#B!0lA*r(Lm=6Mjh`ww zd?D>R@=URtGti67jJ+we9rL$(dv_{`=+OXJ;(kCE78;8}NHQR00VTI?FXc>oA_R5; zXvnBDjoc^w*gfFCk;Sb=*dq+wd-9S2Xm?17vKR?b1}ya;EgDM&T1dBOP*gba4ILH( z?H*)V;SBmOshteilhSE-px0m^0Y1-;w_a0%bf#cpJbX|9@=LH09?E3;JdJNA+@0|nn9`x}W>QOmaUOS19 zyr6L!b$x}yE6^f$znPwvfW*iW`3eea`wsykI{11A+rO{t!dVv((V_RK_x@>>qoQJP z)3>C4n&4?XXQ+a2XVvu<5+pSrW#PMtyqQy3h!wgh3vWxPYPu6^*~F+IT+kQ-$a3tZ zU%2BUUOv1N>>mxGiTTZP)y zd4RO!*K9G#MO3>kXpDk`w~>H1&X{;ftdkl(j^`0*zlrEXbbv}kHYUWH!8DZXRuYF6IJdc3RsIoHYAkRa31;x=k zj6$?G#6^L#-ss~q7|F@$5{xZ}oKpNPjq1(8U`;-CLECCXolX!{NM7&A1~o*gNYE)x;Mf2Zen-=Kx&yrw95Y)A zL!%K4;}Szyc2GA~4vLEN^4bYHE~?l%E-Kd&4s0W7zjew6!{y^((r~4l3xk1REzRGs zt#UBBH{VyHV`L|DtM`=6;80dgQaJoeX$pr$q&j@Sq5y&lL8>T}Byw2D9iB_;P*&A} zoHyG|8G52^L#w95b!TKm!ML%}>pZ1AjYCKN|AI;;^FE~16-u_rj5YNJU<665vYlvo z2&pS#>+?xn@y)sIiH!--E|0=8T53KC&#hk2t$|~iL5gnLNjD~rndP5O0^udjxLhDi zbz&=DQGuXb2Yd7~!oaFdECi7v-H=tVOTjY*9SN&#w02|FzCm_=1CDvlqBc6)sUGN^FV* zbrDxpnfP)al;VZmz5&sBf(lM|SK*K;ucfL+fbC%|3<0>M#C;c*R*3*unE+s2C)Tm$ zPR>B3gdL09a%*wuVOVmSlxU1nPdT&Js#^k=La8A*U3==#dOrZx9ui%B8Szdl8mqD0 zW?I*hs0L1Ff?|bsD^qe|%wk*ujJDb%3@wU>yk<(n+9HnlB5!ga{EcFPp1_JYk82;5 zC&(-jJV)uq`yXWk;Bbv-r|N+BaJBdFW$l5=zn~@IhDn65S=tDD2eqZ{kLl;y~kB0rl|~ zF0f&P*tFG=z3Iw!|Ax1KtKy~@^kyp&lT}^gWBZ1pH91aLP{AAa!1xJCju8=F$f?6X zzMvBDVw_;eK3KBS3Z3Dov#-|4=eYTGKAg`fsIrMRmI$j@%lm5R;T3M6fJ3Z@Oqp{< z_DSGk$brot1F&`KMFZ3uVKRg9mRpa4B%=dW83OF`*q9JpE&Kzpu0);8l1=2pHzs7s z88s}RZ>cqI1uv)5u3(C{tBOMAYXKL!;rz?NWvD@zDn8I^OfI1<$qe{|E!mHXmdq+% zi9k!xusDu6(=kV&xv*!(m&>q+%&CAq%vUP9^I>5R7kIV6OF9TMj;Q=jAIz5&cNhn; zKv=1?KSPWinZPQHxlkR;D0Q%G$4$QkAi2<)>cqM`RCiG! zA@WAFEg&brGFrxTVpU^0+)BY_;p_8eQZ|)0S$ec0bR#r2OhOvbi`vIBG;TZ9VMW^# zZOO)?@8i;3<@5Neav7BrrgVt#R8g&Bnq30xK^nQcdQ1CDk}mHqCSAV9doLti{s8@< zJuiSi6!>t4-~+Es%bdbPXwq?zJ^bi3q$e{~rD6(_;T7VE?@o|~4xPzOAw-Et-@%ga zYCjISYKcR4wYNJ5&;x7*;#k*-4V${b!z1nO&)lx;JBxF%q?t|hQikW)VW+cG#>Wxx zmH=z@(Gqz?T$uKe7*1>cgDq(+<$5n@GFA%;@-wBq@MGco@?EsmR`bn3 zYBC)0JdsAgxp^>#3Lhh;5USOl`L3j7M=JL4bwC7c_ytXdOi&1f!c}}w@y-G|JA--y z433zJ5GgZdiczWE`S8gJ9bD~GdQ9nAuh0ZpMI~}HD&ip*C4ADmIbe~rsRB;5Snoc= zkXC{GKsQN3vo#zAv}v0)Pzch93C#p{%pRn#Y$B9mh>4^!*CV$lw0BDHoN}gjNIC$i z-2|TisDy)2XN}R+$so3f`%E{H*|cixO9unnkeI=wB#{#X%_#>rIP{*cEk)GFky+({ z?GQo`+wBAYstHGR*O+4Xjo!`&bQNeAgu}@gF{L4u1mH53)E0(KuU77+Q^8vzLfZIN zZ`@)qxrb--TNvOkQ_`C3F_|H*pbq5!FDk;g$-sih@B|&{RJFJ?QaxW_SSUh{ZLQDP z3*9Ovyn;F#^`q24w$1xCa^t2S);h5TfC)tke!G<{?g=DYz^1a8JE*E6QkufNWaNRt z%V-sh^Bn4Jg`q+$mJaof%Arykg0B`gB)V7ubX?++g}T#6aEoSXm2H)wY?Xcz7uV{* z5eINMVBh7fW-W(hqdasAnlkVg%YqhLpN|D?3%m*zzSWrEAB1SL2BivXQ=v=UALzq$ zDXMr5z`gHPYmq-$*NHVYE3J!7vML?zH|YDEpE`iCo?Md;X2B0VpbUPu(?r#C*qzLQ z+^1{sd#qrDd305ZjSZbxbf5AMkCT_jLmFX=fn#eyIgECCs4=$ccD^ClZwbl~qV^yxsZc(O^cDsaY{3LTsW<35S>tOV!OtqG*zAOyc%`TRpY(6>6G{UhoIhnOmoht-G z3{1346y54$Glt`rjl7#q!1*CM36p<7_)|fgg6gnlOV$xhI}%e)bTMo`62Meq*c7;@ z1}$926RH^6AldIp)u)w_{IsjQ9zav18U{v#VJqD)4OEvQ?!_)Pw?ChC?FEOeqU z6EX>-*NKq^Y*tONTd`-|ZQ>~x%&fcPR5g=RaLmCKO%HLDqI1xQLZy2wPrt(Am3|o! z9$X5=t^gCARInriCB!xvh(>Ia0R#-?57EhGhDsuoCKoi8z}ivZOKqdn^4eWV^>&AK zfmA=Za8eaw9VrlNO0Bf~SIF5tf%c4CCDEn%Au7l z3M&YwrV1zCQ4qZjEo@Ujpa>}oVr`zJdSfS!!$?*46Bz_2shXKFk}7QH!Y2wc@l+Jf z(DedHmHSn-I~t8T#mOIrX#}RJ)0x4OtwWVDE;mL7YVF9kMqhejqROT0>^(OB6)~l5{Tf z0LZY<7u#tT(Y=6AZnIC$aNX2(QAJsMtdMpGSC)m9wRIBvf@<5*u&~NO%8pmdPw)5! zZ{%xPXQuHBC`3yDF=H3h??p%9fS^E>to%*ho~^u|R6-=@2IvJ;oM8aC%$%@Tb3l`x z646Y;YnXqizzcgIPalP0i4r78Yw9Zmdoq`8-nRjf{49@Rtk=qeM1ML+-tNs9qEUm% zT7bZ7WB{lsxE6mE(9Lz4uIM(NM>lY?Zs>;Y&>Gk$X_Eg}&If=Xf~^$Yw17_$cc}%` zF-Xx0?@i4Yd+zjh414GcF7@tKJXSBuXXs_=cD@{3@aP&oy1Q1pI(n*5S!ToJOl1*c z)Tl*H089lJZmeL0q&Q1-uZ=V$bWfGo7Ew`7#wnFKL^pL}8@8uaq%jOS>MjWs!&tbe;!9MahU}G{)V8`& zp=I6pgLT6#WhGlxUCs~p&9R(~3ID^=F5%MRQ&%Ti$W03KNl3|lB-vrbYJWUgZK`gQ z;rcN!>B4Hq3bxv;fO5jCTe2QwD%0OC+Tp3Ns zv0RV5-P?@JPH0-4!iTX`(jR$5f%b&N0`YPEBk{?$(}=HR{gr^O1D{)@}(fDAk-&Am&TU4wDGV9#Bza9V+BKXRzNw1uw6U88Hfc4m!41Hb`Gn^W|~W-vYLdCXyYdaCg{?;)PO5zrMq zWy-bwZmw7vEF6+mW9jfwtFfFSp{7)^cKegH6HRV7YH~%E5i1x-S)oj}O?P5Ri)~Qb zM>%uhw&g9!`Mgcuf-L~&kv*R$+nFQY$k-ZsA>{m(ZgH@_%E_?Og`G`GLdahppwMNd zHFAjk%xA4ru6Bd>@yGMxYTub_ts4_!dX)8+C1-q;9Sf{p@2A5|O+?Um)zu*uE7*Fg zmwc>LM9AhdSw*BQ4_z8?$sVwZsvF@5f7p~>#&x9B5HolCwohi6Kq_Ca_GXO<5WVyW zJ}qt%eIw2IrgmQv{f_39b1{xUYwuv;UO_oP(ZT9BPTa(?FO2!3xYt-uxd@hNJ zz22L6NabB+3Z)yps7*$5RGC_^o^CwaIZyjQ5k0nf*M^Xe z9=FgJIR9fv;JkV^--1#tH03DLeueIJFf6wr2+i$gS82~`*d&YqFzVWm0f;p!&S+92 z-G}VoVJt1};9zy2Te~Ej(v-${8cZ5;^st8O*YhWo)_39<4CQbgdEzzZN=Jv8xs;fF z2Y$0*3Dh47&f{7>P+yr1xWDRR7(IC(a_CI5Ne>OJVTKkj$r;l80Ccls1NJX7#gxvF zITjTUA?Hy_wFdP>yX)w z^AjJ^^9o3$!pX4}E}!%=08pl2=UG5vyqvID5QNc@BtSv{Km==qa3&5HZh`h*4|d%r zUujZFhr**ws@`DDTSM!!E*;U!;BE}~DvOYfe--5 zf+;<-#|=0JJxL>`ZrSFNCM}SI4~;B%Ab=O4)Xgd?nn1K^dFZom{HHpxcXLE@puu=3 zOqyNU-k9y1+YVpiKr+V>#Noyf4ac`?MHdF&%9w8mUV1`|x6+7nAk{23`sgl_fEGQ4 zpk_wsEktiJDzU`c$pf|7mauZ&{r(N@JahOkaFjbN8-P*4cfXyin(TS~^K$dRG=&xQ!5A{iQ@ z21kd}CzkqQx99l~GDGPPODw|~(v)&KGB?aXUYMrO0TNtB2t)T?*uYY89{3`w%C`n; zKD2S;OMGjf=G!A!myH||--<5E2C=KPUbT?_j%D*;;^2?ZRACe0_rid7xLol+yZ+5{ zab@7(yoh`AgZYFM_oY0S;$VTi;Hf%zuAa_IX%P$3XOw7!cwxiXCh4Tc_+^9 zYbEM4&tss|R@kOX9jduTbfh&QNuf>QZ|a+k!UJ5hWey)_B;7d73&Y`ZoWjzl&aeN? zME3HXr$AM~S}nk~Cpa#Co-s4pwrBtSNRiAgZjiSi)UcS5?Ag(vGLLe{v?;q|>ddNG zmtA5z{PK3Eyj=_Ah*Ca^(9wIfqAX$fF_fy9#1U07>9fyk*QR2UQbaVHcHI)yfzP7K zG!CMeJ*czyn+a|6JXYKys$TJ)KCH%E@!41x#7Bs3AvRXo-c@QCI|8_~R@SV?oL7lc zFcFhOsGukmP&?WOw%x3*aa96SH~Ca2HovVdTt;{2UJX1{+G=NH(;>bUk{Y@N=d8q;7+s5(0&hJ7!#EEf&u$DdvG>4MXJo z9>0r=cQnQ;X)f@%vSKBRI!|JiPcePuL>SEv)L~IW!(< zJSeOj6RkyR&!f4X!QKO{KBkx;8^m1#G*rU0-P0Pl%xc2$geeb5OU$57v(c=r5wy5P zwByq<10G6sK<;JWHkfc=G&Ml8B2>`JXaqn8&;U4+Udm;+_$rw$m)%|~hD|6;#<5ZW z&59B5Va>zJp@Px2_XTuX6uu4s*Z3CcR}J+rT1BrG094}-L9Z}QK`$L>IeOJ&J>m$= zN@&AZ{}!Ld4m~~T7S3q#F~DR@3a=3C)U!alhtw0rP9meoq6EeT+D! z9_pBSLOY7!Jb0Lr&8t`$H)REY=_F@;C45X#pMHVH!*4cBe8 zf!$=q8v6;PXwN?Jc#tF{t{{~`GEu^S(Z=r}nP9$(CwQ;&$z6FwW=}9KOj&m#9m&ue zZsW$x84(!82t%Ft17W=!F4!IEis$R8A>-m5`eyhO`_O>v5U1fQtV)hzVFrR?LGlQS znTcY583zjpD!m(c*g~8*TL?2RYe9v_eckqWz_WhAGB{VNk!xo_6cY$kbFuFH6=om=)`MW=Yedh4~ z1rkgKB*@;b%}a-n)B~Rrhlhu8ueMwkc(Yt(gf;3u8Y=WBPk z_*!F4Xd^u@Jc~n^={|%_opcE2=7+#dz}Yf{O?4Xr352JU&eG0yIusb$uuPxs!PR_( z#!l4YzqqQeM~*I^39bV^sgQaDQ^%7(Q7WIQHD^#$7}V($deBw11f~6HD3M+=ccah1 z^rO>I2=ix1K&PX5xLA29_+1@L5ixU@;W&fb4uxBTQH1lt8_@ysd)mmuN$koEogTJ% z&$gfCeUVYAmuZhLX$nK-W@HUI0pDD$eXYghdM8iAz>x1H-D2(VrfpKlHj~?8F5rbN*_`XKbe>LQApJd;o zroKwCKJhKyQvifs{49)QSh6(61vOvo*Ed$!xRS&C1`X(>NPo%>Wj9;^g^!yrmVq`VJX@gJo;ERv! zzQVLMquwU+&tZa()lxhU0@VpJdJ#ktqndZIt8(((MOIBdGi%1zVm9YvHgdL3_BNtW zy#kLI|6>Z(a{NR9P#L6DX8a6p+Qi=g@k;FG$HAM%XlO zqBqaT%8@>@XZ+VAy;BX#j+nntM&4ojvc&;oUxTJ8EJZgW$g8j*mLg2M#+5VNUpADHmO1cAv_7#(&eN`mN^S>s(E>(_N+1>@{ydjrx_V%4~p zjg~h7A~BGA7qf8776rhSBle0Qa{pQ(Tw`OQE9jC85Ri+BBI7pDt;ooaz+OzJ6$LnF zCAi9(E{YP}J(&1NxJrhwWc-{RhmON_SIE)5!?5B7ln14SuV#xmfDKXHdWc~#Oiv7h zN*%aBdP({9B)IT79{m7T)GdI(^m_zv2>yX}#y-F^!|uin{I$V~h787`A+#GC@FTCgdMc1%{L`0hK!hBTB0R3Kjy!yM(D>9gqHJL2SUcx_JMDhPU}>L6Uw2^(|V{N z8^Q>rhLv6XG~BZavvVC6Tpr88ESgPGcQs%bb|VZ>rBJFj;NWrS%_vCgtV!g{rmAvA z0cyEp{$#4_ee&-R@{x+z3EMalM=-OJX9hmSRg)B7svICy+`s4|4b4AqTatSs;g@98@4$s~!!=mBa>Py&7y>=6LU^Po@R1lAzapvkc8 zx1?i5|Jot0!Y)!OVO!Qrq@-*j*762SyDtG{d*;z&Whg$s8-0FT)TiQRvR9V#3rszZ z#%Vl9*N0xS>v>&p0C9!u4S&^izc(O9)>snUgjjylKj?HeTZtT#rn=jn?Y_&L>cqxv zqpN-$AS$#=Y@zcqa@va(=tEMKq<)?$$`Qy1j_X763V?W)Ri z;dR-2uYF0#7H@%otQ{`yaM2wh5Hym#CjsK6nyM}F@9{Lf=d}HM=;`zH(Emxol7z4Y zgn+04(Qd(()Dn%CTKa3-2wJh#Hd@UqlFW95I}_xr{ebIm!|+Lr{h z=bX)DtvT1YkMI6{;~P;ZgyaP02PjShm!hM2dr@dj|a|IZnB9gLgck9LxoUw~p$EP0+nb&q=Tdo{ir2k6r z=MFsik{jvAg_DMkeQeui)0DBq+d$;dAV?(F7_<&{wE~RbJYg8C!w9`SC@1Rfjx#9> zNF=qBN|XtSxGoY(%uvZIk|*r?jwTZPyv2Jf!;k4Kd17ux+AUIpXeP1z-n1*{urmu z4WGXyUPG%j_Q{)9rdO>Av(L%z?MgJEV!E3_h53>qSS3CTzc+RgNUaq_iAi?A-PxoC;eU_#eG0EMVUj41G3er%wgGj*drb;U>OCR zepsex>d4DM&G~&;NKs(9*LGst4svWep-DbFk;c9y_2baX69^SBzjWZW1%0}JH@3bI z;Jtr12fWSc1is~OdF~PO@<+JFXu zCZ)Lm*lUCsa>$~ruqRdjc1_NB9?IjL@ZbRy$J|VtJbr~ll$KmZ=#+i|g^wc;5Yr45 z5imRmjKhPNLU=&*zNhpL+}$)}_29E%SyxY38jrbY;sqiG`~^`mtO1x|{7&I8v=7lQ zZi_BJ<%{(w3=uj^4w}MNR6!~Z=Y~PwU>i+diOwLK z8p04QJDtZ=iUvMlpKp2*5VhloX^z9 z{$?2_u~6fAo@rsKu&QvXxoc#W_L!2R9;17tjtC0!2OfncN|c5( zn}+iaL#}-OaYL^>6)i1zL@%yBsVEkF=5Qq$hjI@;7A-rpHo^RkCr06Ah_IEpiM|D- z!(~JM3F-}3uunIc6o*27{q5}*ZijhbkPv8qBnCZTy6K@ThOkatBD27&2cJ@hqcF>wx8pxh+Csyi zLH+`p5Q!1#UEW3&zE_DMH>C}BF@(u3q8LJR4*eMrMEEx63XBU@;QA<{Atg?HbL!$B zjKHMEuz|tchn^ULHEM<~MHN>;Vs+q`61%aKRB8s-5T=s50Nco5Wd-GkL@d~Yv}ua_C)oju1VGe-6JB5Vrag841& z?H#Fmk9WqgB9M|);;vL8Z+xigZs`h~k;Q5jNxw(iq6`VbOSn5Zw!RPr?!CuD4EuJ0 z*$ILcDTW1~BrLH0wYL}+`zwiIiNX*90v=V%VX>9Ia@doRg|$hK!vLH z5a(?X+F-8>x?M#k1S1$^45lPb<#3>XO_TVK%O-UWk%0s5@;X_+O^Ovtn^a!pJ)Ky3 zA-m*SS$>m>_5a;%(xH5!i-oIYdkWh^1*>nG=2#(52>{R2d6^E*u_VzE+PC;4ggQPJ zV^a2XVzW0JmQj0)j(6$i?FhUCWO)datcm!CFO$1s0LmX zv7DG4INf2c4Mcw!wyG3+Eyof8=%%Wb=ok1HE5wDcbvQ-C2BBc^JaN zJ>%oXCUC#QxIr7^xYHbZj(e`>xbJXg=WRP5Z88MyOE-Edl(9j@Hk_NL5w2t!f!#0!iwD zWoyoYs)#4S2D5%~KIa}R}$FOkM2V(v#ngU1ANPBAQmv6G~ua#mR>N$->g zr`iaY?|+=&`c53MA19!?5Y7~pC^`-Th50!Yp?D(W;Ga27oV2=%l6R4AobyqOWdJZ6 zVK2oBf)|Bk3B!yHid?k}61`b0*Qa!x04HwZ98D^gx{?F}Tr3z0lxXZf=cS{(*lgew zVh@AoyEhyi4qZ6aWz20Z!R-{1_yHO`gC!*$s%t3=XUqXe+o;FaP9mQl)(d;YFVg$? zs~rITZ(sbVA@1$OnYo5&N)PrK z8lv~JNDc4~p5hBaQq`h|#jpN^M#C)g`Cx<-R`_)deGYhhs<1;k;F0v~`F4o%k0-Zf zl>AE9Bf}nPv$RM2)enekkHWfJl2rc6dl|yMgkLSwFn{&jT-o0T zfAy=1xfbgaysnSG`w?*dKAoU+dQnjN)=u1Ahf?!}8aqX;NE=ggn>+3>Fgd^akl7`-JL}rnhxb)5G<50eF3Sk=Pm% zvL7YNYUr$nr!?lp6kvR3X+YDS;nABq;&$s|C zv~X|UL^nn40g*SB?0RK6d{7qLB@Fm;p}QpyIJR(L@dLi9%K(q%t?O7d^k1%(LQ{r! zDEuuv?QS=+YpzSb?%BO3+c-;DvVgc?>;sDp_U`0j#AAwm_<#ZLZzZYwPcOE6|C6Zd8Is&&^ zY@^+7&EkEFHCKgKvFI=|cpRJQI-T+M2$zVGHo4yz zE>}VzS$niSvg-{T1=BR??xObC4h&#~*MN+8%`u%@w4geS&8v<8;C8O&sIdx|BSwxf z!$+;&TI`J{y2<6#8?36M?UwZx4*d^WZ!PxL>gp|q(kpHYt&gDF5E;gaYZz#=#bLA? z+!JhI&qc@^!rs=2Aa;*s0Acc!CvJGVY~oZ+v@v9iIjtm?FtsEg5Q%p{px`}tXX+r` zQj{GncEFRM6vjLTL+r-WY%}|M_v~e>vi7p$E1untJmUHU;XnE zA1xp!Bm5(Bp3_{pNd`Uq@5iwJenzvti6H;fQ~!8PyN)71fnO{v4s}_@e|;+afJLwC z7ya+Y37!N#$@d=WjA|FtfhqfYumM-VzFN3rVgP4{ePrXcpJ0PA*+3fe)TMXhK9g5Z zSPoDV6;xkmkPkuyur496Fm?h$Z+5|K_SA~qJF;u9w!3p|CQn`8xn{SZ8L05Y#ywPY zG13Gn`hE_zKK(!%>}@mauG40mb}6MF37n0~wxIc2%*Lk%0TT6HgY$qygF?+J+G7P3 z%G629jlWU-0akkv?XMT$f?}qtdD=@z(&scMe;g}M&lu#*ZlIXdrVQgJKOQ22hZ>q? z_2o?XH9{Lfhr+2e#QYBgLsA<655}QESd&qaduu0-{R1Yom<);S;ucAofC9)($ChvU z{L8NS>G#Y%y0Ht2n(gMC*oj?w*7R{bvGKip`#WSXsOqROJ$KLQ!S>+Ypq)c^uWoJn z)jzoU$jF@!ZoGTb2d}>Q)KCB7=Qhr@TX%07_}6#damO8B)G&LmHuv6k^S$rwx%PD|q*@B|e5!X*mW05Oy_tNW z)A`O*HRoP>JB|UlX5Z=!s*e>wmD`;_wF*RVo*>k5 z5HW9X0ue}Nf)3l_qZ@yWG$t3$#Z`x}y5o0x&e6aGbn4>fN+AW;Kg;kx{hR_ z_bNXgR?L+NF^Wm&kmod~0_YebQT!0*r(bF{A~mUnbjth>T3y<7gzk3C6Z4(YbS)Vw z=Wox|&SO;y7+G6HMKpWo#2|NQ&{j9@&|5lj&L6TJ%0me%5fwm52=$7trx;_6_?U<8 zv?eQ#F*_QiX$h-9lvX#K3qf{$GuY4oKq$LFG94vLMh$*sxZT_-@>D~%%O=IzW=8RK z=WgXx>eiOPjW|M#7E^5xzIS2>leIPO9&FFC8gPA=s!oWg%Bv6nCj>JHo_d4N69w?$ zQpOvhv(8O+$wX3?ahFx7;TfQz_NRO3sKte#O0I+iJVFrGhscIQ_T7i_$4RAdE7|OK z?c|rAe}=hm%-#i|uR{N}`CrdtuS?6=l0&$n=G1$|z8&W82uF)wl+2(dP$Ob0bvLrD zG&5y3_w^f*|J00@&Fl%R1toWa4()BtthF2Z2@;SEk8l`xSn+e4~D89+8RF_`S%o@(kk zU;&^X0jZRX2C@dz)-9b8G_DO~O;(AjhK&x%Sy6BxREye? zY-EcZ6kyIMe`~ka?8Lp$TQ=JFWqbEvG5ui(59n6E?8!~otwYLrE#IT5NtHWhEiAmpW_H?MD(HK&_Vw9m*8`1x3{AGN8xuBr zOm6x7DB6POYqCl8Xyf@KaQy&?k@mm66VdM-#iWwYG$DBMe>p+`r6>m`fcmihRU7+E z5rRbx3XqEO5CNA$2sq*XguvQfAR%CL{RzR+rq-Jfu*d#{U{O6*5&|wkH6fS>UTkX$ z@O2D?AfjK15WHt-2@(Nhf#;gAL@R2%6Bus2-lD*F3KW1g#F><~kHKehiMk(bJsI<~ z@^ry#0)f&lOb6%Gy*La7b)VRDwqpl=ue~15d#khy5+~$I$OZQzfjZx<_n&YMmkJP5 zg(`6Zpx-I8QeZe~o~kx-FcLJkC92_jQdMJs21Mp+X%AdU&5LGECgKLaEw*tt(g;1cY)nv*-U&Ke(O8#jVgtVb))(+&eby5{rn>M0p`r;t7!w^hTn|-{<#YI<8jc@THG1Pm zvkO1qSz081G|TwWCNl7tJ5=NzSW(7=xFsLWV*-FRVnSP(u)c^1RV(3`P_+`k0IfAX zfszRmxPk!_D(iJ&Leb!VTPKdcCngl@+@9)`FyZ}lzg6kZjp>E_1D>&zK#)BJv``>O zaJ;4P1~7o9YT9;k26wo%b50Wv@>mJ)6l%#$J+JzPHdm-k@(gI6MK#jHJG@O-0*0>7 zruV3Qs&49yI#lNxybMN*K7t24aSwuZQ4^&>SwvjS+tosBBd3{36Q1KS1_^ ztWk_wGWe$osc;Tdhe;(9BQzbDnlxFFb5&!G7;H0Jc73)jH~MCV>EuSQDK+9788Bcm z>La>k;>p%6d4&vWoRIjracA`0$WFXIyDHangF{I@H!zS~;qZgzR9t20U>sFH`P7GO z9uSbywt49yAGx&?AEcDGesJEjZNh9 zM%Z`&mecT8$^5a0Bpe3`3`2D_#M#-~1*tLnc5c#t5UK$&-Q*(vA3_n%xSYipO~wi8~iY$vvJ81gB%6Q9~nd}0EaydPExg1ELdj8xmIoc;C6 zZRHAW%?7$r1~#Y@ugCI=f@9qQY1jz7#rK3t7%Ye^iVczo9~ou8NzF5-l)w4tV* z7aH2Gcn<$AG#obeQH6$PdH*-+5lf@Ujp?d?K&K~awH|@ByiD$tQ(tfzFZ${c(R5RR zWUofiylLKW6!#k;HWG>_G=nBU0u2skbtQWOhU;ryBs!e!4NMs!j+jC)2XOT*>Fhi0K^Zq!5nCDKqwT2FiKI1gpxa8SaoQt zmpBMI#c&eP|5nyuIH^5xD2*L(C|DP(P(&UDpCxe3jQ=pZyMuw)#%r1C-Xa9KR@MwH zQi_9LAhmcBio;oe>Ofsnj=W8ckD~y&W^06TkP2IDODzq07PRInQzg*YSz+Rm$)$B? zC&Eo$Eb3e5u2LPzL|qrW8ZxDR-czbmR^y9x=1O&vK=gfwe*69p`q2pXzaRQRv^W;@ zi*U0D^efg`2>KQ4ECl_EbrSl$W8^qxU# zyv2XRf}MhwWY-(xk_DcwPFP3UmU-swnvrS;?)O&-yF#LRq+J&DqTTS_orp(WbSdbq z6eWsvezjDmOqYsv-dn0urc1>-_mt`+x^(mREnV9Gy`xJ`Zm6sSxtgm7NpS{p)TcnJ zj8gp{di3vs9zpu>Ymch2++){ezy98rI0kwY@n;eAs90wq^r%>8A@rzNC()z#k0JPV zc;0goRrY{|zJttkXaGImI-4R@?(8l-nT(5H1GWlV(Ih!M48xx_{|#g9Cdr|*b0}3%oO+=i&y!(*y!9-9 zMoud>Fhxf@%oGSHr94)r$(Zd*@y)K`W$KIrfI2*=8>`cqk82zY&7czPvcI?5Gz37<(jZE;DJl*lC;{Gle1U;sm2M(#&AbS; zcujittuzLTW1316H5zsQZUeVbX>e0+ilMB9Tgc7Qys74Y3VtMcvK}Y@%Ctb z(M)tuzHd0Y`z%^aSq{M_IKQG}<~KSK1DyECiqJB-H6dc`ZaX>Z4&KSa!aefQa3mrHvA zenV#PbMXN~_z?Pr|E`6qa6S&afkzQ#l)4bVGw1_w9haTNk~=I+Y+MN_4yTQte5w|{ zUTqMq)nAF#4>nYM@4YQ9IWA;df`OLX;wIU+Er&}>Y_vL8rzE33P^yz?^(U7{j6)H_I1jN5w?BlG3&Apc8VR}x`I@uOIrqF5y?AQvOU}Pw-Gvve zzxbsu+wk&BHcroEATT|Q$8!Y|zX?Ti#$%pz#f!M~*LGqB&uqd9bS6_6IV8V>egBZY zPiDGaoaFaXfE7x%ok^S%nLs83XG31{X;M?;4`d(HRtGHthYt;roU7O+REe2aj8tCq zv~8?nCDcEhf53k&8GJXO%)FYJF1|!-2s3;ALAZKo&Z6!6rRW`^v*F`N_7$-Xo+Y^$ zKa6BA(hO+uU61D$uV^B{ya*42unfUhI0pml0gk$*6R_*XvMC&t4b87pD;LM-3-mmt zR;dA>uZGx)&J*y}OH$it_ZozPsrex_KgE7o9AtUU$PDcRQ>eoiqBDO$I`d+-LUVI_ zgp@H37BuQ2RF^65JkD@R;V`u9ou`hu3m+PyIof)pJTUL-4rx6}k0>T+nP{e^%~+-46+9vSjb_6_5`tVaH?&E(;Hu}|huvEvijldDB zEGC~W)iDm1>jxNH2xR$8sZwHLf3XrQY)-H0KYZoZH~wEg@*my={OZ9K-&f#@ zKZ>HcROOqEtC95oM}Q!>&~z79V>HW~jH>~gn=;-02+2m$e161##sx$A`HkXeEbSyn zn$Ko|KclU-q95rgQDjj6o{N{DfB>_>Y@ynsJ%z|TY3qh>_li<+A13z+O!3H_QQ_ z8x(c&^<>CBM{^+{Wo->RrrlW=o_x?_?NRNVBqfSu969Y1CuB(KGT2_xM(6}`xs2iw zDMx6K7=<*2@!{Jbaj*s8Z?^;tYG5rJ;DW+s z($@LI2iXh-I=m4){S{wOo`YY-_R23 z@e*fq@!(_fE+1eIl-xp>U*-!+Z@Dfd&Zs0TJdkIGD9`8_k{nQUXyyy71$&L-XnVP% zSP4f-25Kxu9Bn_#ABdyepws-BXc~3S`Ox%x(WhOY_8HEa;^y%jLWs3`Ca1m7K7k55 zVZU1r|0NIXj0+n+&sDI%B9r+3m@i}~qxl2}Ah^$`;sY`h&c6^i+V~jBg|FBEk|O$t zoyepA#A5nS)hfd*1S6!n{TzFtATBKt%u`6uCm7%O(FQ5Q%TvKYG(@I?^20>@H3y+; z!k>>iD83*Mr);JlsIpV9zm#o@psvmrjv-y!=F)lKe z=3z-G4|BQcrVVrfIhUr|Es=HoM%AL_GX9^lFb{|gMIrwPU(vqS!b_L(hi3E^r@UH$ zO{ytq5+G9J_A9PPhE}nwJ-P#w7_!NXu#PEW;<8Z&FV5;O)2v+9r;5?P&LgEdig)e1 zdVf=@qxkc_b&i(mm`;)R!UCi=Yts@^e63W?)QY?+Qc>;erD{pBc#5{MV@cK4nC|xv zg#8O@_@kAJX@i*nMCm^Ywyu@I+6Ad!B0qMjhwOf!AiJ+Y(cJMw9>2nioJA{EaElfz z;6#?0Qkbk=`Ju@1{Ph9oliA0R*MQLw6wbl)+IX{*&kT(;rq_@lMV<#Kw$STrr`RjQ zRj5ZO*9%x?6aNj!uEUs@atk+>TJWB_Td1sibE&TPfx7UPz|S(MNR~Jv&uhog4Fjzq zvhRg-K8V9k$Zt0Sd}YM#DhQs}>}WR?r_2Rh3zHpCQpxNNBJCSuZJ^}WC_bU!ZggVx z_TVHW1Rp-(Cq^-Y4C}}gYm9o{HK)voSB7{nQ+b}Syh^v0X1Y4A^RUkp-D)PQ;&h=m zQ7CR`8z?!^=*I|Lnw9+mw%n~HXrQ^XfQq-Lj{ns76YGPk@PE8#Sx*EqKoj=b19})+ zV~i0v+s-;~Q`Wc;kwg<9!h14YT&_c>h`IF=sGl|W`dJ12MrMXhKuN~9@URsr&bZA1 zD`@9sifr{=rD3zC4}09f0F7cZHFO*ns1fREE~S@eK&r**cw+pHGIM0>B&qTpxq}F7 z8xtPDA-*vDVJND0ww7867zL&{AdLv;kP*e87HBR5e+YHZLY%UdwWaJbgBD)sT4J;j`ra*2qk=ue5&Ocb6e!4`u-7mb(Aq8F z6ptEzB&~sq0*L|sWebk{#=Kdq8q@v%0i#3iJ9Fk#xpFYX9{lXS0zad-*gZ7aks~)K zt0X}JWW^FyHnhH54k|6Z(w5Tr%-{cCg8bUrAZ4WR_7f(b|GGt~sy?;>o@ko_ZGM|{_5YFIWw5bS- z4?Rh)0=c(Nj(Jl};G>6Lv z0RAk3OS^r27(PKWcDZXK=;->M1$OO&&y}7xUa@P<`b|r1WA*KCfnDUOrilrknHNa4!sBI&L58gWHD| zhugo^1GjJLkK5y2xIJ3N?ZXA!{^c@mdlBMx1K4tQ!*Tm|;Pz+UX zHQ)Wwn`k*J;`I6kFy>%(L4TZ%gY1LTag^}h*(h(%HQo>SNeD-GWTRa;9lKlrPRFj} z0=<2KT{}+aN-qGXbEW%DOKl^9tX9ia=-2!__#AH?WfW%YgaL$99IT_XIfBMVq>@U2f+e21EwtTPTKGBWLFO2z zrpwtdC=1_svk&vI@C1b9W1f@HS&vyT`_{dyUiXU3=$CddY~4l8X>>Ti4p9na zAlhEkT+i&cYnoR}xMhxT7|Ec9+PO_Tt$>0oAvr#uP{0D^9D$=Ius=c3*M`aGmP7pk zMMa=i&?PXGZ8jp&S{lpH!ByS?EUKx$#J}%I?Y?zX?T%xhEV)g08(d8n0D~$dSYf=T zZf&E0E@_-<6$J6k?Rs|j&?yD2kg{U>YTf>D6%)y!ojR)2l02E%0XGgwenK_}GKODXSlXUo@U2K_3t0i!P zqPDfW1G_j;9k4&#K%#z75DNgMg?bS7o~rs#cJwo_T?$jTK>s}h%_43OZwLXHzvDjG zD;*4FkDx4n~$;)#^M7h;sszz$|-08~OkO?-zS@bL)?;hd}Er!kis5AY$#d58Gm zW{AfsavucAILLSq&><5ahh`Hf-xpIZXu#8STef&u1Pt?!&K<9#pT@R@xNhV^p= zcGVRzc=E|7uL7$Aqw=sp1c2jjl7DN~oXr4252IiRA^tA9Xg%WyJ&2ndz;w;bexAL+B~g+6-}1u-Pm1QJ9F3YA)U z4|uu_=8l8egj`Ty5%|73xud8o!@m!1ta(cA{(Cn4ipmKD{6LSwHK)cP+ffW_N6fMO zkIGPiPS@Z)q9{O&(>l(kxj$%gM|=UwLZ5XuAaRhWHO%)+V-;t*U;dMixtKWT4C4L} zZ+n0*!gvqy!4P6%TEMFWM zqbzLkZKYvcQZ)=lU)0ZLFJUY{5=O|#3%u2Kvq--Uk5M+U_=fC~+(>u~x(fUs{^;tPcg#G|-4(3~OPeF^H>pi=j7 zB}qAo(%?O*YnKMuM5JYyAxHZpfHNX=)r>^J)Mc90`%=>`5UzEB@X3}W!hJg1`?p*; zhOnp&6Ly|#(W9U)x8VbL_Yg)A;eYjZoA`Ks7%n7qcTa*VYO zg%25VThlxWSPPONUyf%-gFM*G9t&T4iiQjsK1W~z3i3p&TQ+O(1}1lL;)t`Aqk^(Rvw4%hS+7S)}Hd&4!fj1pWw$PppzrW@uC z2bg;}2iSbMNS)`?Y@OP_l)0Xe&0Z=X`|QT6;YUvD4vICABMVI;CxIzEqzDV4=aEp& zCwX*%-Jh^87!U|^_-|n5&-mhboX%q4?h9$-9PZe}ae=!prluY4o?8WXiY$~#L2xJa z4D^)hA_?hs+n*!VaQEk_4~IMWTT5{FSZ}!7UIBNC(1Bm38}5z-xO*%IcYL`>g8G-- zC)pH8BzwXgd#QlCr-h=5EV|?jFB>~{z#ZrYfE*8B2`_5OllJy%w&Vlad*fzo$d7p0fzkZpFH5 z0s#vt9@BsBg45C!>p1uM6l=}DOR<*b+;X#+_!p4RMbCrT{S>{!_zv^IG}4)U6>8S} zdUXe^jf(Ya@d3s9HA`2ldGClSFus`V_aYZ0f3(#09!xkRhqmzpl9*0aM>t>;Rr^_;69 zvxswXQ4s2bx`rxJsanUC>!Vsf(OVR(Qb8(J>xY9R2yHj2)_l20Nw7<`?hJQ}n;qkK zQmG{fc80q=F9yz=YW~+39dqinsIZab9vDfS?1I_EWRf`b!L*?ZQm+pqDTJT~^b59G zJQ-G&)$5C!+fC1L(C({VFBrBzk;dCcypp4@vLG)|z3!vtEXt+WtzP$p?x5xrp!=NW_Ad1r#j4fo`MF0VR`UrUU0~N= zya7ag& zhI+CwZ_fF7s zvuiuC(a)HI!0_lb&9)g~CUZ_qD0pO=a?4KHdxl1#@T^_X)rOePNa?0Rr>R>oZ4DE2 zPylFK;1FXnm=bFM0Z@7W>fSUE57t5i(*V2@?bVIwF;JEb`hjV9tV7UdV6$wFLl-yE z99h_AqbS={8Od!zWt>*QF9E>0KBf$s&QgqMzab6hk=p5u`iXW)=xAF!-`ZxQXWOWo zozt8~+!hD)9F2`W53T`M1u;lQ-Dm4^MKMI2Co$YmtBkNbd|`{3#Px`R)U}JQsJEvf zI&EhYMbjyL!ud&KySkM%Zl8KgNc@h}vXk}|ZaKY5((-Jbu}So&G0lhoz^EC#z?=p8 zTaOQ{FT{!pQTfi)zLRwxt|(gTxAvs!>no%QhIYZ2*Db`_^WlSnj* zjB0y#2Qc5(xB%#YAKMEe@_wjjMG={iJVFTH=3FojaJh&37j@bIarAXCV*?R(RU6~N zFFk6fZM`QgyOUnnAhXASo6-3fP=e?YpoXw_^e>)UfRSHMjon%of+Vu}*GJeq|Eq6VH(5dBwGzSjBmT9dVlFSsu9$xFMi?tczEQ=OxO_f;MH%U8{M4 z^f}(VQZiN$^@(DUZ_cJ6e0)UU&q=b!l?e#*rc~T_C087b800)ko({gg_#F+*!I)ec+?akhQ6o$t4QZeE zaqrCdFHh8FYVF#yYQ~-oEr9tEEik2s7W+Um5r*yaV(>Msu=K6DF z&X2KtX!s}}Qo~QOaG=#s@WBd3fWta)_?Vdw1&fiHh9i3C-_ye0nl|sgA;B{^CR*@K z5ga)^0UV)aWJ`&_v!4$(oS9Ce%))A8Gxf1f9aJM+nn;=fTG6c4YIVWXZ~>U!-1%If z3Jy#h55o4br;<(WE5Qn*A@qi&B69gy%*sDgTVZtTZ(F$$G%hvoIF~u|E(#41r-rU6l2f)ZO13MKj^h(OHn_0*3{ua1APj$azXK9yx2PFp*==32ES9c9z}{aP0vTiwusw30l%~`*lW3Vd zg*k5>ziyPYz$=J-*{C<$nE_4!5nqQH_m)olj_Vb7d(?CAcMTUUNe0e$$fgJvF3r4kj`@r z&Z1Z@>!~TGv$lNJ>o3M1a#~wb>zNFHb{YlgJzx1M{2|4s<@od@pKp94^L+k?H~q&S z-S%TY_TxYP6F>QrKlRf;{WIIQ|EHh**`NFQpZ~vq0ZgTb?DKGeEMA48Q2wG$2hqn( zNdMVPNc-zN1PJa<@c{NUs0-O@o$;WG{|liIwQ&kg6wfKUOf+VgB;eBYx zV3cAwg{N+0cFmuIwF8`+)vrWy2bE{`p`Xo_uk#95OO8AM#W4Gt<(3>pvHui`WlZ;H z?brqKNW8C6{7kU;;-Qz=Z)dgn(T{oEb+?)l;(f4#BX#bIkr|cw3h7wPyHAcZyI$_QO zPKD9sQ6NN>pmS^^cHuh7?{jIye`q6q-SHhUB;yJh^nIyY=a5^}t%<=vKW>E%p85vi z4dg;fi~L-qk@hU?_G<}>Tv}>5(9f^#7NE`gLL;q^7e|$JECB^2fF9eXSu#H$ywW0# zPK?lCKAd)a;Y*a?U?ST z7}*N?#x(F(pwcL)6q;fJ)UkT@RV4lrt^6AMx*WfcW&djVU-gCuzebtsbwWR}7Efg3 zvpvdIzr<>n;x`=5=Cg9Q;#vWuA{^X>Gu)%?ksYh?Kbrm5qv#BN8fsfU2M!eRW3-=j zArO%b`v`Jj>R8cz@reWNjp*=1Q?cfhLV zzSt+?bqlGB0?sOc_i$>$f!8iV=+@yj6IM%599E$e@bCav8M%17!P2aLI7prJI=ous zVFIPQ<*f?+03SVYY*m2I_fXZeS&JoDi{AM^OpEI~f8lZ3`9Df6`_ALah|!WZ8&Hj}TkNKsi zusnI53}oSRDbD1-r&acJ)0Qk6Je)D_RNeju8)j$->Q6y{;wDfii)pL{r$MBU-^Cs( z#pp$IrT;ID(1A2YeB{iwOOZ$ZHMQ(O8V;i6fpj;4ROiqtfb`!|6Aq+wCKQ2mdT~Jd z6c-#}DAn@FbU_|j6m5DlCu0dfdkf;|;rIh-&RKZfo1?1c7Nq5buA~{wmI@S(gWXsv z0JD6)g_}zS6s(rIxV2P3=e|;b+f#viEH`+vW&bWOr5XIbxReG)s5jNz1_cw;NbWAR zXFr=+yb!&{L|!LZf|OJ7_kz>fZ6%vliWFo=p-GDOtG$>vtjQ*YOV)79nx#ji4@6tA?7+*@Xg+s`gh+fUK^>s`FovaX_f8RG{9I z+Hh87nGZ0A93S0IR)v5H8GycHQ4!`^7ZGjWj{u^H*EF(p93R)^U$Fbc@O-R!Gl z*b>b=Tiwiq7Wh-OUJcL?8kQ21(YSFYC(4kN*?Mojkq#2h$^xy$>L|w zi?b)R4d%>&59Q2(`zpWlS6vQDm<4^;-Shgw#amcrPekl83+D3;m z6N|geGfRT9L#b(pGMKB%P$r`kZ#}89E`B7n;ZTNqgi8X^RSSkP5kX#YcWO_7x+)1o zy&Vp5YO8sl|wkb;58fp}=RAIx9f2j(Lq zTr9Nb1%)GN@~#I!%ujL8gxox%4DttgZ#nMyPg7$a_gqj3{yY`%-U=$gmrDh@!mt-N zoJUe)r7-N@TmkiA=xI|Qpb}i@Dgp1EX$_la+HP15seMnv-^rFRu{{B80C&$o9RTe0 z@Ead32>QBwCLVDiA&G}e=#cbFWoGNyv*l~yJDJ3k>C+Sd3h$E6n5_3Kpm5L$=-w1_ zXR}>8fys;=z%BCM`aKsYQkQd+LLM&44IDMPBOu^JaIKQtZs^3xIT1TuIM~fmD+~-q zJ%Ft)wt0_96239D>@*B6Bhj$@c@19WJJExk-ke%+`cRcWNw!a*vU%+uS(7Jf6||5# zMJas}3|<=9F_}K;@&}_f!m_v{8T*o;`c22Vj+A zYjM9^?2ZsZsIYKH3&M5tRSYVBXWE6&n_|Z%yM4>9%YjNnT@Esbn7g2pK6!HG;`ypO zQrphiaXs?Dy&1Q&$l2+tXL4uJ?QQq~d7Q=vDC2q^tJ0weB_Hl)_XzRR=1v<)$2~V< zUlhU7)xQX0G$ZapRP^?zRrfeR3<~X3A80|0!7ikz&`q82`~yRYpt_Gnw;&;tG=aY% zdceCrdBeqkLP2otF|PKss#3vtv4-sU@aV#smX$AcJFpT<)Z&;QIq5v_xC5Fw_sNxMq60cY9QBABa!9cVM%M@K2}4E`@8Qh=mL+SNG&58c<76X@$_W-V zq~xBVsf;I7dHzOP&9J|;6Q=3q7%oI=TuB!Iv&vIRvU{)WI%Zmrc*zdmRYYf@7USi0 zq?FNC{!Ha&Al%2y=qu4gzBmYqjexCe3NcNT0BDQHBMy9IaMsy7ssP1z&+dLVrpk!^ z4_WzPLlDV19c|L`ja=X|L?MqrxWzGClfz3KG0qS&KOpx9i7s(E-ex1YLhDY)uq7+CZ{#NYHre25MCh&F`HE@HnRpI6Gp@dxlzZyjl z{GCmB36O1Y84$H-gOXu^2P)?KA>Z`t4th4ASR3atK0gF_4~NK>2JwLL2@^p5P<6CQ zk3Z{KC(0@fILA>yjAaL8ub*JRSyKqYp7<-Q z$S_>uA|%ebN%qu)n7{+5IV>Z5;sWpvSr-6xbQiCNYi27MVbj1iJbz4~jC4W48&=TL z_jcmY6E9~uk*YaZUL#UYVQ@S!4SgA-z`zEH*BTiZFf`FQT=4*t0xB5`CATqTw4=-% z=1MV3N*2_BtrmqK%@)Csyt-jdR~8SW%!y;Vcn+x13|(A=OZsr<7JkIJ7Q6+ip9A=L zOESd^cX%#(g;oalW~oh51)>eLNlgHwM@T2$l2#C38q&KdloLUkT7m;Sj5jk`HiJQk zG1M*=z!)Q~ya3P0FUSpqJBpd@<}BVeX`(+UG12Z2AsjJ?SNdN8ov!P|;W#>-1+Wrs z*tL3uYAT9@4&_A9Gsbkc9#lBHvXL35PbWAA90a^qz+dsuc~tKM-E%YelO!34lz^~aq}9~#o{ zpn6zKn6~CXe#kPPqZdwoZ1(amG&KM+PEk0J&qRJs$6HwRFbdGmNPft?sacr&jLelx z-*(@~Pu2F%LwXZ}M}XR7qa!{*~Tes$_)D@?i8JboZ4ik76`>gqW0$s?a2c0qi`g;jQ6 zm7Ls?o+l=FNlLSwailvA{EpQ=!zHmPGNEFq-t1!VL%yj|0FdCdGmDg#lhI^zB%>WrtnHV|T*t zz#ToK9h@8hT>>#P`3TX@JHaCwSP|hrg$SxYe4(N7a#ZR)5RO1sA;^;eNsfWHspYhd zVhsu9P@p_~K^mx)@Np9mQ4a#;HHmqU&2xlxJn6vAbD;+9TG8)*o(uYfxOxWuyR(>>9>dH+;;7+971;!+eek@gcXE8SDfdSCN z`XcBd=-RVu`0Kig4|f~&rdi)E&@84lpII4&G+uU_mz}Te#0pN8SOGH>1drt|TikhDX}7W>!`RS9Pu+^fL9D)-~Hu5Wa6n zBmIKeS#1R4*#=M^g7GF^h)2E2AfkJp2=>L>tKV8`a(GN*rzWz%VcnA2_@WJqm1$zx z#9?I{fNf4?2RPuuG)v%fTdBRKjj29n2@&=%A;Pig;En0<58&(kF1`u2i96lKmhn$F zK8k-n=ed^XjLL%iLYPPop7~?}{%EUmo~fzZ&FQ=#*=fhDe%QL0VG z<+sM$iU#sUBdeSYsG$Bt#6aHG$3pw;&G*8)-Y0w1s zZGkn#Wsh~W#z8raNNzz|n%z8_1I~dkB%#FfQP;mdZ!BBaZf?adfKwTc%!tKn;(%+$ zQaDE_{v@u?wjWl?_Y7hKNmxsO=BUsMr>i7Y$j!aPWHJp|xJd1zmQF4qx*iy?wDe%( zGBJ5I%1CFQm)iFwr@!8b`|8vlfCj8(SRYr}>=zV0Nt-G6td;`+x71%OzD|AxLl@iv z5?kFI!ZTc4pcxJmx+H7~Ywf2D{(JCDw`Wir6KhmKiM3q%9Kk8^rw^A#oFv=*q~uF+ z(*om8ssZIpOtq{e%jABgpejf&r&ak*Kq|)wvoJBO$^mlp=NOG)xFl{JC#1k?3*fW+ zGfAy2@R&xhYn-e`vmO=`;uY2@fB;~bXU$rW*&sMVN^B3&Jp*~sQ?#!x=shPMZV z&3r{5qLtZ@mhuy*Kfy^DOWPFerv#^-xJnIn2vvYw{0c|Zy7o{WS2-lo?qD=Fb0R%y zHPE({ug2)}bxc1wbPVYy0U>Pyh^sO~rQ_oy#@OW^1i15I#;wfM#yx=zEu1qC*P;Zl zO(GmOk>*UKeZR_2RWooF!f1UHz>|L+m@2qu&*jDR_Q!i)G5aTL5Uhtim0E|+7Qb=% z;mRB!h_%Zep&FC@HY8>mOM}i1NZp=&^L@*AW#iY=?MPX5b2hj8Hux5@fxW1LcMuQg z_##mAvRQ)nwqK#}t@yrazJe@{iKOOr|PA!cA`urlw^|3$j^g9Ii{ z2H}N-oi;u|FxBK1%ntB}H>{XwQb{_vwKP<->I1XU0&BOmXpp;zCU~BN352iTunJ5N z6A5Fb+C&izco736WVZ+t(@=7A2*z69{|FO#F!1A|y})2I77kvVcGKjwjk6fi2!fpli5P{lwF(}yODRhc>+L-u;XwF-ZJ>Y|dB;*^oE_%3F ztQMCNYy9bT|^5Bds+@H^M+A#^ITfP_vs9UY@nmH>7bptWekUD{xc3_dwxWN;^Q z5jCcp(~U*`bBttg&#{t0UO<;fpsu6qB7c6b<99#{|GksHxK=&Lp8+0$tPcrPA(4`W zk-;fYJCH$A!zGZx;*g7EaMH=(l#{_JBZHGh25my}qdwJ&Vg9;8fy5F>;aSH- z3T;jcB!`O{E=Xamk`$h_7*YrxTtx~OJCdis!$1O`A4%Y_Q$Jk2ouhuZl#v7vFVAkk z=aQp-3&vZcev28OQNDjT1**a5B8)tXrHqR!4?4QJM$@=C0zH$t5+UYn;}%!qEydm#hS%P-*xE)zRv4piiXoh{JZ85Ey6kaEHvZ6E<~{!rF5cs6$FKE{$E z7xzOA-W;dB;w$9V0}thu>o}Z68xpS{!ri0|h<8F-#ck{8SO~jj8xTm;1f!2-B-dRe z7S2W?5~O$$)dnuUk0Ng-qeKD)ua@R_wJL(&=P_r{~Fy|HvQkVzOi1FstN zeVC;2eGDvr7#TYtj@sEH`0m<+yYUX@c>ZcWz!BP@)$0hQN)*vtsJZaEB;;Wi4$~&_ zGH5c8m9qc-XKP>>pg{u1(^@eF(#7~0F$&rLd?fsQk-d0|FSJ(oLy(3Z&1E~>5c*Lg z;`uPVIYe1ZzaVsk;@t&!O_3AFrzDC$#!nT@iKIcvhsbG_{WpliF0ShAT1?BE$H2>S2C@qs*aziQxA) zpz(_i(8C&R(HuA?iT7z}??^-Q2)>tSXphl_fbQn3!olnbfAO#m2Vjs-`irCX0^nX@ z;~d70LttzV?SX5i&OH~b5Dv%T*?XlOX|6NM{8RQrSYLuydmf zh{6j>xIDKunmugjKq2!*+}hHfVFvey8C2~Xet$Upj#yP25UnVf-~^sq{(TbP!!lxb zqPG&eR?@28m6r4?rd3(mh;S7gc1d}S4M+LF6y3Jrc+kp+F=^F9$69fN!pha|z7y^N z9(y}StAbhl68m`)gkh#OGpV$~oH^_f+#f*AhT1P;*|E4UL9Mg3xR2K40HZ%=jb41l za`ddm3;NAQvrlU~PRBDnWTV+<^n50s&l;0E{7k<6hHVlpZVXG%lGDHvQFLDdl)_w`J6>lG6P9}UFt&^rt zG!*y&2j5V3V$37=V$4a_;5H8U{udu4pkM2>^r?Bx1x)Q=n%Y-wY7A#vTl+6YcPwYgp;B5dZ+bgR&bDA8R8+R(DYV&Jx)r`yc}hySE=5kMw4Euclml;q5akb zOf+bq3Cl=oV0mc3i5dsvb|&xGdkQp>wjrQE4x0tc*u6!3B?{92> z;kv;5Tp}%tD`Db2rnm6z%?@9`!pQ^Za`wcXOtlTrO|bWwG`6>y%6jenK72LlFqQc6!9(Z)9ocQCWf*vRz@X?mLAP#1989)HLe@GG-7a4ET z3UIqicWPhTiLD;7?J>77ZhY*HXxNUZ*( ze8_O#G=tTFHQVpCLHV2DI8EG81l*U0vXB@}XJ`9UIiK8ORLNY0= zb-#VXFkH(^{oPjTk8Q>N*n`^c+DF^gG)sPC0fium(Z?r=2uJW6%gosT9ef}5w?1sV zouTKQ;W6D!y9DNNE@ui`C zwDOi=e{S2Z6BeLB<|T;0Xo3VWYgN+L-JQ11B?tq}acOe=xh`JC=h{99v>4u!obu9z1p-mre?~r23xP*;n8QI<@1ss&JDYs*6N6 z0x%6=Z!MhCq+7-pD5%_l$=uf>UQi+$0hru{Z4$%P-5jM8EH=K|@qn)|ZEfvV^I^+) zMTFvs!om&%Mh=Ho!Y)7LuJ0(m@9o6NK4J*UXpMrL*n5|cpxbCidzcSlmyhznce(Pi zjfT^3Vj|UpMxf!O@zMx5^cII z&Ht|rYVH1;Aj7MLE~pJFgAV;7tU#LtwL$z9)EWr)xFUw9^J8}YS;$a~5TQ9*bl+et zr5kA~hFSrdg>?(vSKxQNk_*(k!Z7`gGwgTwUBa1wF7F}3D;jsFr723tqB&VyqRGG`eLeP;mC1c+622rq z&@~APT_l;#Y+c4iGOCINxiz)r3-W5U#r@fhJ1V726A&g~O7t*RMwPr$rApBCw$z*h z?5n(>Y`q8q?g1_X1ZD;e7ck(Rr3POCMT7I3T`u{F@rI0B1(cc#8Q;s2rX zbLki|3Fyv>mT+SN?|A=1D^&h(tUQA^@Niqj(V5kFwUHH#zjtgtNE0~F9@7x$x1vuy z#)v=0R$gvH0K|Kk@We8?wqC}jAS&6d7R%uXhpD5zTrRUo)O#uYS8y-WeY76@Qo<&a zXs)*gee#%aeFw5USiuYF$N&r0Wf!YQkUZ)H)mw{t$VrOMux+F5WpbIWu)f^3nfJeGj)g96@ zP%37T^Q@cPFy*+Xg`ECId0%K|hZ_+HZpY@BuoPZIEXjzh^Ew=jK+Q4OkL=A^oI5Pb zLz?j=C{J(U2wgb}cR&&={DvnwcHkYfpFYbyT0JJQ347V%0yRKYV3+5P{iFL0EVwp@!R(SgV>E7l!dC?1P3cABLV+jm_vb z1ZEbmZl%ZT7Ac=j6B_g@zbOyXMetWHTp6Q(=}A-mn@r zVVow=*bp^8|8WA9r0J?1%m-LG8I8I)$|Gsr{P=^^t?DWF$+qxyE}}=OUf;OH(^daMdfdU;Fu33tel}G<~rO`70cb-b$ELBoKZvS<9yi`eX zv-tq-^6GcRe5CxxiQ`A9|(znubyTTOTmD&KGotOg0HaDJ)-^h7o>^X-aXiPuW#f@-O9f3?i)=z+BbVbNtOzM*(DSH_1_KTZO+1qX zvd}9+>gLkQyhvl3j5hG-kHUO&5mHb(FINI%43Z1frt=fx2G#^N0CFr!7UyELg-Osf zWYIClKKk2Aqd&Ve`YD@4XzlBZNQW^oH&c0h8sT-d!u8sN@J!V!s)45Q(20fQVa7CJAWhf^^eYSGbfXBtqAZ-FGr~snlfG2ZlY)(PUF*hHcBuEQp8X-wEVFChj(1%bfq!@!_M!_9cw3bgP zJ1;v&=TZnAfHBxPVQnL9ZHdI;49wO-i{J$~KE&ak(xhoc?=#p}VTI0zeprb9h|HgKN~W;y|%U>a1RU}$XJ3p!;fb?`Mmdl=>iGGvSxz}qlcL>xmM z%kFIM3OVDJ&GNJ-j&$+^aj00YurSE6*=|v>Mci_Jai}TrjBuS{gj}4V4Yey4w?=^j zR>Q@i(i)jdGmp)^09$LcwswV)zHJJ7!#eB)lwf^AQl+?Rpod}A7-n=#hUzV?X2i{2o1koT0RTRS;+D^F+WTdokL^D3xU7JwHXFiFbHITHcWoIo8`I6{#?$r>WbpI)$>8M!5Lk*H zLib$-p_@V)oEvUprRysvbi+(Q3fx2JrbyO9=%(<*n#W7%j-z&#Sr*Q!2vOn}N$7^v z0^`D!8I?k}`wyA_$HX+6F)4l(P=PK-6R83TCBXF}v;76<8#~3>^^~4^iJs&r67%fJ zj39x!*x4SU;7P35FZU?L%lLp~OHtOOp^K&#M{rPMims9&>GP!3MQSq%DP*&v@R*m# z0@YkedA_gSu&*?I21j*s8KEjDJ*SD8oeJ z8di{i6@ZMgZU8c@>^vITJJUoQZMw31=e01Xo>451^Wu;gUIo}0z@&-lgK(R7sb;k0 z(iBy|4{{Ji`Np9y9Y5|WO~W!mOy(5JDi)i=epAgP;xqB?km8z{hzJ&JMka*ymCrLQ zuw22m3)SA=z(g%VmsVgJet~q_XRZuwT>@GM02uwSdS>&Zt(rzJX+(~(s>mN0e1yRn zz79j!X|;z1CKPpP1dBhSIWv#9WYdO8eTryM*bgQxFxCyU*h2I*IVeng>AQ2Fv^xvu z;9%Wy^=~0Tq9D{#b_Fr=fT0{&QN4SA>eHFB+1Uc2VVxrLzc1Bs=ARh(TSvgi7n_y{ zO!>K8Oc|Mn>?#WEP7mfgS75#jC7d~$m~SV~d_5xms%Y@KI@!Bue|6To-N+IH5iPeB zb{B+cdrlAvyG-(tW6JYWkn1{e#7;pBY4WI-=yB3|a;O)rT^3A#m61)1R)bU&PDH;x zP{`6T>WQLwxYhte@nq2lvo$1%vce>4{+2X_f3V;X3ywKl%aIS80~b0^6hWHXO<^6` zy|6A)Uk)`;XfA75;`!I~#xx*bQ}br|n&w%&sIrqbSelr@L6)W`?0`1!_$xU7-kKVB zZzApEydIVR#}$Qe=RrTBbR$WhB%XAkX>$+rrH9?@-9RZSlYu5KecHFCk@>ViD?!EP zn>NP{MJYG?bFjmxx{xt-i5@wKf$j*~h#;jJYHm-Xb*P~aIs&*hCP0ut#<4)VHNeHz*V_x=8c0tkfStge#u|F`$8b6L<9!9< zn4$E{Y`Svup(3zf+lf^i*ja^#>*$0>_Bwoj$U$D@2ImQz%(2tN!4KrvX$DCKjx?Sb zVxT652wd1paR<0Y@)Qm=Gd^>pP$eWU8Q;xl6uKXDjvF5JdS;$n(hGT=^{%lOL=WZ~ zcFin6Z&+p78<6#2#cm+u23)iU=U&Jk(;i^PVp`^!F;5Dt9URy0Jt9X8y5A777DKeQ zQ3ZkeVRUWga|=Ztfh|t-s}(X0qaU2 zz8W8(2pv!pQoO710U`)#8#%1%Fm16r8n)@^7QK;7#IJJ@$Qc$w$^suZU+t?y_0Ug9 z*2E(R@OO($`CZO=B|gTO&jnp-enR`U1RhRt*g>Q?dE#19EO31}ht{Eh(!emAb|CYr zr~*)KqtP84M;wk39&p3^bohz;SJA9Z6H*|}TTBkLVRkiq^}BI$8fWXZn>5eUM_&&% zs=Vlv*QrblvilJN@2R#*?JrH;&M!N$mB{IQB|r6HjyKJbPx*zwql{FXIgM1KZps{m zR6$^3;2^%6;R>uI8z3G95D_Yvfs@iG9XA2B_{;;#CPK%Bp#;ri%ThKARviO~{E7s? zs9uqGmsVsl4-8rnr{P$INa(eLJy#?L1k^BQ4%1_OrYlGX%y&g&IxPi-xt)&J42L)# zbGy4Vx6?~=Tl8)h=0;dJ5F$TtCQ8%6=8A~4_b75^fLEQ=vnOge4UhBFtAImD1|S%x zDc;Qo=2FPRcz|WfQ48PEdrPzKvK!=KJkOyMjMMFi_$eT_@VGrdd7vSu36c*Y_6xXg za*>=SoDdBv(E7+N;?!s~(P61T5n*D!ys)oJo8kLQGsGG2M8Fm{Lr7V1h8P)V=xzq4 z8>Jxvxxgs*;&PB+O{d_?l+g^n4mP?33P_eSNg-I6%7oEN zh{$lShpR56GW*hRyjCN#2IpY{hPmxs1%1Q6?5Q1;E}6 zz(%82-~-UQy+8(f$t?Xj^zW6H-4b>lv&^#DveaBLF*?IZh#>mHjBsImMWQsq6`?(; zdPS1l#vn#Zi|uQG*0>^Jv#2XCZ7CisErr3tF)jt+azwG0bl$0#ql{>6YAn?3nEeJNw-oFt*L7llu40=1Xp20BD^*2b+Zsg~38B@s8^5x1 zbt5}T=*BYu5C^l9C|`hNU@*{0K`xr6|ADl!(QOQjrxb!iU?R6agBLT@`zYE`4o5N6 z^;B8gK}SFN*ubuA|L6X>wj(?7`gnEyG+F`P4}z9wt7P(_M+-MspzXmc8MI8LkJq8o zb}j90Jw6~QoR5#@C5;R0BZ}XFms40PdQNUhtM#ba+Ds$^oz*dDN>z;EWyk_Au)sv7 znM76c8GxJN;arJP$&B$7`ntvizF`y1I@&!V*MX)S~BuauPN&ri-H@!$1_fcaJ3)>ud4k{EczG_8Xrlm4Nmj+pW4)#@5D6 z8^7R2z&gNyUr*$Y*;kwoFAfpR26^E)El%6a4Y-!C4gnn&jZoU{1B|K%UqyQmqNIS^ zCF-t!`!HN^;kFNK38u4W;VB$8#(HySwyR*WzuuEz;%f#I43H>e+WS&D$22deR+(hD zEqJl}sqh_0Ux9A$>tc-tlnoo}s6aSuv2i?e%n)M8@tWCShblQ1dvKQ`<6nqh#Nz}- zYJ<*{?pb6m)JTBx|MT=7t;qC6Reik))B50@$?cgCkjpGK+{eC zkuVPzi1waNY}7&NEP>qCM6~TIq3B2j6tUNBzXC)j@h0uQNVIzxT|#HiE^^w9LRGYT zdy#g(g0!22f3=3;4x4RGyRQng`(romX>`%<%{khAk!UyViV!A&*hafa%TFWb7HIcH zz+(s{)AmuL^h#-@AML(5E!y81o?2L9744R~3*UG4+%oNcUZmX!AxzX7Bp$>*5NyA& zVj5OPi`^sPz978-b8<)UfLB~puf5z+b+E${iV-o(C9CybDsW+ za0(dwMuQUlJzS=SA4r3D`ddXt50xt(DpkypQRbZZK0JJ};Ip}X4__QA&|MwANEc#G zWzP{JQ)7bjAUpio8zq=dWzD@jk0g1HSc`0}{FpS2*KST5l2Zgn=6F})K?qr{N)5LM z_E5lsh}9yp0~ZzJPO^59AOiQ(3Qb@fpqp|K$QmT{3o(j1A_ST!jFS`iQ9qHc!l3}P zv7cb$H&Ke`C2%Yv)|nzSI=Wg>*y~NwqX^8?5FutKjEnh$7y<_~PzPhSSqOWI7ysPa ziR5(-@E;h_l)k!&Sa8*TB~ptd1nw>2X!k67$C!CJGlaM>R`fqVdTOIg%$!~ zw4SuGKta*S7 zr>&(CGK`u*`)Q4JCl5wAmW}%IGS-INObZcvI2Ugj0Pobx#yzNUdk+SCJPS%zR_-PUt~NS{XsdnzBK!#FTKK5tc#2rHPzMf;DFM&DzDoG)S1jfM6n?foMZ+sk%Z* z>RaUYW=Bk%;5QPCdejWrn*@ber>N2WW~$>C!da+!u%JPzz_t`b{)44TOv2LLkr_$S z;67NYV`1BUJNi(m5(BFGcl41`9SiKRnM+P8&*-;Gm7*yuE}dKAVlJKEF4Ylh%bSPF z9sN$Jk{B5oHi$^*D|=31#Xp{^m7bH(V2*;LmwUaBT!#-ML@)xo*?hWbav{o4e&|NQAgD8NK z&}cMFf8PVgmgQIx`813nq;GX4Ye^!(3MsRG%c zU8G3U-kDa=&0&|Iy8QRFOkt#Y1LriWrX@OOC4NBA)8bC?rjR~y&I!V&Jd#{E6 z=zxLNo}IKKTNy>F^P^h7WhXr=rb@z&g6cYk%y>QA+deS{3mx7;?iPH-=uM)H$tD)W z5eOQITVVI|5x4iJ#re7sH+BO;T}|9(i^T1|RNsl41@Fw(la0u~w|lh9rNjcj7(Bu| zHwN1yvyfilx}2R@24|bh&C8MBqt;$-wq`gx`Qr$U?R-aBw>?UG^D=+24At=hZTJgZ z9L*ODIiMOu$(Q;FlFUG@8l9n&;~Z)@h#<8Rl(-p5V~!0zQF*`~fpk*$VM#dxF%-6~ zNCvx=gPI;JY_OUrTO|ll3Y7y3vsfi&>W0+~T{e{i1SeHsK^1*udJrlE%Yu?+C00{4 zv#-ecuf_)`#?m_N!EiK7LmM2{94|pLlavaPBi$`-jn+q2kfq<-Dq|943t1PV|=VFUdxaf(!trKU`WnsyC zVj+}{0ElS9fNcfmhm!-116Lvj-FC>y^77C@ksQWul4!PK1xTG{X94|yTp51AVfxM= z{?@l3D2f|0aFZ012T&;;p2)jKgZCl- z|8wzOQCr6Nv!asuuCyxOFg^&1T(Nq0rE7t);R5Y8sP|9d2oLJJFb-%>&M3*iRrTARep%pve>9UrUvJ zLMp9ms6iji(oFjdIfYqW=vjunC7hdQ02oa_(Rc#^-0UrMh{C08)*TLkQi&B@3G;Sn zJ;cwcbvNRlkE-28gzDp^I>)vAher}*Mkqs9450N-7Mr3(u1bQ_b8tL?6_R- zX#%Hx)n%@_8w40=Bw-pD#o9WnRONF8!3~i;GzS&)|9?2`)LnM!S|+5vr>;Mm>bO0l zY(X+nG3h@aE7hR|NgDy985hlC0x4_YT0qeT#il)8svnt+b2!wJG!MgZAFX0Z~sIiFkjAf!s)Z z^NmDQRbeA($pxq9R$?Ou5z2yU0AlT@#2qt2L3d@y2DHy9e1Jks;sbC2d?Dnv7qi)I zQ@y86e^_r690v*sCX-6Q;VLf%kG2WLLOFC5#CVGL$4o4+LBjxX(8;vH52OutdeIsa zxdMgOOi|iQCq>KWr&7&#=MMfyZG%I$(?O}XKS*`l@|iqC|2X!Hn$#dDTu`g!MT0KG z*h<*Mbg@M#2^ZF-hg9&1f>f{;MQ4KdXI*15a6&+M6OhfT+d$3FBSl!(I0FEVr*jD_ z>l$$R@ZY163WCxoN~5&4;?gQgtEi}`xZ{pH8dThI<^O%BPTjh%-g}qZO0JpT zKYf47d-vT_b-q)lPMtb+s_t-}G-GCsMJ80y&wy%pW_w~es#(ppnRg8lL&O)J){kyC zndl5oYm}}FPhz0#x3ygvj=yw`?NK|O2=o}d4c z!yK_ClsqgXm-TPS%SWu(;G><_aV3hYGJF|dLy@7zVWc!4ImIfNtY*3)Ozy%lD9oDR zUUN>7noIqnRc?AMoM4#=BcCvfBpjyr8wX7D8^3XcsXw&a9A^?HNin;LYfpRDe2hs%@Ky4^5B6*u1R4| z1__8#aYW|$W{Bl2>|1e#TVFLkue z;ET>0CNr(F8G&;I)}Fk}96^_uQfPJt8c56(+Q+;X z#C9{pR_UxYo6^jVJZ^oZ`>T(df6(q?FEICsZkXmCThivnYzjOb!ci}fj59Pk@0i7j z+FCcY9AQ?igX4?}FbAflfnTx*Usl5CM)~j=Q%HV>&q2S99l73t<#od)M04qRA3e$RsgV;~^+W5#(pTDALU4zK4X|k6+D{*x!F_HN`|yNa}lUo_TOd#a_y5PGS3a=Z+-1M1RSEXj6? z+9i3tVqJBwnB@dm)hn*+hh7o(DN2UkF(d~o$(IdasTW;?xufdJqGjrIkX2p>;dZCu zT9Y7ZRQR!+41HWtO#;fH6h8Zv+U;XIuKpB;ZV zh+)+8#~+hwghWb~Gsg^F^j;*eT&=ve$Ch}!i<5OH@@)YGb7l(RR}aivH9u~p5H-UMimv*dAZ{BDQZUj1%HVkk+i z;k-(EC?GoOq?QEndvx51j_sW`(mvcU0L`j2ivICevmK%eqp0!}Irr*-FTGQR4kc08 z)?X3Kw!sCkcHBB>Egc7BeKL~s9LH69V|lV8@{MIACRXN;{_`DOm9@P6y)rIq|6yGI zmc}I#@86YiiMaavH!c-3hian|A^E#9DiK$GF)9&JAB{>xS7lT-G2=RmbD`0=HDqp~tZ^(oAoi9~j<*kfo zHpu!C*K@vMyuDRO^yd9i6Mk1NnX_y@VnqxEHc8sv*R?>r5Dxdu;cEYkdtG=b@Hm{a zj4{%#beJU$jU_PhcMvMWO0jNME;Jm4l=9MU;(2}=KYtBBn|;pWILg{VKh#2DF>Z0- zz#`8mIzXRla8HpJDTb>F2N05BN0!T#9WGsSX^8nSU&SM`X9cGX7{ZU^uH<tJ0C~io$HeLc4FiHH%9D<4XKlj**6GHifXvhX# z2#1$T@%9)8miwb5D_f4I62bQ{ABU?Z%zvgo$ipw`70ltkAdQ?T=b9LIP>PMYu-4nD z?ZTeov{pwMlW+~!EDE2fn^oyq(S>a=E-Vg-llT+P!jn8jII+Sd+*jcmjuT#Uq<$<; zk95&d^v)Vi zZq%;BApb8=ql8x5Q^Y`_tDdo0^QKu97{U0?;%N@divGiLEx|U)iO>WYaZG^G7lMnv z5LhHc0<#s@1SSduYho6UuJn^!7C9buI6!i>(YpFXXI2qmBjc8cIvtTNyh+lvsz4p~ z&Z;7k75ymgj5a|NNgFsNT3SW4yRc{4$JDf&M{|y&(X0us#A|coplT%f>Lx)LG@M2$ z>BC|OxVDPraOB#-fHoN$Rp^Jr7c7H^M*ubf) z&{&<;t(kW*nTU(^l96QgQS#NCMnE*uckl^0S;g36O1v?WxGhKCS;&QbzW*5m68Cn> zs3GG4ieUmJ65u4Ip9kAVyF?>aZe~T?`dF8h)qH}-r^FiHvV!fGCQ`nV4>4aZ+A?|r z?=Ve3c*_fK*elB1Jsonc;}a5XF&Oi}Xg7A6JS;5!%l6_t26KjCxMHB4yH5YOzN+mc zN3EiNtn#-x-sp%_*G-aIe3iMXQ{CipYhi8OwNEs0%N`9THy!=a29MUWJFAnTI;lO5#R0)}{Dw zN6-=$n{gjD5vlKO+c`}#1;}?6V7`vS+Lc{o9mC$qG1rfoOe{z2U1r8ymTu#?hNF%^ z4$YzOY+g`@LaeK0b=fee9I+ySB;VaYGuc(9-U>}LgJa@8G85JK>j%-f#I{Fnm6SlOb62CUFG;?{H((F-(>* zD3uD6ONA-i)x~How!oCI#X};vd@n5x-&p*E#=*l4L+1WM3bSHxgOeCKrh=%ML zVkYA>KvzwT1|DwaK7X*NFd~H*wt=l|T98Sp2O!sZgdqZuIPEZb%SJ`TfJb|%{U)~0)NbMv9XxGfj1*oIk2KD^Ky}THNU!nFAxuV> zVGbD%M|BK2LjhurdFk;rBb>sQ3`>QrBb}!L>oVIOLgQIq-p^ay2nuF2M z*$YSwIDkLnyf->T%=WV@-b~0b?SL1F7C9}#X`P~AHfYVhVFjdJ(Z;Wb!2h#Tg4(j1 z=h#-+vG~4rj{~?I-5{Nq=ZeRW;&ieIDSaT*!I=&yc`w`$0pt*GQ`V7afDvil6Q@&*J!F96e z&~5M=3EA1ywC}r{Q)^yoEUk7+0-`LuVW`t_TNTplYJ_8vE(uK5TVrWp2&P4$G&Dq= zESJYTZ-BiE=ZQy)jbp?-knKZE-=`-)*HJtDfyN?ZEv(oNzsTAh8$AZuwx{-ed%Dz? z`~Jjo#GN){x-L`MjK7dnls&_-nwQujXHu5C&FLo`$|Zvo4Pe#}-12BPA1wFjcV)o zA*yZEoDC;|5ACHqGTLC~+{7fNT9<{IY5j9HlWnpsx6w?;kG2teePo{{lBQivcvC*% zSD9^5#^P8Rm{c{@9m)E!TuIiFVGHV69RV_LFu7_kbeG0HWru~M|9`$PuUHi1swNhL z2M^w!e>?0TN1$M*2i~{N5d239g_fa1hwWzfe|~!R&y3uoG766~PilqXzx%!K|KN}x z{>zVk{I5Ux>DZqg`tx5L_RC)#{%^nj&2NAA`+xt#AOGV&|MXw~{pTb8=P&;|?#QE# zE(ha-2|;Tx5!a+(axf)m3#JCg1jpiWC_~3+~J%FawF>C8Rvo?dz7NaDJJ;M&X zf<$&j(0=WaTO@BJv5EI^X}*Q=if+#IfVQr5f6m@Ot=iGy9Pg1k!$z1H@jgL*lfuO} zM!38z(hzSr<5b!Up8Z{JS+YuT(hCb>61Z(QxtQG z7$aE6NX?wOMD`l-TyfTD;imFuwb;nF0A$Ix$jf;tQw%R&iiI@+YPF-t?Uqf#G>1S< zg47V%1hE5Z6U0ENO{f@tDH*kd@+Kq84r0-6rqvURp4Q0*s3qbP9D^$2i4=hq@nSSR zXF;tZ(>-!$+Ql7ij+`JjT@$y2R3s=2XUTkEJRT^OXV2CoX!{Wjuk8(I8G(3cLSu1u z0D_}YbH4`K`(f8yO30Uk)h z)Iis3VVL{N(O7a)%&)Z?uSW|`vI4c1~N$bIu+>$lvQaEyY@@`{(bqr4ZlCj@884se5t^}{9%4)zDEc% z&j;iNk~Fk~Za1B7+K?25xb3XtR!=6aYr^=ID|ew;NuwL@=rJ4tI>vx3UDR@Y73 zICbf0udR6j8ip+~*w-;HuO_zjJ&pry>w{1@LJ`J;)i+}6tKu+yFMSYB6{7ddJ&`#% ztv=7X+uw;)EV5=H%b`M&e`3VQrzqCqLu`+)l2`;B6Q}i6`fjZsbYN7RtYGVk^W{Ww zu5%oyIQIhwdxrbh6Xzg^^B9V=i05kQ;3-K`r zL50W)(g{%(Fyg9NM<_~RkGsG~8@EAr1@F=e2$D8bIV9PUr4OJ-iPKAPV_5Dm3UBQ5*9Nu3A7ICUKgv>)e zE8V$`e!dD^^_xSriNxY+6N$xDQ|tV?I@z_pPFn z3l-TG$Ev?3O71nsfl7`G>s-JSuX?PR3Pi3jUN;hI66kp9AdgnBsf2G)S|1lt%5YyX zso2aPKS~f=Pn2&vASy~$P$|lKO6atY!#*ThM+u)v6lHmQ6arIG4oebcOC8CzQm!p^ zBsYmaeq`%PZldE`CC3W3uH;@!l-y*;flBT}wIwHf$(-7nUJ0yO)3wFGn%ND7)iS7c zKRdm{36oJ!zlq~SBi=lS+yW#TG|FuIcnaN}#UcYpXwnD@jZ^UQKl9nFJ2znyl^I8- zl1wtMn2dnjkpfERaAJA)hZDQ4eapkiaZX^`WbcbN8G2k~E08+j2E~}$G=>?q99)`; z!YIxwL;A5uMMf7avnNYs7U6L@JvOZ3xRv_yIDrHv=L_;UaBIqAW|cfDmfI8L5qaeY zI(Z1A+j{cA8lF8IXC8r=9qf%q;<%e&N}-V%80IYpr}0-T&S6y^KjF}k&jk!FBHG$2 z?#0Rcoojda6>4UpsaU*gg8L+qRU9LX7w5{1i;-ELmVoa(dNQB&W^cUb$%F_ zud_n3!CN7L+6Kju(Yo(wGi;5*dIeW}u?aMfJLv8hxAeR#u9X@sgrOe}DZzRa@DIM_ z*jJn{C%#d3kfbyXM=A_5 zO2LCPH`CIXzhO_#Ds6r%&vs=()HVZ)A^sWUejOT0DiD6>>Mk`7Z#|K6?CLNM&ftNs zT;myF$f0LpX`RFcc$Z7UHcr6rNONE%NOJ(AJlH_@H5ErzFI{fsM>Kh(W<`;2%C>>a zP>`l_%`?L_PgN>H_pZ>(_x80!p=x_y|3&XOv{vu1i<_x-7kz~Kw2}RhC&2&G_!A7N=<{zwdYH4*; zd+r+fMZc`Ymq>5c@r&u;wGL0hawoQwgEJma$(R>cPT6yqJ1+q*IsJ>_xV>=an+|SZ z?9E7%84f!yCy9nUrJMr6P9=N_OOKcZ7p9p>D6F)%7z<`J94yrhrCew`zAj%yO#J%K z5DO04k*Arc&%I5^_hS%`cI<2N^ce1Y=MwGx^s5he4+V*FDWu$Z%F;jSy78CsdH?s4 zCpM-Ckh`q*6N%j^7LdbbNxoy9ocjSN;Ud_E9F0K9J0dk<>0$E#m)5a;s)Vsx1kT?P zM_~g;1$-I5H^+X*R-&-A9_U|;-tbCZG|-@r1!Y z5{!-jql036d4iOoo`|Hdwh1%&g1U5e&(<(Qd{EHlk?w8xBQTEEmX({R#gRJ9oO1_jGz%#B1;2DQ54i7qFy*s=7$WbVACi?>K zz0)TM)=r`8NOifBs(M&_cZ3ej70SS*Ytan4kI{}G5sIDn_C+X|=QK=4Dt&{=&cN=r ziA?*))KolOS;^wm99u+X{*CF_m~lg!ZI)F30O!c|m*$prMNG#_0j9jSaHQnMr_zF> zZMGz+%u57iQx(shX(}y|Ge#o{Op2RIDxD2_(cDIx+P(K@3c^8zxGM8hk8{ zjKfq z8#Uk6&WbgFEkmps(98s>V0JV}e8C=1B!R!!#K)efsl#V=-MYQ0*7297VXpfG8YYWZ zy@c;@!kh&ilyEvzkAnaQbD9&3oAHMiFh-}$@3`ZRJMFad`|yXCF!HqdI){LKZqJHi zKzIlUrs&=|ASn}&qaJ}!P1SKBo4igjj-8_0?Vaq!8X}Ft^)&gC^vDAv>}!z%ft3pApd1KuhRvADz~PKD6cIw`8rs0Im6Piu_$cqn1e$jwzmazk^rAuM znQ_cayR5b_=mg!?btL%~EO-h#w{|Aed=ViN2zx6_6SX*0I*aLw>>{U<83J3&iF z%N|gkIQJi9BFc`Fu%p@q?r}7JG(ne9eeF%Bvt3QP>C_}9s$qbUV3Sc?M8!rz$tEyS z#+e@_xG8i`iW3=B{&#T0it*APAyhGpH@{&nq}EQB?tV|+MIX?lpt26W35MwY#sg8a zuD29lqhkHGQo^!A_*;tIum)E9nFoKJU`*E_cRI44RYzACuC%3idPPy+RAAA;V8?~irrAhuP~4x_#m_G!)hxZ5ZQf* z)V~3q{&o5_9ad2j-W`YRB6CK~l|;n^Ms$Y#^dulol@B$|Tcr#y^ZB3QN2?4k^2S&Z zOD%PX^%!c2e02ukT*v5gGr0a#I0YyPBT8hE8HA=kv!n8;A*KzoG+$GnCoeyaG4~vA z{OBDrcY$M0XOaIR%thuYl!J~A7n{QT*&nhZ8{9{puGyu557=WReV(DkL(sa27;4NE z)-3oonnS*R&$K(Eso#~46^(@Gs9G%3a(t(s^TRoH%O%-s=U=U`pQok$D{Ys@Ti`mo5#4f)2>N*Z=jd^R)d zR^MCAj0Ne~kW&-h?bLu7K3+wKX(o<3fy@x7EDYfLlbTeCA7*>=Xs#I{0sMbPg+boX1YqsMrh7T&lQFaUpnWqqM2?H{8>Q8lAU(9Fth&d?z| zOrQy21Ge zdzpqX9X=*<+;#()M3y8q&)A4YR6u=?^#PNw{n@_@7s&QLN%-6Ys;0e9Mm@QS)d57k z;H@$t!A2hVB0avk4SM(l+vzh#Nqdn1!?&7OIGFM_)7|-ijx%V!9_z5tzl$Q1GO*Yb z85u>a8{WrJgx$@Y61O*cHbx9{l9yTek55@(L@La~lTL5+WHpnm=N#@z^FUJ?u`gIG z$99nHv`DS58s!!C3De(&HII;L2wB~3*X^Em;?uK3u_goYTN!}P4*yXEW`m>AxHHyi z(CMuMp>-LD*j4qcBh#v|e6xkBHaZ%uYFMqRs$jj~=(MhuE!OptqtUu#A;O1MRo5$y zPV4%R@M!g_p6EAK(d`O4*krnJ;x@j)j>@COY(KO;EvC2P@4=g^;p*|#i(AjnivkDr z@Vx2psQgTx-InC=wxd(|G0dN=g5~j1phD|nsJ}`DtJ-RUqtm*WbtFk&Tn<38PB2bl z%*S$$%|JV%%97=E9B(kc3>jo*QKNrp8}WEr`3pnr%^dKX5w12bQagtC8CsXKcE;kL z{`=%g9+SqL8AsO+^IIO*r#cuqt`9&p(Vz$qIvUq8K*k5oy3vQR^hfr{mGF9PB;=eR_9$@PeFw{Dm)k@rz&j(mr3t8ORd+G_lXG zAv@_{$xcE`)(P{!=|wcZgGZwma_$)pF&Vj-mTnH1wZq&t&X=)PrF+?!YKK`e-ox#- zyqk}hQNk%e8JLgQ9q%&T{N}(?uYEdiKVt5wPjeYX-svfaC~_uEKF0FJMcsA)VvTTMAD0Qzzt>rL2IF@hD<5C5Fjvfl)<&;!)AxAzSt$<3C*pm^#q)4F+$92 zVKxy=4t%sJFg!zHUc?+pnCL+K)_}emBB2$pPL5I(KCT7%Obyu!W=aQyCZCZm zZiOZRh8+l2#UsHcdT^9WW!I4;f$g?h-+8o3Z|Dmq_npV9XpA>#T_-xyet%nEMblsE zNuqhWiiXJ%l@T_-o@c6Pw!G8exhfjxJ*{ql_f-GwvSH-=z-QTpJ`3N_U{0R}t92ZT z@-j|Ci@Cv%ne$t*{i7n)8F|S_>ZAubTs}hE3+5P3CfiE`nV*L6nUQ#Ah(t;FD;;*d z3G)hRX({ozgB3b`Tw}bPk(*eKxcmID91e76dE(+S6v$X2YZ+i_A$x-jr{rQVMl`LC z4h;r1jg3(wtd(S?zTZ39uN2ODb*0>#qQw_XT!)nw7!2jhyPzDhoW&y)>1i9u40k*Y zui_~lfbj)!jN|G4oJfL&T1lW6vmP84ZU?bZz@_WXHC~ryeDN0!OsP#yum10TLXWtZ z$qRJi@lH{Bsi?eFl(`GrZo3_iPs7=1%wE_JB(+o9nRC%e#7(D(A0H0??kWj{sE7=(;!P7-8(s@ zFYTtEq4ZVZrU~V!sP)aFU|biEW|Qo@=s%+hL1mdyr(&5`L|Yx*?@7z=&L`iH>rHd6_390v8RLd21fjjT4x$$U9e>&<}pcuE{Pw z691rA4Ieyl03l(aSGp|4U_P?T!WK!)eWdnHhTQYkDtKtojYq|VIQ~|9fG+_X`{LMc zb8IW%-=qXQ)ln+o-&nxC4|sst@#TD@EC9DA0zS^Mt$+_t3HW$Nseq9sU|M*U515-n zew9@VPf7$l!?CS^4@(JnrlVBAhgraDe89|^`9)TMrz8SC$+4|~4^0Vpj-yn-hg!gE zeZb6A`dLTz;7g~bhl$$0e>eY;PV`%0!Fx1 z$EAn7ftXPy$xO;(Abu+m@P&?T1w1At;ENok0v=-lukish>?j*TvjBW~1z@vq>Rhc$ z9oq`{;FN$bbCe4BU<-JTuhNX!emyIdJ}$8juW)QD;Db^E?sb$37>Qj*r8|7US2Lo- z*mx%1^a+WGS315GG1AFWO&_jtl#2KOi@4KAEYU^m-^~W`<_e|uN8;-p--;NUiBloI z!BHw=tVEbL?)DMi#5U$iL?&&#q5`qsjc;~*E8=2G#J4y~MT`^h)KL3~<*jCtla__y znx3fDw>!QS@xCb$-{B|~@xB)Edf&a2+&4*>%L4JtM8s1d`m`fO- z$8Tdf4}i-|nP~OwM8pp`z7_GPl!za6l!_QHv^0o&eZ&%_-#aVBy@~z!5y!V8-YX^I zM;)ai#=4$C-0u4yvi>3|g;{9zNr`Rzq~lu=V?{BQtzPda6*12!5UpP8x3Mf=F&i-x zt)82Rc!T3x5q~Bn;%6MCBL0j;yv|1~Cpt!pp?~Xm-n>M_&pW;q@uyNEe!)>HVx&)+ zHeT-|ewpL(C$nnfQxXxs;`mm?BT^!M)ln*9o=PEFz0pT3=RBK5 zA4`e&O-HGSKV}hc@)7GPkQw#kg^7sEZ57nvTv(pryW=A zGqGH!CnBEY_*TS)l!zxgN=1ys1B1BDM?95@i6*x-1Fc@3I36G4_*TRpN{RSbN2!Q$ zKBYn2>m!!KBIR(5EXLzA65IF$$G0N>KuW~zj#3eSz#^XGBc91Nmek=a5HC(dJj?N| zh<8bec($Wd#JgC;9X?`gOtG)o%s{J`BqE;c_*TR_r9^zPqg2E=Ownj{r;qp)A~t!? z86ZA85%H;xZ$*rAR#MsO1&&e?Z*LKI`-o2?Vw}~Ijjb*}n7ICOx?@}+Z<`YGB1fr^ zk=bGzxyOgRn2;s8B#VyRmDtFgj&DVbRFYJUyu?u|Vl<*byw*p&l!zs9CJV&pCL-=~ zd@JJSl!(u9l!_QTCk^6tKH~F;*yLteM0~#ETM_q5iFlc#RK!RGGKkmvh%X}I zhN_M{c}vLY; z=m-|dby{$Gut=^mf-{4~a&-nvg0tj0J6IZY$#qU}ZqO~)dBOR?GPy1YE(|V`>*Am% zxJ0f?gUf>Da$O!=5v-7_H@GsmO0KJemBBS~T^n2%tdi^c;D+EvxmE`^1vkreORy%m zRj%8D+k-pgx-+;dxLdBZ!9Bsfa@`l)A3Pw}gTX_=I=LPW9tj?m>#^YR;0d{&4Auuv z$@O&b*I%kjxy&1d}ye-$}pd5~u zYeLu>PLyj>I60gmS6etWJVvf#!)f7havdL@5Vp%TJ)9BFlxtQvJ3LXYlfpUST)9pT z=Y{j-Iwd?cTp(9RxG+3TuG7Os;TdwB87>Yx;iYn27A_Ajm+OjfMc6CXmEl$4)pD&2uL-Y}>$-4Nc)eUVgg1t( z<+>@nIlM)#HQ}w{ZF1cn-Vxp@*InV=;aa)w3GWT>lk5KQf$%}O9tzim56ksP_-Oc; zT#tuOgip$~K71;CTCTr_8^UMgdNzD6+$h)c;S1r5a=jG39KIsgtKp{bHMw37-w5B7 z>#gwZaI;+H{P_F?xmxoR^ONM7oS%|!lWS`JnEbJFP0JsbKVGgA^6mNQa?Qxk%+Hc* zcK*ctNpj7}&&{7K*S!4v{3&vsnqQFbkZWQ7wEXFEEy|yfKU1#7`Of?jxz5U;onIikV|-JHKAzecWG^S9-1m+OxFo%y@ux;wu%e~(=E=I_hj zFV_S42lEffwJ!f~{t>wz%|DiZT&^ebPv+Ol^;G`p{9o}ZfO>hvZC)PnGkmsgBJt^V z<9h8(;;1mqB;LTn`j$#O`LTFrt-r6LwH#HU?lZ8Zn* zFS3~lw>}WZ?C(lwbBrtI^=UCrb)6cykD2+zPiBUB-w$ zxMF@hE#~7LsbU7HVlJ=qQn#2={8(m~r#>5RXMgY949B=)ek3jCnT}L3gH$oM`Iwni z{BUNNCr>?b+K74t)BG0$DHw8VB^=onYb_oT&qnj=-rAXUsAK4xYYugwhev58~V znT~PAd{_W%5V!kOY=8GJuVg{*V z?)5P<(|C1em}eyF_N9(-#e73r%$GS*#SBu#yvoPSWaH~I!#pd|Zm)2RE9UFcV(xXM ziW#Jed5w=*@{O;}4D<skrwnVj#NQ|R6(!zK}+KC<(Yw=oj6|I z?l@P_m!$=Lha*+cAXU&CebAD7d}(H&FPapeQ10kCCTkt%3c4pP=zAQgf(EIA-sFRp z^y7;&13f#@kUiiySI`%x1^u8SRnQ<+(B+4{S+ryzUyvE-?oDwQbO*1cA90*3==0Np ze$wy9jSr_se)eTgO)7i_RK)vl{ikH>Nr=>$EO9oz>z9wkSgf)K4?i) zJ}xuR8$08DdZ5>*Pj{Rv=ws7@UgSs>G)NWnMjy1KDj$;>=#vwJ2%U~|1>Kew^b$v^ zph2pjH~F9?TX{-mpf5-?WL=JP1wAP(=yM#Yf(EIAEP7$&5tM%N^$m`pvYUFL$I08l(z(jt{z*px?+0^zy_$eWl}ELBEz3^i_^j zL4#C5cle;MA?Qt+fnJ#i`dY`if_^0}=<6J*f(EIA?({+5K+rE|26|nhb8@5OTtUB> z7W8UIs-Qutpu2t0w-EFTnSoxMIGCK|Fk z9p?)AnY5tqa-<3xqzby%2YnAgZ^#Vv_(YHFUdOqDemX7a`y8o)2C0Hx<%52Zpr6VN z^y)-I_K@RTK|h%m^g2hXph2pj*Z80xCFmzI13h;|e8RDfH{p29aju{rOAGpON2;Jf zs-V~Upw|=hqnUxeBeA8Qa-1vZhtq<7+L0<~kSgePKImr%dR=CqU%oRQM8NjMT>Sjw zXC3DX`oXlIpL3)N8l(z(y$|{Yf_@+~&|Qf`){BmF1$|#y&@VYs1r1UKz0n8#DnZ|y z8R&cNi1+F3yq4bNI9JeX(}I4@kt%4AD(Fo<=r;-a?#w`UB#zT>InEXIooPY8?MM|g zNELMXQExsyJ_P7HG6TIVQN1Tj@K-o)OAETykt%4AD(E&J^kjm*H8aqcB!ZseIMDxq`krE$I1Q<#fcu-xsG!MeQ{dQ-Hud2gH%DU@j)*m=!-G~ zy&+M(FL0bI=nK+Xpk!CwLa(`f?k#x=wlO;=Pq%aE9mpmg1*#|Drk@@=yg8m z%L%$WGte(3w)7Q_a|L})TF@&Tse%Tnf?n@~zKWo`G6Vf|V%+;`$GL(&J1yvyj#NQ| zR6%d_L0?DEXJrQZ`ow(iRgQB7-I*5j^^R0QgH%Cp@01eUQD&g8NgStdbDS&a)6#;z-H|G2kSgdlAM{-Wy)ZM-ixMXs zcRS7%^n$dY*E&)K4N?W&?t{LMpij*V^rpmU=>3j!1wB74=m#9Bf(EIAp5udFN6_;! z1HCA*Pe1H9SI~3Qf_}u2Drk@@=nfzB;{-h?Gtf6C_UR`a=L-77w4k4KqzW3O3cAw= z{WL+(&J6UD#FqZ6<6J?{ObdF0BUR8KRnXl&=;sJ}MrNSjO!UY$I?fezds@)XJ5mJ= zQU%@PgMNviPsj}P#7XfOnSbiV%Z_seeOy}5uQ*Z#4N?W&>w|ucpr>U9`h>&@$Lo%B z1$|6f&~G?W1r1UKy~+puHbGC#4D_vuhHSIrTtQDs3%cAItrI9{kSgdkKIqmwKu^vL z^xcV|Cpyj*^u)BFCpl6D4N?WY)(722(5;z)o|f3Br#j9R^!T)(k8z|58l(z(oe%mr zf-YwU`kcgY(eaLR1^srAGEMRXN2;Jfs-V~Vpl1;DTR~Q7l3j_u_e{sRf_@_{=vj_b zL4#C5Z}dT*M9{Bi2KvIpmY(A{SJ0c%f}ZP06*Nc{^d=wle1d*8Gte(3Movy~oGa*; z(}F(Lkt%4AD(Ld#-h6r?LBEt4=;etmeVXH3LBEg|^y!XNL4#C5xA~yYBz&K2~!w4kqa zqzW3O3cAM!y^^3G$_(_(#Hr;qj&lY5Kw8k(I#LAkSgd^KIoeX`ku@{UzF&3-{Lq|(08W=y~dF$Xpk!CH9qLu3Hq+gK);a~ z_rAk%uAuKo3;Iq+s-Qutpx64K*An#YnSs7K(G9)Faju|mO$+*7N2;Jfs-V~TpdTRU zHJO3FArbV0j&lWlb6U_3IZ_1;QU$%<2mJ^^-;^2X6^VWNQOCK0zA-K6#~i7G2C0JH z=!1Tepl`?w^yDS+5U{^#e7)mbL9a>+`YA`Mph2pjH~FA95cGAKfu5cS`WeT$g1#m# z=w}_Nf(EIAEue13+Jv z8R&BoS1rd+jFu@B^d)IQPjI9P8l(!k!v{TypnEa{{YqjM@MOoig1#s%=qZj=L4#C5 zclw}@A?OP;1HCMNg|o=eb6GXwp0VzB>Y$GL(& zD=p}Gj#NQ|R6(!uL7z&{OELpJZ$sP--QL^Iu)uMypckhF-Qh?TG)NWn8XxrO1bt>^ zpxaJ~gC5|4UgS7e(2LT7KEshJXpk!CwLa)hf<8Sn(2En@&?Sy@1-&pW=(8NDf(EIA zUgv}EBIu6HK%buo`W(l(f<84Z=yM&Zf(EIAUhjiGpP*044D`~(KE2FwuAt|o1$}`d zRnQ<+&>MZw7Zdc!nSq{>*r$6O=L&jGTF{p`QUwiC1-;1!y_}#=$_(`UM9`Nz&K30R zw4kqWqzW3O3cCEHH=n+epl4+Ux+l>My~=T}pl757eYGQ1&>&UNZ9eF033_^Fpf67Z zeVyZ6L7$Ko^eRWHph2pj+kMbC67=zzfxa~{8oJtXuArx-1$~nvRnQ<+&~tpyYY6(- z%s?+sT%W$xaju}JrUiYQBUR8KRnQ$i=sO9zEi=%o5<|duInEXIg-|CAE(%Z^eJ|H&d=>m%Mo#Q&KU;#(6(sn;CeiujKy5x?#z74aV};&nda zw}|);St0IDv|MjHz7_HBQzG8%C>8PVE#mb);tBnL_;*<$UYqE1wodYwGk%j2@kB?d zh<{@dZ}bsQA>v)RK!2Fi0Al-JBav4 zSs`API8|Qg_*TR}Oo{k3N2!Q^Xc2e#h|eJ6L$X5rMq(SE>G)Q}-%p8nv7=PP-?xZ6 zeZ*%G@%OSqd~c%9b++SM5q~Eo;-!vK5r4-b?)DL%OT^#K3h^C@THWpVR>WgcB0kSi zD&jE~agUGq0wVrqR)`->oI73U_*TRRr$l^_qg2EPTg1IS;!BA5>scY5@J9Sx-zIMb z@>0jQB0eZ3;>#SRB0k6>Ugaacf{4GC72-vSai0~AZ$*4SO2oa6QV}0u5wGzPUrogS zlojHq6194z<69B$pAzvkj#3ftZxOHc5w9ZR{jx&5G_j4ZcYG`2VoJm}I7&raw20UF zh;Jg|(ODtBAQAD+j&DW0Z%V|sI7&sluSLAxM|>L*e>p3}*Cj@MZg+eu;xDB{e21e{ z#9y+AH~NV0CgLwBemN2GBaUxH{MnRZ?nB7W0RD&k=lakr0nGZ7EX3UPa48MA}(0OJwD=zjX?a7tPr1`*pDYUzO{`%loIh|N2!QEWD)oJh^G?q2eU%FGEu9K zaeOP{52QqVtfN%KAFzm5`G}7v;`e8Tc>G=Q(aC?)&k2riMZ8N&#O;n!5$|FVukjJj zB;xmFg?M#h8_#llE8?9}BA)Fi74c3M@me4893tK^E5uV0J&?JMZ$-R)O2j8SN=3ZA zMZC^Od5gwjJTN8V zMUGMt15r4pt0gRL^bs#6;sIG9UUqBTa)q8>-RbyN#LX!YFL9KLxY;7!DnJ&k-BJP(G@i~rC5%;r*%TIgrQ#3S;B($V8u@XG64A^)AOp$&__3Rbp7J&m?)3WcE1uutwIkeZw(RwKppV-U}04%YO+eONA4qRG)2bx>M(Db zY9X5{NNlQbG#YCl8Y`5BYVJRvenYi;4K)al7KcO)RnUeS8nUSDR{vZlVg>UKC=7Gg#+->5`NrAmfLlBlaf^V@z{w{6N zRT_>q4~%4n)M{4qL@wcpQk(We=?hWI6}*-^rW{G+ZPRjiu{qiX47diYTa9U=3!BhH z&0A=qutpzCx`!qmR?(z`w%K;O!Q1b!<4!xjZX0+EnQGUH-BYe)%wd$rqYRjYo|e z+PwI4L2hXOLMVDS5Wjwi+EL*BkXkhew>Yl}3;n-~uY6)xd_|$-S{g+k-;ZxC4f1iw zKp|`Z9HU+A=|f<2f|js27@yyVf-oqXh5Q)uwS)XPu+SjlD1;N_Uyk2^ z+Ep3_%?OP~46d!3c%r1LS@Q{JH)fWjMmoJg?8XiN6co%dqfy#^#+XO8X11d_(a_LG z>_;KM==3XuBK876&lDNeA64%(b9{qGdUnw+txsFAR|0IslKdw+=w3+bfhYfZdb5 z6%SF(_(ZI?(zZx%%@_Gmdh1?c^U%EZ)@|gb(Y5XH8ND@+F4(}%et`N0$R}nJ%CFLG9IxK}~ zP2R4!Ydh?R@VRz}rKxC!5ZPf_qp^5fS%`hiHs9-R zkU~%#9u1Kr$5i^c6Uq^Ro7vGBhldEMkLem}Mi9C`GO05^<=FR}6AW`1!X}sgGHx6V zu1Z~+(fUnV=3wZ1P%sfDGZ>gTn>d!@^K(ENqCV-Dg9@K?vSaoQP0c_y zyw*Twm@g2Q7Ts+DVk)^LpX&o2yyyJRn9Gbd%+g6TntKM>sV%qQ>=`DwnSZ_?! zTRzK)%hu4_X%2|$Z67<}7WKBKad6({366pJ##59o85s^vX8j=0bVsAZm2;Tp_Uog= zgf6mu%nq9lG8odWw>Ia+rgW9==hym%AeyyM*QxuQwZvT_x+2mCx=K4idYroKbkw-T#hu<9z-heP zHG_3%3?tm7X7gz%93iod^n^Hm_viC4-jNaIbc}|R134V4@8Bz+rS9q+hprNoh;tl% z#AF&pd~lqIrW8&dw|GxD3LM9;W{iW50To)JZAKL6tj$N3j%qa&LF>dq^SHQZbk1GF zMp|Lg9Q2hWj8~B${p5*HdpXjND%E^6tm76y1^ZJ4@rN)LFckC@wNe zLm!)S(u7n&=}Xou(WH(=JK$eqUl$x5MMU0z$gXBYs}Z0ot#ctT{fH2ly^HZbCZ^aZ*D{!z)d~wDP%E}2 zQPSn-MY6j|dzU8d@3=C2A@%GQKlP zFyXw8M-b#~CCa zJ`N|QFhy)9jV}k9X2w0wNFe4}OJO>938u%UsxHwq!gZV}k@RwPM zon%SKlO!Aqj06zL$Aq9hCKv@|J)h90(8PP&?QfKtJ!0Ubz z_UX;(@Z-#QYdL!IRb$2(|8>7lbiZ#hzq3;J`y}`KEoPyHK_d72WcT}%&7w;m!S7g) z68|2`j?t~u(Y;g5R@xB=OC6<64_s@w`^%jp5~2(7uM2Sgsk8ID=C z`i!`ww)(A!`RQl6!c~S`_}_49C_(KcJGj_Usth3{Bg0-_hM#~8CB~D5(u_~sW^%S; zTLGs{qgm=G6|e^E!_q1r@Mi!xvn-l&;?CY~$F>4an?-Y;qg23A7R?$T@SXttu9Ijw zw%kkPkytOOpG4C-U@Q8T@G3tAr!v5zMZTfItw*?5|!f%2zBGVf#{J}?AEdew2_twO} z*k1;fc5KNPx$65tS*|PftQmnDTrA#oAZ9EqnuT)po(q5|bQFVdTIN2n&w785A;M&n zC3B7M{jrjzg!Uj7@R-9dYP-upt)&cBS;+IL(#UaK^2kdn5aywHwd(+lZ*#fREG7;p zBTUYz=zyab+0K`C;(V8LwVekR&44U7Ih$e*gpAKsb(p|SX(tVjYiPkd2APKyL2|gy z7D8l~XP2X(FrRLUP;Pjy9iHOh2j8v%%^q>esaXfFp=THQ`K zq}5H#t5~nqp`%-D_F-s14jo~scC*tT=|8Z@5eDX%y1-`txO^3Ey-H#YF2A^@W{a`S z*5%?$BQ|VTO9Reu0#XeybM2ZMz#hl6vqDmfym9=_<+sLY^Lc#F2+D}PntqX zWw+>U+fF$^`<2R<98XoQW&n@I8DO9)%22Gsz@{1u$i0XG)IP=5&NeR3ypE!(s=cCW zW(K%1w>I{2G^9H0a!=I|tyOK2O+0zSAm~o|1=nzN{4xV(E+?z}&>}`+Bo2d645KlF zBwvmRbNs{587WzD)UT`ZS9?7@!vr)a_P8;#mqS=QQZk_&k*MoJk`ejd01_N-f(i1u zz~G@wwdE_KhtXq0%;Kro6OP4ZUW<^$A<#CvN{YscI?b)E zmz&{(GLSwKSyyxgqieW7(tNi3(OM6W>4(G{n4qw;?G4?~Y(`kdRBA@In17SZESQHd zn;Ej{4vZkiNdBwHiqM8IBMC#X2QfV3}&7+%qlt;oN|pGt2ETT(+H6&-;6%cP#SquX$%sEqShE`bXMD3g**~#v(jYxovC0*2Emf82$w#L$+(u% zVpdAM$u;6uOCjI}2C&+6lL0_WYhFB!+Ue+$(NsXGk5!E=eszw$as}Y6;Q!5UI9DK#Ht4@xDZE6}RFN2NkkJ!Q z)dS8cPAJ+P%!=$N<6ue5b9f!c3;eOBssYE$Ldm8ZaN4~Ar`_)kcED-(1{_u*<0l=j zV2|7ZY$RhVQVckxHVDz!({@7K zD+7>8O6{mK`j95-9$O};uy6i=vDh_L)qrvRFicMx>rQRslaaso&zLMt407g=LzwyF zqzS_q=1ua4U?WE|JDAB%qxV(pH5#_tM?d!Q;Uhlr$xnTH_uY5@%*Z`H`?)>$`uyIb zzVO8_?epb*zcRX5+Hb%8zxq!H9Qd_^4*KV>fBoQZd~?jVzWtr=eD{0b`~D9O`Qg9( z=*K_)SLm6U>KBJskBzImu@UFB2E|S{Hum_IxV0RS=-5b-5&0fti9Z6{f*yn2ItM@n zX_T?MFkc!h>8xLbZt}#}d}$!F3U|lXf0eJ>%Fpk|_aDpmLENnNIeeAVQfrI{)2g`m zk#HgAel+KQVX5sgta!*&3&suu4|8M~I{X(@VHg%)wA8N8!DG`We#j?i6X0gLIaF_; zd$8Wjp_CsWh}#ktU*qTR6Vi5)UBcPN_e}*=gV_8kra>qbfX&gR&|}*2Omm47MI$~- z4djz|ziTTpy&MeY!Bj)>c{25F!{D?0{4K4=8&%J&V(8mx82Xfy7-L8_HSzA4It)EQ zCca@9dX%4W)Fcv@rPV(xU-4aY-f!pcUq?atQa@@5)!?7yYa_K{6uurbuqaP`jSrdK zFni;+9M>qCC=E*oMx^V8cz&;#>(v`!{6Y63Cn+7~4}_$;N~>r*qrul0(au^%6e=(J zA$S9Qst#Eu3dV)S{Q^ITZ7W<60 zXw7G^EI@s_m9X}R!GcwOH$C51qBRb$_WY3*c;QuU0dJLvJtI`n(XIHYM7rfQ^89bB zVrBO}vf`TY4p-LIW}^bmWeZA+qSw4~Lgc^v^G-*!#t?lHMB>hJsP`fRce$r;G*5p5 zPdgUwcE4X|e#b#+vESFa-&dO7hm*z1pn8W1s>kW>adb0H5ccCnJ;u^6Xk>F7?gmWL zI?iTs1A^JyvyPgz8%Xw-IpJm@&rzQtU_cyRMxR^7s?&Disgxpa|kT>vg^&FSf1$!C<8*Fl>Heh;q5{3~MoCsW`lh)nNZR#3IJZ4DDD%D2jA&*i-=DS3EhhKK{4YhgS(# z;x?)DA@udZ>Pw&X;W<{!O@1O@M(^IeKD<<=4`%CBns7xueRzd@nxr=B0r*6Fc6jlM zt*Q@LI4X*CFgc+<$W+6`UACwX$ba2}eZUiWXCF`jBJ?=uLN)_U2!K_Vh|?%T%q&D9 zB~b$@pTF|MUVUGS$Lh|HR)gPzWp~>wLdpMy*qm_o-#41`_k}R&mJ6z(K2QZ z?3!XPJpH1G1sOeTf0+vhdfw5zW`uJ3dej4gCOhYHOvs9k)zLFpARY~3G*<^PR(nAV z9BCI6+e{Fnr0YMNGc(;t&a>Mi*B#Jf(J3c)&S<>2BPcb08;>#tO03O@e7he4nN*G{ z)DQ^HqAS}d0t{v+j4|n;LZikp?9hzT#DwrS<9pZuAq=t1mk>Xfz#yb+HtGxjjfw1< z=$mn=+iFfO7Z>_-u*G)A_+ZO~3>|E>GmVnLc9hxMh#V03DUz1PfH?!jjU`yO$ykvZFy?O1$Ol@_FYH;8 z4{Lf|v+H&Jsr9ELITV*;L$Roa9g5336d$2OF)Oh{vDKEic2KwIjy7PUYaX%^ zRWlj_*x(S9{YloVe7R78~Qa;qBFgv#JPP3e$SVdEfbtyKwaX zwF`#rGDL%AEfWD?*}^2bGqRYec{AL{WDc9!#r^5IQ)W9;i~Soqbl9-nc0+6!e+UoD zpT>x7ka(}XY@B!>M2bzQ7?ENdDn9sN#EKiW;Pr$5MkCFyEr!g#y*GGG}h>f7xL!6ZISjA^O!!Tw2OK3R|88pmBRjD)|1Nq z)}|93I328hDHP>A;ubrVf>!Jwm64DepUn|JJj3QNNOBcp$xLzl`M}aBHBKPI*q>fKTsx5Yt7JtXa?%b2)E3(4jiF5PB+G(ovyS(T z;>6U!*jcBColaVljVk;Yby!tEWUY&N)r^el%EUT<3*FhS1eLd0nOGM>-a8K!T}D!^ zBtuJ{Y9TL6CL_S1xSUXPquwL(1+)pkU}g(d0{5Jn=^82q1YODKDs`hT&{+i~pTJxg zu0#WCz!a{~4~LW~X`=)J87h|*4qFYnR`CnC`2%SM5&ck{!XN|iiLB=b5Of~S0W-p+ zB9RHZAl+sjMrN9L79Zxz&loYu@vst!Sx)C|S*x%$;=B?%Dmkn}_B+xfWlJ&raHd)D zSU!%02#RBfG^g~gSgY9}nZ_vBneVO@dtDoJn^rXI8t}P7Sri{509L8ocpgg=S4tan zb-W*iZE|j4wTz9y_cET>N&kqvbcD~Mr=tfo;vckP6WYowt{0l5e@JW=Ya-C|Ced{X z-+V*F9QD7LA9@?L`WvR_HJJ$c*V*-$t*bSTge%sF6C_NHjiMCjYha&|mU6jSBtC^A zgfKyu}rUriJ zeZ)1pc3!g(0yUvJYUh>3vHc+mZDDpZMvTR6H%VI)C@rpp;F0wRCPkeKIMKPNFX&v7 zL8tZ#%=eSd^%OC2)g&q%Cb}rGn$aRP5f!?Isj1AG_(CT1)2MryLl2pk#qNcbOYKK* zvurMrGzcEBA#M8xZ+|&nCHj@=Ug(&%d$E`XY^^B1%*V0%kh*)V62~*?S-aPl z1{NP;v0o6}(oeL%Ky>Kh+Gv$-fN={bC>hLcN+?cE;kFT#UzAhXRqANKZ5zhv*g106ngkYRbx|FBbzRdv|CD*ZHSpG+y~J{0l)>5JPoO)tLE(lN^by8DK8EE67ga= z1)39OMlfa$uRa%#M!)War6JV4*i;b^IwijSddt!1DMFtU8Viv$zVdH&G$)&Axh#rA zGOAV2`0XE(>>u5fItyOfN7CJi#V_hat>TL34N7G^W`=rp=fGTKczC7u* zIjU3b8UbU(Xh9x*;0s8V#?hSQXyWmC8Z(m;4z*=t_;t;#qBAeAupP=Y zhEFx$QE6jHd|q5%UG1=L@X&lI-==PGbTHcKl(-yUB9Ec{0v>C`;W3oh49_J=>=NrjB*Y1F6ae^`U$2OjLs6W3U0Ip#I+U{VFs1bvazPb)FRPl{ejMkT48jP$@5 zk>T}WW$0nObYO@HdSSLiXwv5T&^V1)tmi>Z+AR8GZ$Oub!yF`o-{5lQiy|4bS6NEZ zls|mNlA0UPXEw^Qt14^PmsE z8x^^fjG8S)e{&V-po)lO0u2MN2!r70VY!wd9GxE>dKaQ1?%2@eU1@iC5eC_nW=_^d z#Fn}>TzW2#H9iW<2jtbStmW20F66bgfCrG3V-=%n%7RHP9ClM%=#LK9f z>dMsFANv*Q3vN8E@)3@8RI0NsRJOGQxb|-$z^KrzD8Q)9J_#_QsuJMc6M_aNm4-() zjH{=JzGD94`#&V`UPu52@q&Ii`3r&|#2EGzzZ}IoL-~I0Q2vGm=KmPMi|HZ%m{__$4^B4U6@BfZF^2no(I{N6N%fa|y zLhNb{DzAxwxh4g?CgYkCv;|XxV}fJlnifn8j>C0)aDra#0k7%7j9{i-vjTI?4rT`@ z1}8<=oWNXjgSo-UxaR3KKR6{gHCTYFBUl)m7Mva|3eE`53>F8S!II#t;OtuT{aS;QHW(;6}Mt2R8*bv>!+ z$n|3IQt&daSLAv%FxRHQT(1SZUdQ!D@MiE<@OH3SuW~p(oDjB#6T?a23|K3b}g2E5oaBT`kwjaAkN+cx`xHxGKCpydk`iVIf@uZx5^2VD9$@_?!5Au|2Pg zFbHqST1tQ=i7vR`oG{-*Cueo2zBzwpvc7~aZZN#z6ZMu=_ zR2+u;D}`e?$`Wz}SBDz_-Iig_IRK!?epdj!K7doI07%ib02raIl0<+#a^K*5l#zQx zbg@wgh*;m@GLg@Xn%1c}78eKq zcT29AE9AD%89Y}QJR{xfpSauPayE14J7AVXe&uJ?t$cYTOw~su#=QX zYX*sHzO(Drd|A9^v%0i4_%7eEBWkl2{dw`OjE8a3yivHoJw%jomyHKL*KoB1iiX2d z**iu;Y?ns8Lza%vpBsxj4XTH=^`XHXg7cjMYJZlp>UW2Y><*!eKCD4Bf|X;E-3t~N zgBeQ&-pEB6V3TejUjPXcLM+!XjBF!X@(XB(AY9wKG=7>U)Nz&VM$(z3OfL?3p=1B5 zK>E)`altc^u^6&jOM`l$b|R?~rEfIxbL`Y7tGKbo-VhFPV{Dv#eCHOGcgX0)j?t%^ zh0zP*jA9X_@=%Q)_q@)x_&g3+VcH1fEykalx}YRsX?t04m>&Y=`9v9(263l|B!Qi0 zZfwgN5=-wkH~xq-fTQgt=bC$F>%y&+);YK%0l+2w@NH>`fO@EVsbmWS?g$$l{=)XE zD$emJ8Scn0{zS-^x5(!bmIL?|hr(aRx942eG7#sZpsKU%)1E|bsw($v`y^wjpTyu} ztKnw`q|jpdQY0j^5o|5%Sfb4L_{`r~RS6ztK|L|%d-4^`44i}7?=8Z0Xj zr%`aYq4XY{`>JXpt<=QTcCiwulu!nt-TALM5sG5~GRg-1tP7`^ZS%9PR+E5MYdBz& zZ6mzMMz2Nnn(WakUht@CCbkjU$E=i{X774f)>qM=Zl4s!tJ}hGB@2xU>q%&1RjGK? zwFMPMG8-4*Zdlq@aGpY$<3??nzfx5qX-(^j{@{xlWFguCKhu{f){-nLG`n|>XB2OK zJ;Ara<8l97dsrc|TWqjnUU2L4S zlUe;9xr23=bCv!d>nPOh%q4{iMVv?|CAj@ovT%+XS2C#ww-CumKtf$KX$SLp>qLSJ zOQE#dNxU<=o)BkM@q|ZJJ7rieN_=>xz3D0E+$!=}_Q}N~c@%&lpMjfUsloJI@`D>% zi&x-+ssc%C+VQhNRA9RlXjY$*E|?pH8?_5OqpCpCngaP23+3>5d(-3RtSa&o?2}xN zmf_iI9337Es-1{pAii(fV>y{Sj?5uxRPbNKJJXciDjiu?RUaNDyU+~QmoMH-`eSet zRY-wz*)4HHAM*fQQdJ;nO@VA7EwD`rG%a)$Yru`#1+J(nkhG>iwvZM$Sqd~Q1TQ}~ z2sdgMcuiG-q%{S~dqxc8iBh1+<`KxaQM-zdfH2*e+xH}5+(&cs5kU6uVwG6 zDv-3MK$^U;Ct88PxAc%mi%?$XMphY6#2o8+Wb6GRUl~%KUmPR1#Xf8 z&Boy8SRiiHE^tFtfuyaH*emv?2k`kS@>lJXTj;u`fv3{rdzs8(u}<*6MRs3OcB{JX z>s9sPQL-C#-FYnW1>D5)tQ6R)H}o+NKzTwm!svKGT2r8mX+) z__P!_$U(-9+6B(3Dv-3X0`VoCEkLi_nJ)d=c>s8l^@XKfc;gZxdcxco!ri&2@y6rk zhS^0f=HoHpk#+YuFtpI2SYv#RM~Nank>sSdjI12U{CFzC!vMf-vEzM0dKuTE`21AGtZ5`nFbut&Iffpnf_U zY?Pg3Ji3y6-p%L2((iTpc|GslW$www@vC{`&R}4%jXH7%P=zHq2SJ|1chPETq8 z?OJb@v0LdNsv6-@*RL2=E#AQrZk0MdAVo^0xPb=|@{^G3YCf|Dw?uP=;$~A2pq8V} zO1JVc{Ge5MhVqswX0(jR^4>=J)s{mEE0RSiuBwaNRaM-LpcFkZWA&IWMkG&T!`z@e zRTXkyRUvqkL8n;ff&me^JWlSeuZQlDs*><%Bx+__K27@Tc$2Dl#5?Re>s>w9nZ6@M z#{15Q{1FryB54%BLJHs-VVmsq*{W@D6+UVzTuBV^3aRD{;IaHZ8-r)6%D*~ZKFi!F zZ;0<8kgEU$^)M!AV*D>ss#oH!3G$2CLQpVYe3d_}5OKc~*e^S_G%6@%#bHM_io*7k zeUl^Co_7UUVbaba65JGH1ZInoIeJ|ws^iC(8+pKP0?2FWf7^mJqKj$!DGl1Y!5!WP2=wL9>{R^M^L zqolU3cJ!IM0FGr@7xMvAff{y=19TYUZVWw&s9Lm{>MH9oS}bMNY0l^jXY6u7<{b*` zHnX^yLwr3FQ=t8=`$zR`HCg@;l?@lV?~( zE{ZH>BP|w{Oe3{-gtpUhbA{EX(Y2|9r;Yl_{#$QrOH1!&oQMI1&@+_Ya@#n zkp2{VlaVgnOd?gz*Mh4&QZQ>A(&eO|$H$yQx{~)!HuuCKy@EI9!XbT?CVviUQ-}2b zvG*l#b`@3L@4fC$cM_I>EI|-nCm_wdh87q3lybF z8V2+tZ>CKN{X8pQ*a?Bp6%attgaD-4gRH+YybJ@1P*3zxr;uM_f%DaXFSv<_0)#Uu zE5lrfaL(iCp5v$&XyGdb)KN6i0yO0q)VYZ$o}ESq2SDv+Pn-Miu-I8F))hA+kMZ4^ z_D*yEC|`_V?*D_>tw57qwi!`LJoAOk{lBs38QyGR?!Q~WA4Sv9Ywo)mKO>A~YQ^SW z&EiFx`=7JOQg5bh?l?Ne%ll4l3{RbBLhnbCE^8E)QS*zFwRLrQl#oyo0IVYRSq4wVe)ZXs} zDe$zxK9}|Xj_{43)!yF`Uf5nQXNkY{-L;A{s9pU_o9nY!2vOvvXpAh&>(T}xZmrK| zZN`qX4^G(p$JrC~zX?t3VDGz%Maf2naB&xHR6s5w=y&*@;7UF$R6BIdiem0Ed#@h~ zobA#A_68vexyxDGg2S;3G#ST#%4i^xz;&$j7ENTZwA{>Bf2~&{f$RDF=9!J3@!vN^ z5>T->shE+#YW}VO@e&fap@98K!Yqh1IGo+d`iLYCB%t>Gl5-hIU=2$kY8)FYFK)5f zSu(HgJT9}K9d)XS}u|<%%MRiXC`X+*ghe1NrIg?H4k7a77^tW4gQT5*I4 zG2$yr(jrnB)&>XY%WU)&M0u;mXI*N}cMKNljp!_GovkxlZASTg0sIM>-VkH6qI`+H zKp?lKW-|hL8p4S^zEePwY<{-yyJ`R)a7 zG;x_Wd?w!iYcd10sOf(t4b}BK$nuM9y+F@5DZX_Z(+CX&BZ@XN8}N?JPm$KjoBwK| zc_!?|kg7pLf_w3=b8uhieD#}ru$Xa2iD;@;yP;r1*ynKHW4rc7?D;oR)8DD6=LQlq zxUF~RlwMTnC|9VM`t;L17Z!Oq{}x?0*&&gfdX%t!Bw_uK?aYQXUzmGfEuH+Q9G>HC zZI*%fZUXTI1A+X$XsmtlVXsOrVyVjXB1QqUk=eMKW`>dFJGt%#!)IBe|CSnk&>FQQ zzYY@<7!g2|A(MwT$y-QcKG7oKXr2L`n7uD!Wc+?YX`P{TY*v*2gv0o34&$2Uctzc0 zZi3`{tpd-o0@z4%7=$|Z#$lL%`joXu48NmTL_JuXI_=jtrmncAX(9eVg;aqBB<`gA z!`o<|hTG16kxviwctXR|16k5xn`9WNn@^$BC;q*4=|LoHi*=hRMOEnBCHWi%o9Z8-xF|0Ljn9HX#7_y>1Z6b?a=sj0`6!W+F>+) zn@TzwOd%Xr^AjA6-zDIVhSCKvs~$tPO)V|xxPMHwT&H15VK?MJrvdA!cPSct1rPlO z*fTEcQ7}c8o1#7@j#A+JOP9y(!MH8^{WTu#63@6>TGm{eV2Kzvu#&L6Vf@`f9mP;W z7e-AqCC0w2fY#G9>rm)TD!CNA@P@=WDj zcoMnHSqTj%=zgKGO}Nb23Ahuq(mU{~UL`8vz_hBa35!H8B8fgtBnlcC*%}h1{+K=f z8cj%i+DLS-94(NlpKKBx$&={H0$O|K(E78J=miNyC()|m-0qGi6nYyLc>Ya zE|^Rt3P~qH_=jH~xTS({RRZoL%Iq3tg7At|($TOq&@5h-0aSqhpyh5;{RW`1F>m2iGRxj*jKq=#0({sfMFt9`y;GU43-cjcu{Ea$^GS z=y-08RZ%c-{&_V{YHnjfiyy^CYqVuMhHN=(ln>bZUS+Q++lU*kKFTCDy z#x}aG3!(2XtW*^9&Zu{N82Qc*Gp6Fx+o#X;8OZ1oE`dZCysm+?ys4fn6%*uvvKvbR zWjEvkWf6l>ZEQ?&vYW7_#)gbm*UvE4W*;&^2xnOG(o5Wfp!I-MjP2QH;D*f3#AZ&faKk03j+^I89C6$bYJ~)YJ;1G}(GOs=i5pV4E8!=Z38V7n;U6S$ zrd<)(oP>WcVDx!JkRIK(z{3{S8Ip{wik40B0D$6s2Qb!lFV#%&&2Ah;Bqvn#ai5|W znf{ygq54>4Y)H%ln?hl;eoHITgS#NHdSG-sbdM|u>M>&VXgWBc3)x8d&&ie=X(2`k zPm2&`Rzu(!tmk}$L#1OvzZ0Z38&)*(3}mqu`b@-0(bf|?#5YVk)!jeCIyAHKY`o&- z08yca6yd_a>~Iq4&k1U=7NcqXU7b3*O@gqj;S2`WsT z_T@HZ!3J4|pNWreOo#aBnX>qRfOuM^QuU9?h;F-r9s+?Ww1J4T{Z@A|Kf(`kY@hdr zH(EU@J%TMm5H#}xc((pkJ-JhpWvvLuEeupOp&j**TY^`TCGy4Up5}(GrOUY9$cr`r zZzH5tAtc#{d@MY3rKnvG;YOMJR!gj578WXZ?j9hSY z75Ns&nfVQ6FwGB}fZyueJ?9c`W<3}w)kKw!!YTqDq)ywB*xa3HNfa3>ttw%Wuy794Q! zEI4TNHiEC30H?Rn@a*&!>Ct&tq(^67@vLJ2^l5byJGdlG)+dbwsI-HRg+Wk$XfF4jJ7h`ZN5jx#4&F=4kEmgw@Kb z*nipO1{;dGGT$T;**_rkOyHApOPPw@%MbMHcrmSM*0c2Cy#!BDnkk@XJoaVn zc?4RmpNF3Oz%E_e14SG4$X*AcQq2^7o&|J(rwHI+-AkbZGYdVqFMo!br)4_O-{op! zPlNZNFhQucTh5Cl3IkuN7wH1JG>pYOesA`kisjCnD&0tyjkk01b8&9!fzJgL!9F3_ z*Zd=R>GUeDR{@gv(nR8HT|{&Ykm8Lp)9cgDm@}QPainwNo@lDC**ZL$wXUNhFc z*J7NZQ-hzYau_R))?VQz7OwxWsId0^2DP-7uS)}Pt{C6;I{*aIAG!+*+EkPF?9@ABlmc1q3@DCR6XT$;X7p z$p<0W5lv~T>)s3OJmWP|;qZc#GqE9(DyU;0Wm;MsM1{c&cyU(!O5IJ!w zOQ~s>2u1qQeL+T(jiKW51=R>v5@3ZZDbHv{Tz|5i=*RR?rx`T~!RGW6*#^j~`Qt|p zaKLFbn0YF!5=uZL^)&J$slheV)Sx+d4P*!wL>dW}wBz-!a?ItHe)LEFUJ7kVtTb>?qrBzrzl}hN5JGVDrc)xSMXEnGJ&q5(;)El>f{T z%HAXtPs_@w%jZX3)`~TJm9YlOVWH_V61y{;49$2TFIa)0gez={WDn|=?$ z&w6i_fI`&VS%HANgmWPYr~!Yu&DM=Yl_=YCg@CSiaSv)sGW8uO>|(en{(@i zij6Z^V|h90w5%0t__|>Yuvx5|%tFBYIOWs8xQj^6D4**{SKqPD0bRKJx$!i-!X_9s zMEShv$B8mq0z?_embWVD?89ITISg$2K&p(&F1@**ypK3LvjG(hu#S<5vpkwWW(bDrwm=RNq|YqtV%wkUu1s|^6ykR< zMB-rWwrUroYEM30wC>=RzEPRw`@zZSBG%|k7at6C(Idh71n6SK2;>RVMMQd1x;XPL zr;Gh3p^FG|E9fHD-7>m})e3ZR3;9L)ZlX49f8ZJ0S71?qB%~jmXg6y1~JU@Ta z{YWb!>e~tvAG0#tyu-HQp5JD-72&Sn$;8K5slm*wN2f6DW0Lr2lZwvLI&Uk&wyXKG z#{+5_Av+c;+jzwqznW?d+q!&wCWz%vd#@*m?+7D4I}6ZBz$_?VyC^BTr$g_bGZ&X- z;-*Ypl8Hp;ohfuAN1;cOLf2Q~=2xi&co^2z=mJp!(lmK(x#mI}?w}Ot?gqCXhcfoV z5}+}&DxE2LD;L%4des{K7b0cs7o~fzRe9?Rs59tVV0B=!Er4GjP{wf9YDof1?rFer9F@!~q zHwXev-4R#s;rVY(#*Aha*^=vkurDu^>kU}YKd)D&HNSOk07d2sT<<9q>A+aMMsMqV z=r8Q=I2@~6sH+0d>tRSb4bP7|*c#HE4qO3qnh;kmF*^omyoER)02Xm8iW15`*Fw+eyhGQx$Ctyvyw4sQO`{IO& z_1YAiC?;Z|u* z3XVGNuH(nCV8NKk4hq0IIrd7UM?5BwJ-<dAH6~!K<)!AgA?j@E^x~ z=tlE!h&E*Vw*f-oMlVO>XC~~-x}87EjC2j=quxhScF0iRVG|Rq3W8nO4efxSF|uZy#rhlJ^845yK~oz?~|rr5BCc_X)gwhZH#4+%Z;`_SYpHQ5}y z(Y_?9a#d>EPpECH4~C#=5(FC$=SV?Jp<_+#is0sCCs+6m*PznVi~QB>qZfTHPh8g| zJPK<2hj>W1B}QZ{>pd#?aA9M|Z+iUn>E>BM9|v2{z_oDlH=0}0uzXe5NP3_ayOyKpN!m;=&-;H2o_aQZa{=VPIH_yvfMq{y_KHm~Oje9{*Ic(1*LKlE5^b ziN%pHTUcd*Gr{jxoQ2+Vu1a(VZbs}*4kP93iVS4LR%sUNvkU!qXAO-P&iJs_&@v)n z*xG7y3(-KpqLMm)ZpY4NIUCG@;1Sdn+}1aOiDG9*c|jc2Vr~%``+&AASC@X|JhzSY zXvgLVAgt;FXIxq6tQGg|n;l4@k7&#IKwG01c5Kv`jIDFn-O)!XDB>{eOs6I~U7U=a1Bry*1Xzhh?bNnwzn=>xF>^{%zc&2m`U7Kn zJJ^z$A^XITw#R3O9kI#t&r|f-1s@z-?Y6reT0L#=ed_(Z{|XmhwQc>5I1-myJ>wbA z7<%Tjo_*|dj>Gj;&F4Pv`7e0kycfL~!{uyltgFc9F3Rz_muhsoBcJ2V!->z~24Oh= z#Qg#tg3uvM-=-1@|dkdJvjp^z`X7 z%j{Tpk!U$c<29TznLFzGDmSQT0`Yyk{-+o2somzDYV1pHQgB4Z#Rk*R$L-*r1r}1>Z{Zk+yS zX@GaLIGzNv4khv2$9*n$3Tsif*}A3e@{u)7%(ja+ZeooF62Cn=P3c2bDLPG!)oe*Q zZDTo#+oL-TcIWWQX>fADkgS7KH2-ahlZ!iPyFG$CRU|HtN9oD1LH)Z-cS#tXmoWNc zpD-e%;4oca#pkEuF56Mu?-wC{cjc2ht}Lsdf*8x;IR2O-R_6F;I>`%T@C;V0&e|Yo zOh9?l8$7{ccsTO_a0fh{U&pH;9Q+Glzzm~DVxJ+xhr>Gn(Q9ZXonYYIEm_UI_OTdk zW-A}&r6Tni+BN@>XQ7JhribOWfdFuZ;9Qj1 zkE{}%;eB4|yEF}t>DA9te^!Ya3!{H|D($0>;$e#b$1D0=*%rZ$+v!pNOwth)7SV12 z;OqMn?t3AC!Ga9N97HDS=+rY#yZ=;8gHPe#2u}Muom4!^bJm`BEk=^oC;r1 zthTT7)sZ$#@N~4jhF%^KUZQq9m&LZRtGNe_Fe-C+C_`FqZfNHR5CgX0)IXQ*XLseAbDC`ejEjEnE#a+>N0l%bPVaNM*AZMWHq=$V+hX&<1vB%cmn@pTig7dBTEk; zvhq<3cMj)Z4R9`q+-a5|G2vSf%ppK$XbGDGoz z4F!6voqg#Lp;ZhCY`M@|&}$ozu|U^rC6Oe)ATfH_yNB2T+Kk!bZWC#6*zaw8i9av^ zISzLiewEDhG}x(}Wbd-piap)%vwY5tFBW>r1|u;5(b!YS+86|h5#aRrG*J1N2JzVg z|ZbNkoM!?sZw0{Dmn@N5Fq5H8+vQzLIC0*qZ;^q{V2L*-94t&4j75;GK&s7)1XA(zYCtqP*2BMdVoP8Ttk` zzJd}P`*v#SG7CyDr)lobIFwim(J%u89d;d&PqGLfWT6WWFwsR`{0Omwod!I(hX1<6 zi*+R%?H>`2bGvn6xuMDU+thgRqp1_lXxKnpeiJepETauv7vRMY^IwqYW=y|p6H!u3 zg%^J>q2avP?6@2?4oeIev%$4^oH%+c!T1r4AnwD2%B@8L?8LtRjiV_qL}TBZ5joj- zj4!2cWZ`o}(GTf5&dg$D3PyAiw*CFo4IfQ5F!^Y*%qY8xAyw1rH}SwKi;SF|!f_MJ zNk#Br9Zr7JjY5;IEOT4tC}OYg=O2hz6md?pC62M69H6`#!;ez8{WvNe`P@Pa@zlfb zYQu_U*{fm}VmtAH^JCkoJH|BFPpU=x$*P?FggmD)R*UwNaWizp!yjx7Lm)QKM|mCz zihw%XzE@bk4Iw%3XFr8?7XM$`fp@z7Cwh zISWaUFG`S)nOi|Tt+5NNP;RHFVH2huifTUE;T2NDT$129FE<M_Sv}n zU)H`t!@$8A@G%PsBKP%E-?>$6s%bTof--3L4$&$Y0+u-~;Epm!a8yX20~xXjGvHDo ze-OFMXAO-XBZ@RmYZS=^huIv$aCpwdl1L&mmVb0EhTu=@+eDuG=la96K2)vPM@RiQ z?1z7!`MM)Y(2{V3=#iahi${ncV+0X8g18ZU5IVxoUVE7-el9-y(io4=(}OS8A%`4t zs6L0mDT^Po&JW@9%$$852KpDh_$4pJ=VdQ@IX@?yF#i>=eAS7sehoga)n~zi*S(&f zH@xvL{_?L*defW#`YmsL+uIlZ%{$)tu6MuZy^%T_+`-li(Tk5;I+#Ud7B!y<2C5xd)At{xpli?Lye zH-|SCWW!f)VkHZ*q2Jq^go-86J_ygAO&TW!aN6jvsW*QapeS~SK>mV2EIi=|Jr+tJ z$#aOaA^M&j8ekJ9mh%~}Vx*16@^hT?1w;#RHrN`5F&^jp*G8L;+jCyca@j~5*oI@I z%{iPnWpkz?yr>RPI_{$$u+S(^Sypt2)6nJFuR>3BvJFccPC(=dblu92W4bbKZ`%SoCHIO zHH?3-?Vqn=L-0C-9YsO`Ljo1ArV!OGy1dXz5M^CgE=cuX)2h0~B+|QMmqIPkH zz_iPHt>FzJjk<`HV`l0ScP^X)7;V^kw_$T!ZC@dwl{x_;-zp&T60{g$Q{16vYo*8u zOp@2%NmWgWdvQt4lL!pb-VIVDnbiaayxbO)06vljhy%cg3TvFi6K`#HanuK9QfoX; zGR9e+0Mac(Bkq#;q#VNEOYo18BxXffHr&*%?cnpXpr5OI;@I~309*>yQMG+@Gy1~> z+{2Ea3+Pm;!=%JP~zMb&=hBNjYEhn@q zF_hPsex0BiVI3==iHhP#qSKfFbS>Sn? zt~OH0PuG8^rhH}7vnw^0qsc#};?~z^Owd=1C)@@p%9jzlqr)h+va}g21s&AUC8tNV z!4|<$YA~}w5^O(RnjcLjrZCiN^kzJRtsgPd4BT))2Uhd37-jDsY=1mV&~dgOJz>i^ z_f(_=+ZopQMH7C#&5*=QxmbcsEl4ld9P!`$7JIBNtE(8lH!L zAWasi*w7rhu~Y0gAHi8fmk6|51RAy@>}q$8mt2~VcH-PuI76AE&=Y+joK5lv*qiq} zdZOQltallKcd{goAI9XRQR!;Q%fYJ)2+aXP*@f9r{EVflwsLq#ldpMF+sYQ(?I?b( z%>!g&z5tMYm-zV*hXpD5Bz``^ho_+!f1XVIT%X|E%45Z>__>kLaNLqW^TY$WzD$CY z4rreJ+?*P5F=Q}cJ#yV3^eB+e6vfcm0$?Us3BZVEyBNBko$*Naf*86p0dp~g5O{#- zB!)gqV2mcvKo=B;yAwEP?{;S4Bnh%Eh@nprA_J5Ku~ZCwGC?&0qrET#D0W_(c+x3W z2nD;0V(3jl4E;-j=y;kB=mdC<6VG_`pmmrRm!D2h4Np65C>NJn;zJZ6_Ytxg@_?%w zzKpR3&gUXzD98FflNvNawv&O32oY>|yIo9XAS5u?Y0BxaGnH!VV3fKU>Vqxp;a&z^XcM=5R(YK1nDyD*8CA_3Iv$T zY)yolR|i(6_Ajw0d~+zU1*Z)%U9u4N#d8wDss~v4Wp-%+R#rYxXATa`%;?jYqLi7VEsj4 zCvffxgElow@TYsG$W*`{_N-K@{4iK5L`%gpGmKP+g}yqs&>7Pdqogq78e%TRcp8M4 zIZ|KNicp-?>G4l;VXmF-r5X1>Y&N-dBWFWPeR+b#!QMRk%M$z z0g}yh`w9%OGfs3>oVa!=wvjwTG^F_o2X`fwd#n~CUmm83qBH;*0mLroG0C7y5`xzl z&6orPeYu@t4?xpFQAcRf%L>%EDnY(3ON~5!fHq@9X@|XKok0X*OE&Y zQykJnEpJ6IE?vMMGg={J67-7!)Xr*+R5J8q1%TuV+3ihTL(iiD zkeG&kKYXXIN_e)2k-{&p0}hS=Ba`Y&(LkYayfk^ud_VvTW&veLHHuQ?n` zee08j)`tK8-`0!(80CYtiiv*7e^Uao?lQ;{1~$nLl2!1d#Cs`e#oqW}SAabM&rNk? zy8pny0S6p-;6Vo+d@znp55os%rbirc<12QvX|3y{vjU{;r6BS5~j8UR}Kge`D2a@poPIL)Gi6H{kEa>P`4t zUH#|k&DC4*cWZSG{%)&&7=LT4x8v_4)sI%OqC2Q#Yjfi2PL^$K2=WTYT3n8csE}R5 z4fP#W(`gpw*z&SggyifSB~>+7a7Cwr3(2m{P`F56VcEn_+#*4XpTd}fBZTfKs`f3$v@ZyRv!|bAVCET4}?r%A9>Fs5D>r?KB z*X2__1+wVk76#rLn9}Ti_L5A?+=eUe;-YHUF$NL}`UkE4fh3>|m65>%g<-tVDA(k_ z4iSILvAG})MJAZY5H#;h6^>fxTMTKPG-0$qm#`AI{6?lOslQ&JEHUtffA>{Il7y>Yvo-)cKLqb8M5u- zi_PW|{_^+M17~=4p#8VmnPZQ+Sm@2-70+hH_qBH&{;ZYl-kXL;wr2Np3X`ES@7|i> zS$TS%o4!lK!z@i{m?q$(-JUsDLg^i;&%=Sm4^t*x!A{V{N!tvKNp5d(aYDrG{|kjj z`&K9d1>F!kKOMk1B@Y7p;w~Q^2*;krwQT#%0%57KCK&7~3Fd9Y$+uZs2XxhW zc+#WMwzK3#aR}@*87a|plKddYf_`C)H5x|QaFYB*{_uMLVTeD#LmLiI=GM)-0ea~$ zh1&si>iY#2f1St;XC8IX1&%wA&J-bciv zoTbdo7=g=p>CLG%S6$3CE<^e{Z+|75gXRYF6RiPvut%>5Jt7kM0bi2<*R`bPXGUi0 z2mH1?*b_2fZNQ1&TH*)axMsD#*3e=2OHq!$=Qu%r^lwk_ZS+|$h?a~gN)8e)_CfJ; z1rEb3w!xX0MIQM8(SS=>n5hcVXtg`b-j&+(jn6!l78T<9x%SeZDl6Ru<)D&{sX&s# z{HyLNKFnSyThSQNdLhx8g8KKrwakQSZJUo{Uyc_%lt$6dQstG_RwsX!`lUjh<7`?7 zqgTyBQZ;ln9>manbC6Li*k_6j{*FV=3<%5!5Il=PPt!0hb_2$@SOS;Z!#NnChu`MY z(99+nBTS9RH6mUZU0y#|!_UtEIKUTsypJ!A;R|@+fH9LOGR^d&l{)TPnFc3O?HztX z`0&$WYrT!1^65yn28(_damOt%Tt|=d2gL3}to7l)-o~%^Vh|`Htq2k&@-~-{@17V8 z3MJ#%_wa>6?J3CzjV)u05cHbdF2j~!3an~#ngVB4hl+xoRRP;C6FK=+O-|S7O?TrD ztZ<+f+(4YiD9LngiXHeIq>6-Ar+>PZatsl2q*-0VF4DcK`=pS5iWTT?g<^VfH(xNHC^B#`Nh% z?aeO2k}Og}GLhc;bnhexv8&#<7`XO=a;%egunLcoQBa+{oiBKnjC!Yt$SUY9do~?i zK<5A&w-t%-Z(~_rWg&fWAW|7`m!VkNQh|8OlDzh8?nH^oeovy&DfQ%37CG$1+{%3T z%=5!M0+YJCHX-EP3I{*vEfT3z2%ak^U+1H#&X{HB)D;I_PIWl?Ilg#js^y-8iZJk)`tI7e=y^} zwSo_{3Y>UaT0~v-5%MDLguo}yG!1Va`0~J+2i`pVz;vI>I!$xEhd0I0CfVqbeGH`T zk+bm6ErieAk+VNjd1{P@$XR&0=3`=)v|^PueQO;ZUDsM}K?w2nl1q^1i7J+P&0=Dl z7ot(bcjud0UTDe+N?oUpJ}!myVQ-m=JHTvE%XmmFujtq^M~8Wua%$p8q2*8zotzzG zhaaVxzK0-EjEe_fL%e7cm$7Tz^TFCtMhE+qWufePQE30O`LKch)S(_9+Un^= zsHdV1pt5PI9?rwOpa8RxgV_d)<5dYc&d_f23o%hY z`t5o8wfEpCjs{aYo21g8SE;c8HRFPbjTQC|z0=*;oii7Nw0O_W)#* z(|&O69WM=nFTFuCF&b+Lx_!L{ag9M$26;MHdEQbwHc*=jb^YGBMrT%#a`{ZGAR3+`4;i0B=fIc-G{@ zaAn}nuV%nwg(e50!7Qfic;0@nI#qVsI80r@ba83885Kzw&5?}`mWPTeFhokb81OMg zGN^i34~6A?OKR%tHqnQmDM?L;EBMGG)fDt{RJ@5fIg#EMQ=kHY9f^iAF5PG)oBSny z2T{0x$(m+={GL|vhZ83KTEqvb&qf=JD;DpD>`GNWlB%q=xJKLd-Nlq7>N}zrkE;z> zN7Vc-{QhuWw%(Bd`G6ashpU*bSvFbU0jsrJNCDa&j;&xS{NZu)e_4Z@0=TFsz*)CB zdqj5PHO)uc-_Hu~zuW%4FTDR=+j{`P2&gST1!gSofbHFw3b59^aA~Vg*S>Po3#*Xr zePJP3PE%HQvxlkjm<4Zt(h8>*9Pv1yn8;FFKb}h>N~k@I|m_n+G4_?|R1tIdmW-{L}YP7m(@^ zOZRV35{=bnEzjog%8u|Deh>M(G@|pw#+CY228=LtVDvtbirdn666uLnKnW zU#;U@_Z0`+Ch~L64-gE{(X|ts)nx$Cc!1dM6~_Y!BWUd9Sp6Idd!6USc$BUA<>`Z4oI+fEf%-kk;q`x_(Nv$c*JO)?L6dY2LFldXnLTTJk(E%+u7x zX>47r8E+&KM8-sg`6iS>c5X61w;(S|V4ay5Hv~9tIka8rz)bG=ZI+qLogy>2A~opD z#0GO9)8L?erx7h|-OHHCl?jwH6NF%4C>&qlJ_$3qDgkh2B8xH<5_qYz?;tZ~-_LCB z={IRXF<@;&b|OkBRkMznmH^=Xfp;sgp+w0ooZ){^f!cge55b6OEA zSN#}DZtHm}tB)*4+=Vw*^T-FOrUFM2voVfDJf31)3ko0^A-hP9lw~;+%s%SaMd^{} z7=tY3mS7;{mTZEfq+p!Mxmrg?5=UrD8Oarw~au#VStA zta1Rdy_@dUY*j6RG;@Qx@oppbBn^`7eqn#O(YK}1rFJBNz1mJ{_7gz`l@1ToSjMGl zZptHdcB<`2!R`h`fY&DB#gzRd0@>M=Mcy*O_XmVF4F-XxN__L zqEy$>q2Efb&?RMsbo>JIHPqO}Fp0v~gvT|!yy)=Cu2?7Z0IDvncjIc9IXwW_P!dDr z+>u)hOT^#fuQH)=Q_JHip0OwyAGU|E?8D|J`sGH%>z%^JycjsTBV>2oU6v38$y1B5FfLyHCT>sNamzJjrbf>9cpTLAAPrfDcg4T#t({Th-5$qQcK3HY+Uv{Pw~qu) z5VEtDX3g5`j8>S{i^mWKk}rWO{z}ZNA4_Pu25EOU2EK)AK+{gIeT(O0JrWM_eO6P~ z?=HZcXnV^+!L6xjK{W60c+EX};F*`=au^BAgUexjiw^PakiI#VD(UWe1DLw=$<&>- zcEV47Vmf==t~1bDYn}s*5sRxktaJ=sJe}jJ4$cNx8WWz>-IH3klRDdOqqk~1HJ1>+ zH&yYII?KX@6jM%t;iL{%T)T(Kdhhjy(j>0!Tl(gv;)SvIr8Zp|H;=E3M;hrbm~*4t zd?3}k)cow^^_6RIL$Seisbaw<`L9euvE4Sfd=i?>(<}HSC#{S@kFnK3bJ>$;HyxDi zhjJk6EJuRzd=!p=%K9y+&z zXdgp)u`vta!-}Um zyk7CopxyYWodQe(GkExlWii7uEK&id#c>9^51&|x0y@3W2GCWXsgoo8+PiclrbU&! zqlN`(0VY4QL8}1IgBn964hr4%?HAA4{-*l&E>59dDqBQX}Eon$ZWt1BqN_OXVx@Dmlx`I`W+HS-R(3~ zn{+&q>Rp}c{a3H%R_3`>U@R5*jTO*JPX(?^1sp=zl5SmGxODo4RI#w6KfWuL^q(`? z1X#h#oE21UW5ZpI?7Im~L?oln;CeL=MS!TabG>wd3C}ciW zLF98lhT;w*p2jlyxzttMRI84(n41=8&7)J1RMnI55Aa%qf52j}jl#b^G#O5k(O3$M z|FVRe-`Ql&Qsb^hnEDC?b!RjhU*v%4z{RFc)-x!%gsb9b+mevLlHf{&b}!GM6`jIv zz?p&~>!e8tZ7iW|gm$n<3iIG+0nY}|gQi4hEO{VHLXw%3!sf*H8z!efA`(>d`)dv6 z5Hj1sg68``Zjsn_M7#)L%x{i_TZZ8YihZ)CYmq@5^$f!&+x?gznFZEg6xA%wZ*Io! zMM8#~T$(C+D0~pn;t@^EFah5p6t`F`+qMObjD#6t45*L>c~6DZ_sSWfT%AVIiPG#F zPL$I!M2P{2M5)2SV6eL*PLB&nj|^5lZ84hKOk-$s$9ngIHFNCRX8Ky0KM{Oeo{Mrj zE}p}<7N`}6;3ve?phxHhsX5!R5YCbBm|aELX|>&2=$P3_Ch6GpY>!Uvr^Sw=Nt}QO zR~S&!3S-n*`RZ!sFUhyZL&?b~0N(CH37d(l~ z(*B2Co>=$&{*DhyrdPYxFX6b(2i&uPVqtR7@D1kWnQxwA7rV8W7rSa z>zd{!XcSHJ1a~t=;1}}33-*-}c%MgOi`>XV9j2X*YFdb;(SB+pK^uV1-gQ#!5YpjB z&O{B%(*Ss24Yh#7D+AmZ^W+?&nlc=8i03Cv+yT+Vd=`_n z*+7N6JZ!}^T9AC1##-W5xH7fm4v0M7=n%HT#A9-#;27vcB)cFk&VVwW206@2j0Wr7 z(MdtRz^)JFRt1*`g%Pw({{=)nEBi1TBbQ>u#9CD{$6Qw>MBMX~R}XYv8`LKY5h||w zN4a!a0_u*ZSwS7A{aF|yj}>kwJ}Sb^4HHlM6{!uMc9Xo5PP?0xJ50M>0~y&0<#>GH z&L=)#(+O>Q*$%!c*K$HI7k9;z5f&gR`yv}tpKi+sxLlRG;fD!yg657hXFR+*6?Epi zYtexp)0|yBA+lu-2AXFj7*t2VR0>p9F`teBk$dDP49bxP822y~r6BSa zCaBrEV8VE}kEb@ApCH`_rgc(&((?0_DT|T2Q%f#J%!*p{WB+8KWYRwGKK{>aHmwc+ z-~9)(@7JnWyRiB4j?$hUSbf`kx-CYZS8kYY&09BgEh!c3Ii6wH?<7TbUFFv0b)@-d z{pNEKs{eu)ybxEB;wI9U;S;jyzWUX#$>-C3+uQL8mya%bA3hT;|JN zp+C!&o3iCvhFs>xWoF!v4VRg4S5-mSzAqT5754=X=k^6iqY2ezq${3lje^bbnCUB3 zEI3Q234WjVB3assfSiM(s3ZejIns7vOi~C^GOhRJUbVPg5bjy6nM&$<@!xga4(#MY zXMI-TdziljIkO>Xe?j=M9-O{tqFd8k&7uKFL2Haa#tFm#bmnc~91b$4bDfb!#}$tp*QC`S`?-|-;TYGxEPBH1kuJTBaoclo zYRcu+xu8s_HKpPDb#zOaUF9%V*!WzQ0cIN?=7ojf5OZMx`}CbYlMToe{IKS#ZEf=* z?tS!2*!$=gba52RrF8#;0=cz#Wx~f57G|K`QjO(d*8$@4xhjEmjb(*RPfle~RxV_- z6@d)45#&bnyg5EG6VqZt**4Y*<8H|5n9^b0Q15<+czZ`j=53rsx3-mPm;O2t1 zq=S@U3@+%^9AAZg1mDR9Zd|ic0AJ54-kg+{oe4+yQa7 z49dQrh8c)u9RGEBascE{v-7xV{0E8U>b=W}7cSA}PL9U&zZW)jT%B1+3~(Qz{#||> zXA;=)F7(d8_-lF>bJzf`wdqhj+DyP=Fz)`W^40vIrc0INd zd>*w1c00DR8-ItnYS`47RT*`LuuKKaD1Z+oBE7|&UEd|bHjM^{$m*xR4X%O9`^C*mnYXaS{cazk{Pd)o61r-N9yw&CL7^$@&I%CS!=xF)9wl z(V+t_VC5Fs7fe?Az>}hH&>eUBS--J>rxoH~L#q z1ZfF8RiIvZ8fLX1t9m%`<-vQIcl25bSTdxb{9us%dt&C_O2g*f(SNN8aeXH!R`^%z zS>YZzeG0#<&G0*xjL$iqXCvsM2h7Y>?S#&^6FTk;{bry;fMEfUEZ)>c78*9C^*SlP z_BQ3`wjOLK;)?LfM}c}n+1&pE4K>G4H^G=N`d-4wr5y_Fu5?(g`wElZL!Yj zuQ=o&P7p_d_;G+>Tvrz|yfo9|>W zVsvK7wv3I0gP$GuZhv4$UaY|b@~hB^=J<_!YmFzC@Y_Ta&Jtb(xIvMH;|DnRBeJ!) z^yIcBq^sd6ML~1Wv&feklp(d5Dh z8*k!|!P2jobDeF4U$0vQ0(luRF-JWo z;p8%6C^N)u92LtidMe2+ZQNx;O^#^V1vJKpaiTyt4g zz&Xe>!@1ca_pdfCC3qEDw*Ie(Iv1tuq2OmyHJ|L}o$PO0LS=D3f$m*&BvIiBA zO~N@YTTB;^G$|S4RB&@i11;@Ml+Im^>p8spXNnYOYcw-kt67|GoE>KCL;QWeZ9H2y z6$Zc@H?o>arvZTHD)^Vrmav06M{c%mA=2i_`NU`I<^r<)Q=Tm%>)1_epR}md-cDTU z!_mI@J1MmjGpw}*Tp8U{y7&=jNX1oZ9?cH8<-qpscM>6bjdWwBHy1BHt_HCa^(#~L zpy1{7JLy)sb;LYIFz&6~?zN@WlG(imeXga%l->p^20hE0g`j~THhqrjL9|jq`Saavx^~ZKH7!MSY{*Qi=ww7Ea91u+iToM6Rj$nHqZUHnas~jOc`u{JGS+Pcobqn(JYYkyb+eCU9oZi0|C(45)a({rLoJWmQL4 z%3Gg{5gaQ96n!C8%wz~Lj|*J&;C8y{5P*<_xQ>JW;KGD@-*QIz_L`mUA=T)zG_wbOQ1KfWUPo^v6L77_evs#u74daw&e_tQECG2&nvSwC=1}(+lZ8PjqVX1h&Z>3ora%payDo-#0@-Dps4W-=rQ_V&V~a^PlE{(*c!sgIB?Rb zv~hw}(j>qDZIKYrG9S{f&(dPR1W+%e6IkK99H8eWH%tNdBo$~VJ@sxTTSZgDyvL=N z-{$E?7aYt(xW+&R5|h?T*S?^ztTMjR;TKPfIjJH&KUJ*(QBSs^cwq6~@;E@$vyfpj ztS`!g6pqUD%pij=WAc@Bv=4K6I7K&0 zWT7aiNZFuhho>@(x!i;cPpm;V#Dy25peb!MS9Rw~gcn|-IhM=A|M(sbiu)Qgf%3Us z;+d(}e$HaDf;Gcbx{etJ%7BFB!g>URVKB zRsy5KBJ{&U9eFN@|z=dkn#Ry6yoN$8bRQZNZxUJL zEPuxXu7NglHW)Yy^npk$r3b?o87iht;b?ceJ#Ex|d_V z=@K2z1)zPC>xn5TNz1z`;qRUyb4!MGOw^6JbP^-sjLJ(>%RWaFV+EMlShP)*=pw+v zFYsXW@#;mOfjv* zb*VR=R>F2I%q`a9I z@!8>Ldn3@MN^+ckq)^%X;4u)u)-1q3kZjFZ>$RIZ3N#_tctUS=x2HJIW?pY$VFyF+ z2(J;v#?DUC5i2aVgcZOFvfiTv0oK`rAOW4?5NYEwk^)cj(k6LOgU?(*);?aW4KmZX z3%uX;!WDubMw+cCDoFv>bZ(gMOe5uHTBZn!lnrJ=yf;H2QUE%B4h?AKpna?WjZXDh zXp=~DoO1+1C2^)ExmJJ(h9}Y2$5U%=3`Y7}v=(TR-?5Oi9{9a&Sh3A@fzIGqrY7H`UYZ%W}V?;}+ZJP)SAE_kqQ zo7zZ?Z&e1;hf;$+Qnr69Uq=&;)E5(|t;>u4r39d`eZRYkE#H>rMK?B|cIZ4}Y|PRQ zYOV}P&>*4B<(AZvR;t%0YNhGSvjNF#pxGJ?mWT{*npM=!l?(m5`%Gwg*!FwXZ4VK< z-=%Qd=ZB8_FpI=I>`c(I3u0oq=|x;DqGENsUM3_K*;)=zvX(=Uu0;u3jyMvZqwqQU zm}lTK^vq}B^Xy}v^PJ<3JASw!*ZttQ53l|CuXyFFPNdWRf(7(g@GbK|amTzdw_|<- zr+alu@=~~#ZfPr4@l6G*cvinQMpb>(z-y8 z??K{5=2~DHRyss5iz_#t^thEH1RZF&FOp9}SK}d`a-YbgNi{e@;`^&uXLbPbDuLL8 z4oeK+q%T1>|M4sE3`lJd85DU!>eq1CgyFp2it2a)E*{XQbj+Z%e9HL#avQ-SVb^t* zwNM_!Loof#K9wh5IHkdQnnjC}7M5BHG9Ao5+LgdO3w-jzG#P7ci~2Gly^z*08LQwV zpm9R)3Mj++>xMB7>`O2VbZ#C7Cb+hpu6Rs9{osS{l$IN`~Eck_6dX7Jf@X@58Dh0;x# ztO7^=3U%YYv`IK-QZ#rybTzYDb8z&+E^|-Yv;-G8f6s!Yxkg|QM3IKTb~O&icie|( zVBxW1XlB479gYxX+7KSFYmS+H0-g-A0ylvzQg=BTo)8iTROe3Pr5bW8cV_W1lL+Sj9 z!OAiw5`mL|Q^;FFoWhQYGZbcP@)^1(VeT_z_Q5AILvmS`6_I$he2P}(rpSVGOQwiN z+#LPZ1XDB(Q`E~s;L|FMj7bd+&q16jkj*0gh`T2L^a-JkmGYzPPbb{GK4W5wtc z%7FzVKh>HF<{l1levy7I0d;;&R1ne1spKv=A~ejnwa-$P9boqYAb|rHGYXb+%`Ya% zj;<<{bIq?4E=_P*{ubG$Zk)ntzxbv+xp43v?lw`Y{-!fhPEu|$U48x zhLKnapt~A!vV+0NKu^RxA7{0GCx6}v4(>@ucdS7TNf`&Fi4%iLuyk&RgJMQRM1(dF zGOlP7LOOEMm(T`cD(?&MwS>?uoFApA%1J)cg~0^kERE#)W6>aSY04>6fXe zK1(!=aGg#rbhQ>{O>LGovG>v7FmId8(tjr0eU^|40Nds#GE2WEo-k_IEVZ5trXJ<) zJj{~Dg=UI2s?7`D-=?1WEHN(=W@!q7SIn?C&eDXE_jl~Qoi780`M~Oli{Af9xce-b zt>KBx5@ecaHo&bm=S@Xm+e)#y}b+G+IlJ=ovZrg$2S zo%F61ed0#i&yX?m9UKjQp4->b^Q18t4}xXAmkmQPtu&uWxf{xDMwYfBAQ!8aU1LZG zxmh1$?oXLnNvjmD0nHXto#GvR4tC&*(7PJapYrW=ywy74eygSvRjnG7LbwhT>ZCTF zl~8!hOe-vzH3Uin#w^ClvJCQZI0x(O1Z%0?9l*syrJv>++4{7{)XvWwE36~t^~D`M z*8(Bu2I~9-*$0Z%4I+y}$Kol907q+CKv5-W6+%htevCARM&#dlfQavOb`Xwy&?RUt zItR=4rtNmd=6KQn<)Vam!GLycFQ~M85-JVUS;a@5FuH6+#-2c(jlQDcWmAqox5FSb zMv~!WG#`Arq!p|92(t<-$JAeES&SBm4US38aa^E|w-_?$xxNGC;2^hd`_Gb}yv=sxR zz>r;ugL6WbMj6xJ{LSN`zjD?w9V@Nz3sT4YAlBAM`9Um)a~0D#g+q@qKKL>iDYenW z?rVqP!-DlR#i20RHWZ;z4#l?~41>p^uoP3NR~MyT`2j4A$?Y0OJb>NePMILNeEJlY zXl;0+KP=$>N+qmbT55BqTIMd~d8k`a*O#Oy{LkEK=D}@aeMnK*Y~7R(!&}mdRWir5 zZZPM>u9LG!u$({vZw6%?wCUf|P%ls59x}#Ggb(Pd!`Rv*V=MEl$Aj8M5EjkxNAr>J zXD29*lqv2|eYw6sJH(7JOJdc?!^9I^B9n~(A~S&&Nxu)-%P1A2=DsnfW~>uA89avi zO9}_0?&ruKX9)pmPQzC3j@N2-1&$t^Q~HFf9?K^@Cia0j$wCmhk6(H_GHyK zcErZBM~VJ-1h&x<0{^l1;t|V^+F4+aXtnv{xZ+3>#T6H+>X^9|T#7)b;;Y^TCX|hK zlRC3?!=dKAl>R+(sbNlb=p{r_RP!`EL!vafeg50U%u|jkumv`EK(=zI;>{giNyUfN z=n!l1=RM7PD|Mqf{y=5Br}^y)&GCEUnaTWXH{pTi{l1wE+S-keGyhHOt@7VEQ(Iq} z`4I9S6`KDQhlEwan3PxXU(1gzuTCW3S!#Qz>_j%p@wY{o7T#E@v&zzhq|8^p+Cn9F zM{uFGlOi4YS7X~HM)zO8`4HZ{CyD{8SNO_sroa(+>1^UvckX%yV zmbYRvAGOm3(>Q!FI9JF^kq5WfkLL^VyqZ$P&Z`p^XCy3Kif~doN|Eer1(_HRrdK3b zTX*5(NCM#6V(w~+vr+*cGb3#uEN7wE!Mnmj6k$ehj{U;CG*iFNPLP}#XOFd^w-LrX zaLlaj8>@=feUNUgzyj_7z%9Ww;ce3#-)znhwgAL?GZTJpYSMcrCu9!k{B}1zfkpdF zGS6eYs_*N*xV87snikzo{yXX>i_VMS54lA^PaF`nZ}O1Ik&A##M#-k}Y>U8DWvau9 z(%}0R_GKtbcXD~QOu97AXvM~TnwjO%g=E~DJ@KXSl^-3XEu8e)=2P`Ok;saKg)a>Y zuz)TaQOPJ+6E2OB1k0C($qtAahtIVwRdy3)In0V?xYS4f0iGZUQBk}m>qe67w0nRs9l|#68oDI(_w>yymG2DWsT%03*qnOl%>m^>4&bP z^XBey3;G`I?nhE9g!wRMmt4_`u-$4#G*C_k+!)UTCBM0|c0AmdF`$P|N!;2{f8fcx z>M*RV)~MsvVJxw;N^oa=Sh2(*EU~LfFt_3%sl<@OIEW>7Qwi>i4oW3LD+jQIb&{Ke& z&UV^0V6JhO*C=HT#aX}363MNszlJcpFpJE`hR_f^+bkZ5XPi4{M^D+!c>L_s z_*qg>e@PjHF@%Yv7m>oSNkI4y6Dcsb3n$DZW4Zh~L>A#pst7DXVJg*KH)G6GrnIcIaEBz`x+sTAwTqeq*kLMsGMJ(~T z6TJ+3^pPAJU{%S=m9Hga%ddm^Mk-K#9n8b2K-+aN?Xk73OA5CMemhlkkw9BW&iT2y zsVLJQDO802bD`pfV#V(kD%yD@CbeEFE5DyAxU8hdQ`o^U^5ZFP<-2{Ewjw4Gp$bjD zoqR08E@&p-;L*y~%R0!cBPg?Iw&e#A$OWmz``vLNqVAyaD-qGP4r<~#ISEAbX{m0r zJ2~b-X^j;HP6Xuw$FdboC~&wW1FNFI(Mn9rp{~`05=r3r)-|vgmVmu7@F@zMok=kU zBM2Pq4g;H_z@hVjmk0s}E&zc`QQ-K&Www>=I`F9LTKRs%SXAUuJsds?aGDFzcv0Tu z!FahRQQqWq?9t*vzBzTyDOs9rL5E$F$~{3H_O=9Ri*#5zq;90uXfx=r zL)GeO6bZFqDVEhr71L}7N0{x|+HE09+Je>lqS>)B^JZRBwe<{v?M?L$%;QyH9sJ(|%i&x;g8kr+!2j$K^<`jG?Z9>Nju%`xRlpJP

#f4dG3Vy|1mMJf}n93yXLH~N(tzMufJ_gn0B@{XZRr7zQeKbMI8za*hy8WFrNLH0=_x}Tj;)N{~;YzA6Y6zT^G z@j7aibZvZGBR^jre17E99NrH+B5leW{Ba2gpE@nBgO+d1uDEL6?ZB`@lI68GzL=rV<1x+gM9MYA zZG@bm;^(X+niBm;mlRgT|FbNGEC;pY@&vBt?(Og2TT)cLDvl)RKmtq}S3e88B1 zFmZ~<2Rq~hM=Z610b>=#h&DSPFrm44n^PSy@oYZ+Xk-92A05kD({~ljG>iA7Ub$ts z=(ajlYx<`XEVm5j!-U(F4j+qz%y%hp>OMLwI=HMMzP zs_K4{xvkU#seo^Ubi9}#tSc1Qo+R1kWwQ0tclx(NEbAa9vp+X|52m)CuwnlT3D(vb z_8&?BvI^ri8i1{JUxepK$ovr%z1Oq%E{(`3Dx^Q z@DC?{@E`wa@hPXIJE)dbm*bCjP}%)cXIIauo{PWps^{a+ZlB`aQx{k5=Bdl7mshW- zURk}WdNp@2uGf!ED=PM@a*F*J%Qwb)b;N{v2ha(NBATLZb?;&bVn|>Fqe>#L0T<(f zfWYj{skTd65wxo(0?m?ufE_!8HALtJWj)iofuIOJoZbzYM)eFN!?0F}5dD6dk3~O5 zO4Z{<}7jz2Lc9&faqEwpuB8sVUyH@;eZ}9 zlfX+9sXgGNcj5Bq$oY_D+p*8A>NYwFwRzVwBk(zvDru6J9*2Es zsSr{{)v>~6diq~cC4s>~4ozXlGk=YdW8>HS5qG9#e#B8iL=}0u27`wiu>;Y;~eb5lQ@q;*f)0bLK%b8L6O_Y)cJI=emU zn<2TlcMOmZ0I}yFURZ$0E6Va$yj@&YD&sf9ZWB1i2Lx#vHS<*QYBTf*gukJuU8mk4 zPcT!e*Rx_!s@M0J;=7@T0TKvM(w&k)e(>h$$bYsfHxdz%=8I%kH%e~j=?L(#ta48Sz_ zrXyO-S!fLx52?HV#=@td@N{t#w6E9SuUC09ZcFc#pJ@T#2 zT#TpfeE`32rw}ILz^t)XuI5SUy=-$qzYnm3x!^HLPQJGgvfo*)1 z!2XWFVEpUt?^VF_`|ucah58J;2m%s``|iFho5u?bkF)g02>E>unY`*>33`#?Nr`}I zEQkoZ7w8dIeJ@H*w;1`gMC22!{%#S~W^0J^x7kDsj|G$&`rQVW!_0P~a zzQcx@gYgme<{gs`28$}${okOdqECEU{>UMEyPDse=i3_-o-QUAYS`A=SlOVg_6K3Q zS&`|8%T~fk4N|l=#SCGt(2N8%F0bnK$jq~*xfh4dzf9+`zyTUy^V%+%=T%Y#>|9t|p!W#T*fFb&=49?MV zC|%7umosAgAp!c1DSB@PAnYc}tYVB`9RuM~7hea3%PvEVtHu|Zw9rl~#752{ugt!k zR?Gh+T+TKH`y`Fcx*h~saR*_LrwFqY|M@Hb=}go z04?OLBI_?KcodwUD!Mu4H6^I6Or@NvUrp#)BWiv(bz!RF7@b&x(T1YE@sd>0F=BqD z{9vt0r5vMIOoq|rsfuGXAApg_hN1#VSSs7SoEVmgF|eI7*<^f^Qje4aQBvmjYp;X0t`XT~vx2!cw z#{Py>(Z~LU9k9A7m2|9LFd0_=oT@lh&+h>ImQ>P#KW{SNYf=>l{@ju-Zz_`8hf_uG za${;0Z!c72I;M#i#Ya;e$C5df@)I*&#PZHm(Xo6sE0R%*VS{ly!_KNXt_q1^gRX;| zwPT{9yesG0A5Tr6V_f^0Xc-q-i))Kj8`l;ChhiqK-AMzY;>Oz4fXKCb#Ix|von1z4X6{rUe#t#NNLS>@&Vu*QXTKlQ`L@@ zv;O4uv+t)m-XDwa&El4C=Le~d_s5(*v*VVp^P@r?IiLCN$`l+JG;$;NlT_la*lazD$F$5@e&A5VasJap(dHA4Pns_gycfh2AtB^LilEa-( z2d64IP4J9Xgym|Hg&x$~{kN+1;Q7h;6ACEEzB*LY;r^O}IR_zlJwFSMaKqU^S+r1a z5bXyb_XNu$bwL3s-hpQgq7`hjJt#m4w+>0zw54{{j}k2u$B0I7Wr(F^{S^?4bmm zk33+6W@HH`gMl+V!C-DW4;Z0cS)!=D737txdB6x;k>F`B@zj~1CLBz3=jP|rg}%e5 zr#nlkG}(AK#Sgj3Mus`)E=n697d=X!FbMLu^FRaAGX0B{@C=axVHgyQ;Gwx~WstZb z41^pP<-ig~!r>s?HVj2_`VT$zG6-M|gQ2!0H*#gR=WxJ~pFbsdq%a(~aIDRpxeIHh z%g5s}jt4}E?C)H+Ki~^$%u`#q`7K53(!$RFM+qSpg9-`YGNC7aF@F4~sY1C2G4HZf z{*F5>1&*C%Aueum&;Fk!*p7_kP)?YyEygGOqEImjpR;B{`1EW8uMP;5VF?twmrS0$ z5GHo_lwUs;0|U&r7ZSyy*(@D5yc)1PJ4lGJoP?mSUt=Ifln%!*NZswk3>u6F3e?Jj z9bcBi8P3V5R}Tpq%&p9kR&3F^60^%-O=)pvPYtQVFnmC|BTn9PfX*oZqT3!p(ZN4& z5jroGKFe&HjENAVWt0!w;!P0JIg4$LrrM5l2!o*QrKa>JbcvIH0GFQ~hcXw4vxNLG zTwH+2s3Q&o{wt(!T~$_EH<0@gGpi0W(05t0)wPWFX!MP_n&Nh>m}$&)+<`JfxbHR;As+fmXF5doQ{6xV6fz&R~-JaRN05$@)KyHZOhNE z2-|Dy4=CW2oQWL0e5e24_Hy<8bJvJ<%VA`ib*)k^AC5 zoJQirK_kYnK&t2f1Y<^^0Q|Tou8GEJYaoGuuSg*5!LrHbN@p?0{zi*T{1a(Joo`M9 zHr38d{GL>yLwFYQd5DRB<2OphwFON4(+RdClX&shn7XF(&5yNV{(;Z#SHY)Rh0@;k z;bo9uyNsxy3eQ0C4$SoW95Y4GP`SFj2Tiqg%pW&wn7O>}w!9TVImLT95Xi8ooB4;R zplX9>YQT_wU?zU$!RsrqkuwWW*%vUJ=2#ap&D(kVoV-)Yxn;Ei^C7WxLI{$qRA;6VvWn~B(Y=CQ$~bXWnab1Q&%GEK1IWPEy1h;#gU zc`L&5B>+vDOQmfI91j3A#rO|{g|LV-3t)&nX}$%Tm)D+AmpJGUZm|GK8aq|y46@UD z*RnQknd}uGGFXvfpgxgeI3g9d^|RbEQVhyG!v|$N0-5KA;F1FFCbGE8gw%nIBNyO) zENljH04^&4FxjXLN@1w3>`>Y^wJ<$XI;q)H%LXaCpD;B9GLCKy8mtbZ6;`oE%k84& zqcvMbE$$R)^g`$JqjhTmeQa`Au5GlA1^^0W|A9hv^P`uWr%@E7aps#N5Y=Fe>a`B; zQ$GUgPly4H7a7pUQ$Kvon-LFGR=zj-WUAl{$kLaZa+QsG{^k}lpid>(j*Qv$+9NkM z70-6>DO4=oR292FUZ|J^`7f&w%uA`b1AZ!vsmSGGUj4A7 z(xV@r1CY<GEN4=$y`2X6iN9EZ>G#}Dh%Xg1;Dj}LtO z@qwE^9R26L2%i_f_$Bzf6d(8apO5RS@OdS!usZR?SL5>laaMm?iQMG+h4c(0<*7Lmm z;sxc4frt5m@?WfTD6qD&SCyvbWam(3m!za(%$Po0UX}V)25uYIF&xA9cl{ssz6H*% zs=E6=Cdoh`3{@bAmODXUc4z z5KUAfQ2{}$MnH^;n)cI{TGUXjrq*h-)<(-$zyE)&wf8<}?{n_lnFRFv{l3djGxyxH z*M6xSSC8L2t~iP@Jo_FN^4ie-{py7Ov%&)EIJzyMTWoHfOP4QQ zYTR>1U)JYoaAdG%BRf%!eV*FO6iEW|(XPy}Oj+Sb@|g@{Hst%`uoVIMXfAk@1Cbyf zfBhqlLVuYK^1Z7P`52_>)?>!V$2+e6kmJ_L7Y{H`9=4&D0}?j$-C=R|>W2P-3`&g{ zG^h|Q#}$u1N8HlTPEY~qGvM)O^f!(J4N%>;D;n<#-6|UYp6k`n_!9*8yOn4xKfm71 z+RqY9fUB^)cx>y}Fy{}3&JBqf)EGA6up;qO1Zh9Y=`5jN!QBx^bLs1dP?@_F@P1-C zV+MIEATXc8{BO=}f1FK!gHMkqf0nlx_UDv_kF%MC{Rv4S{VK=!J{qQKxUZKQ;^t*+ z9~A6H`*UoM2tRjop!CPMKrAE)tj}e1JjfRj&PVH$wt9_!$)|mMhA%O653NDq#nF5! z8I3~F(EzI5cc_ikdx0T_%|ZF-njB-Pp%UoNW|MLNU^5LBJZe-Cz~6;2eNqX40el5y zkd>1hJlOy1bh9!&tXwsPRdwg;GaE)6kjTaITG-%*k1h%kZDBnz=p`}7Q zukN8C77u0GWnyxp&5J9b{d)opEfpF|DA?E-d{;8D?+ac7gW1^2Y0u#?N<+pCuR|ji1Y*X!gw( z4&}KO7;tq04J~yjxbVykWrWb?$}(L~Xd@NSu1TPwWwJ~cluzu&r16D?#`xlPd}i-c2dPsX4j79dtc*WHVxliS(+-0~URmb7ME zi0tcGIJ7luo>@$-IWMf)=eMnNQJE~39g}BZ&(v9HA|`Gi^dT9^EbdIkp)nac3yri# z(jd||F)5mlF|pR{dk6d5e?zb+og;&eu=c|VR8*vt7s>QFK{1G-lP;5O_2*{3vJ2&w zd7wWQMqpN!Gcf`eszEEulg)XtWmB%U+zv?BQ@fyd2jFIAIfGbU;t0P#ylKNYJsO6y zHs7{#+QWDt0JmXSYzf77@i~2pdn5rNLA2TvT3I2DQ#knW!l%OvR+DhB_`*Zs1%q(1 z68QuqN+}5BuD*a3Qi68>nd8t%MA+dbrY8uf8_#UBUSHfB2JtZ!3h0?G8gqtSv^|~= z>EFofq3~NXT=0Q}ls)1u{x)=RpLRi?wG78Z;LmbiyzLOUt%8_{+nOB5-{7In_B_Pg zO};YOfTk%qfpkCXliXN@K#Fp4q6~Z~jOm|sOavuklG7!(1hAaN(%qLsYm-hG69dU) ziKr3IMrwkYUBi~gjjtMjR7|3nw0p0&4tchXsydt`PGrVB*AQtHW z;a|fG2Ep8X+X6jI)+r=AdN{ywh-sEcx9xDy!@q|?>{i5p?-@H`UTWZ(rcxcQPAEZV%gN!-ombbFE% zDk-hihcHkSCXu2f&p{ayEkc3{BowGCtm1b>wn9qsxe}qHIDgwsti9#nEL46oq8>BU zxoGox3Ci4B_12ljOAOiY@gl8Gg7owZk<{x;u%}I26>fCIYd11JBIV*4dgq-MZ9I~! zJQ&W9Y^gW)G?`kB8++hfvgBUg0z+}Shrzg4j0u#Dw;_WKV;cbU=L0(Du>cA0p@1Fp zU_gOlhqH;W1iHw(wk}=z(Ik7uN{L9@%R)BC7nliAEC3g9&OCiu_y=@91d$=d7$?Dm?rWoDg73au?0YrI0n^gGyP*&5jr)*T2v;Jy=fk+oV{&*LJ% zIy(m+L#A2fEPI65U!oTuooSB-!XwIE9N7Huh}j~1)C!MIw?{+a5hW$QH5?u>kd}`| z!Xt`Kd^8#!QCQ-mh2as?Klo@-cr<8_7KcYId$c4xqS(ZSOT#0^)$-A@@Q4w7e6&0~ zqA0~joqBl22tGa=&pl%>9-rYtN56^`SNLpO?is`sc{Z7Q#t2%zhvJ~VEfY5Q45cvr zGltCZ+1p7G@7 zvje$j^gr|2K|Z6NM=yw+;8WAQV?QQel(CwfwEb@HV&asZ~ z;!YLQ%#JjY^YzWgDUqo)iZ*B_emVmtYxeMTLmH77Em)w4=bEd9L_e1qaN;1=t3uZ% z{Hy(D7zhOIx-G^;G2f`2^EiMq>rD*m>I9S;ZwLw#R#33rFxiPq@^7?L%JD~zTeLWD zO<<|fr!XvJ!Z@4f(*Q~iy%f}S2`IF~-VoFa>NYIcS)9Rh5TGpSB_7pH2`IJC5ERN& z=nRJydNiS1lBQ|{DlE=3ISMr|GKqtSsk1IJ#ON9L&Vfguw$XPvoF-aRb{{B~ zVnbXgL}zhnG8q8kJfpch)`dU&b;%?LNxXzI1qx4?Ltv7WoJyAPACe){-r~9uW2*9i z{AIXu8cF7pm|OUEVInJ!Jf${Rhb@$lIFTGk!$G;VL1XzI<%(G7W4xkYPKKwUk28i;RBWI0Y@hZTk)i0TEF zlS;%k3@zfm-v|Kg06ikXn}6lh`b+Vq>vCi1+pW}P3Jo#MuKIQuM@0xT%1cXN{@Beq zqjFC-iT!(kZ8qf~I$o5M92=vM+xkRo(*kqzMSg)LOH58?W5wn3yycabyVmC3*T}VR zjyC*%fP~wO@u}A-17ayEq_f?TbT(U7O{6n)Oc~52$SOrq5))}T-ODu{56t#bZCMf_ zEQBS*416lzmP&jRRa^!Wq2J}9NAqGs&&FzLkIsUtjY=>sbRv^j)5u#i~M9E*gNIYrPg`ea9?fNxd7_G9loHaCZsHm-1-~522O<5c0 z5odsmcYK$IPU@0n=ynZ00d^wyok;+K3F!P0=8fPokRP98%p(h_%}++hCW*&k)EknH zRT6ip%@pEQo~}r3-Vy*j+|TpiXtgqps39M`6f;n)EQ|CmS&MA}qOAp`aJ`O_uLGb4 z?Y7GRy6jt~GMj83FZK;d2P&H7wlvN;S-sdUk5d9QXbme_{o6wqw)!f>cg-WGmPrZS zg^w~oUC^b()1|aM_qoVk_#BfyKXA?bBjz+ zE`Sl~SJ}99Wzuiqou8kZmFAOwI#~k&M%Hwr-miI1KxWYZAAG^d=?r_zZf9zYuvA!od*1>A(?E~S`b;Q6r z0q{7cYzpI`!5);mJQC)|Iv$$w$y4+_;bjP_{EDU-Er7>}nkQXe!l!m-lUl`(eKkop zitnf3g+ca(`d|728dBTg55~Qg1Ncai=y_E#6fi%UtX*)u#wQVu1zHeJL9BRyG-@?D z_+#OulOIht#}Wm(f*GmgbXXpE5{hQI>ykk|)n3%TrDzJ{A=uUeK)30N&-r9Xjfc`x_RJB-u^L)1%j;`0~=*CEI zewSG4)$b_-o_uE+gi2mB&qC=O#LJgN1G~+ zew=tiuMQ~$?-Fl_(_%W1AMG$I;LUkxWQK|aZ*C7$G`dntMMo}w8q^&5pL2La6-fHF z1&o*6&KbYgcLeAMbgyxgVF9ouvVc7NP#i~wPwB&q4CQopcK~KXMZTp=mFBsqsiht{ zI8bC5stB^XC=D&Up;w_TKPUwr)p$>v!>s>*;QO zF_Jh?E3+V=7Bb%PwY}Kde_?CqJ}PfL^qn!K9&_t6aFnc>@1b zc(2RNmW#MOlDWs_Sc(CpmXl8hNG2uFgx~~kvxF@IQRU5nVBuo$)bWjomhe$>v(8|!@5HmHO(TwqU3d#CXQ~! zhqnmzI)vrMusSkwUVDw;XYat9nB{WPYj$Xn!{o!oae7oRm zw!?osp4GNwm}_98G4~6`*DeK!CC=hl;w<~APY%b1TU8oASr*F%T zq1&57w?9w@-`*ZpB11gtzAOFR&K3pGIllLM#EZK?58u$6@9`*ZviLK841{H5U z2e}Um%YSi2h0q}KEoX_;%=3{m(Vr2`=9XW4KF`3w7~FxmpMfDv-yW;k_;=+(M4cpKyDz1tmw^ zT>(_}5w|cs;#f~BoN#+{`-t;!>X7)mL$~n}x2Ik_;}kZgf+EO`Hcd@+JLI;q@=tf` zHuTN;HTl3*;67A1X?X@NRA`QSqr-@3lZ&5>t52=y_y%^~umP9>nB-92VtYJBFTuX@ zE5y)!PaBYqAtA$}HCF{cr`s3jWIXFh86QrfAj&{z|?p!q*UQEr*~$`2&%1yue5#WwS_#GbUl6Ym^KS@m+rh)v+`(fq=K>7bM^7L;pdeV@6d;&D zEJ6ff;4koZdpO(K^;@ze$Fm_Ckdb8ar9lRs-Vsy}>HT_*l!?Gh`SK8yd zlZJuvZfk<_Tydj(G(%%l{{w~16AB}FX?9386+IGB5uF!#`J`yqo`Zc8Q%Sq@kfeAC z!8)MMdi+BkkFDG6Ol}eXa1W47=_nRUY+>eL70^sb&Gl)w{GW+9irSU3lHfj&ESRjt%JEqSYZT zo_hp_JDXyryb=-PSOE1kJ+3ueC8+JT>7lV#qDLZF;{lf4M8}XD7l?x485v5YG*9gs zEKl%smakHnrIZXYIr1f35qh+Rpxsx+>6&V%F7Bq#x$3&Po-2D*BiY*OUG_A2L{0XY z`U1vKp)Pzq+Grui0Urj=Y!iBR82&AEh(*g);poF-k>(}i&Y4#S%51Y-g_xVJ?)dIE z%{!%rhzvDS7PzUdL@CS?rEn~OG_ut#SM;HG^aPql@b7=zYY}4{_SBR)9snn@$+vpo zkORgcd*PA$%QnSThC@P*=aEvbmE>f56Qko;$AdC-RM}VRy%}0sgi3Gx^~wP75c%uc z0BKtMm4&xv&R^GuUZ=rd$AM$9Gz9lQ$ht%iGJF9W>YwO5;T2|FGbQ>(EiLkivYlOXY3 z%zwvT=?aOc_NwIw%HkjD zD%0GZ13m4|TWojqirKEa;{jIgjv4>3BQ)6SPKlXtq}9Y8^>L5J^^e1|M}9~Zd-N3B zqgCIS{vLVQ$sT={4xVxeMbECo^Z(fISCQwMtfL_s2+}wL`W`;2@WiGcwz%nxKCWp$r4$OlU$Z!efZCU@-+Arxa_Et&)xNq1`2v zbHqVAbcgO)@x|O?-bJGcHU(K@i{|PVk~4orub^u=BOqc?LdO4R$B8AGCT@niF`5hG zV7>~IOpxv&0UT75EYb~GUQ%oeZ=H;%r&3;{YFdn)xT@nPZD@U}zQ>{Eqe11eXN!;% zZ8C3Llpig61^xQ^UCdvsNG;ixbnH?~q+?N&)yITOQ7}Q1V;Bd*$P)EC;Rh!TssL6N z0gY?KccZXOuEKZqyIg0tuE^c^G-D2Oxf_fo(9{jRCFhy=ZlQGX!fsFIM>i5B>RiZ+ z?VwBEi1y~a2?)B7fFrs$iW^|JM3I6%yfZYkJ1I1F12U9DV5!q4(G)?N2J4iFfmoyCKk-KM4VIFCWmi>q0>1j27^5>J8B9CD$d-_f*l(vJ>K|{)EKOCY1m#O1} zJj*BVn$2)omQUW5*ji%UvWNwYb$lO|ybGGD^Gzh(g9sQSXf%L$DGf6qam;fxpsz+y z*9E9|xVRue`lXO+I0_tE$ZBKUR!cftE&v2;_zaLNjp!vIN94R{NDBlxYawPv*J> z=j8a8M(eRD^lW)rN6eLzi>d${l(tuMhZ<9ZQP?_MD}0VF{6llbs57o=Cjicww}CV;$dx5eabtvkwY-o#8aB(_#ub z%hzBO-rv4HfUs?#f{ti(;LEwSMXG!CrkZaIpbk+rzdAsgmTFEH@yu28&7oK0>b;mg znK0y3^VR)5;!_1bK0C%SVj1rmvFkCN(m&VvP2Q_ zM7|PyN)XR?VTfnmqkwoP5b+onWa$&JWoUiJgD}K<(p-u01oFjZ)Q#cYP0F?@H-)o2 z@5*Ae9Y{`E3a;5^(S~CfuLT8GVu~XCzb=5bVMt&qYq5aI;`rjs@kgMT8>~fImrY|# z)zGJLY}9s)q+`OnDd||nFA^T&!l?Kf844FpVucm}G#EoAQyev>=&2dJQFpPFnj@dk zzEpO(H4NCuLs*LFclq_%9^N}dHn1Z=nid;ieAmp`zQjJi_uHA|62#0CiH*eMFq=J064)r)EKnNsb{3SMe*+$CmrF*C-DFq3!BjHB00(l3btFa8`0_9$pxsnR*uU&J8Rc07!N z^g4tBDpZ)xYL4E;W1MCyejB+9C10pDG+FwE1qPw$;HnodVFfQnMnGfg5;s1 z=!<;Qav10o56DiZ>9g1pdNE{-U5D^ritF$zpP8;bd~1MhC>IO}H&PAi#U4IGR9gG^ zqmu8U3YE0Vcvn>NFp8)Y5GNpvmI~^MFfp_kVP=FM9%u!AAURI(<3>%HQ}uYD7oXPF zj)$G#$IjV3;)i27p7ETLlU-bvYO&s2S2NQ@gg9bm>du4gq%QIxZ)Hk(knh3}$Ifx( zK`Q?b)WIUO1RQsq=XfJiTMK=`W^s+}=j%EibWkjeWvGTDZVjBsu5ugmNsNWYz&0en z^du)&127g5qmM*Jrq@+C!w`FnnC9jLm`Yy;jMdu+40Zrlyp4943J!ct0!-}(28{LF z2u#@QY+$xuQtzK3|8a}PK^BIQ-G?6JJqp>-ZS|Ik{GKi zO)z3w3LP+tj3o}tdoC4AqcR7qS$YCI=<<1rlsRzulc8p5u4pN%ma=f^Gf^ZQAJz#! z|AGryy%d)l;%38(E*@=Xmv{n1g{_wtji;T?wulB_L>e3qnU|AMnS@RqtN%jfxA-k5 zL(_S|@Qq9OBPnB2eG9?xbVcaRoEI72MfrDR7OS^gy)88Nj^Zbmeo4@jb*21iiTA-z z!oXgn<3lCm;&eBK0T?ms1vwMUK7($Z6mlSXv#e7Xqg?i$FXbTaQmOQ$xzm`3)pC$u ztbCL7kfu3YpA6`^F49~=mO5I^K_E%3Cw~nB0vw8Sn@m7GN5;Kd*H!}JEmu^0_x(^W zBpjYfvK5SyQNq#)gM{V${~x+!FLcX^Rbr$&hbGP&`Sk+*703|64w!CtzCK6k=;A=% zn+)`P43ssd1qYgK`tFbpIDf$q5w(Ev+LGHBj1ER$`+{L7B_i;f;04o1mPYCvoxwdL*RRalR8tU+q0=L4%nz} zNJTn)#c40=jkQm3@Kd4pbsC|I!dO)}7+9fT1Zy!cZ3L^uW!0~USCY=?5zV86Llb&( ztI&QhCq2-`9~tC=GphconlYd^P)#NGO{F?6z*{^eg7f$V5iv2+GdsHGW(imKJj>n#q_O z3cnthU4=2=`bZIBz+|BeYfja`nlYWmNV8}v6N=<+4aI$yS1q+q zHIv3PS8AW8G8fSpiL~niXd`N^t6?@I3`9y)z%lQN?bG5=VRze*0MkfE14dJsdgTG^ z2r)=8;k3f;wmAV-u)EPzMqn~cEx=DxnVB+TyW2GhFg;##rZNH(yPMwXsb)CrWNO5_ zApusfySX(JyW3HIniY1pn-gG%Vt0FIfL395bCH+t&qrPk^g^re3b2hDb*s zbtmSi&RN|o7rUCyCL=my@%1T;Zic8uqnlXLxUs3x&39pRX1E#L=JV%hStqw2&3MDU7JgDIo?ye@c{R#cmFest*aEQhZ1- zEGV22Lu77xM8Kss^%1c(^co)#U9w^sec%oVDJoW;7sNwg=Klea7ZQws;Wqu4`>Bd{ zOEU&D0?XvebW6cl9O3Mmj_<*6mV-ec6g0R|%}e5+cFo=rlsDEYq2S^gV!;3$(`J@L zu&+p9YpTW)02E~$5mxwfz`C&r(q&ogRT#7c_`8~-9MLlWRPs3ZXt{qRAu?1ThFfA0 zL5drRK`?C9yy!@s2;(wbrZ(fk+Bh1v9R;GQ=|K^8xeVemu@#sRec5F&f#6pvi5bGx zq-5407Q`ZM;?#$Yp<`R@r{-^0P>(r-^@kVqMQgdaq^S%D*Ycp?qce1t;&UU^mH)YA7I;H$}&-QrL*`%(vYWPJpGBZ z;U|-ZK?3`4UOQ6e`NSdB+qEM*qGN{X`0b%^?Z~J$c~nD~X_^-k zs0~MK&-`1h*&ITT8+#Fdu@T4D_yL!Oz6sBoMwnCXtvvg0i#CNWT-+`Yc4dj% z6>LG9`6nir;{Hud0iuk_^I9kcr>&%Rx`!|< zPlEiM?fdeBHJc+QmE|&u{QlE0?zkA764^sPa%(|%(|iwFJUqS$?vcF-kr}2*{S9R=?Q#wWd~4{&xUqYO!IZUnJ-V^}a*u$az z?V~`qy+nsrQ*pOnK;bX1;bUPQa-jtSl(j4#vKv?!uW&7`sIIEJN{|QDSCmO;;Z7@D zN_*Prz_|)`a7V-r=*Y|!m8vLNKn9U3SwQFf>A*u*vVfJN(~<>5f75?sJK*IVKMvy` zr(zroCKjXy$=d~161QObav|-WC#U>q&b@pVIFH|ok_8)+j*BG=Xs=Lzo#cSKk_9xK z97@Ro9@S2g$y4rB3FcPHfa{G?2BL@ON*S;sbiR}U_5X@e1~(`3E-z)ko+?TiyfXp8 zQU=1Axogo0ygj^KRlh)-=FS2ixY<-|LM{~@NAC%p89LETfcJWbYPAe_Jv>iBSIR(^ z+z!DQiFYNv>LHjQ@yF?qbB2EmiC$(&3nvoGk9PLukvOMO#?!qg=~(UiHeFGW)krT$ zjN@kpYx=RI6AfFO#+t^eREazA{?JQalPqEUxMke2t_l_MBxC&d{$RQ)9H--KYhT*PT1i zn%HugiNC}8RV_iH8D-yn#I+;8$XsX;#Y=yBiPWr$SeVn=ux7hd-BQ)>VYKv8>OT9z z<#J=fqBF+Y zc=eHp(1_3N-GR^+=i^<${pp0Zi1Ni*zTkm)ytrSg?T6Wob$lP@91|4-FFFfECK2g$ zHmg+*Ko;7jbG`A^85E3&ok4-&ANVyjDEJ<~p>`YkSuv|J;^l6@Z5775A&j?+-wS#c z5yeOeE`yR2U}Jz}CqSNJAo>$VEA@L(93)%T7sN=Vf5MbHwO+6(^lI4TBg}`3mRW&} zA>hz$(>q_cz=$o>`VS?-9K0UYv+H85l1m790YRMqEahq>`nwuCcSqRCRAOhv;^LtM z3=Ql<7`(}mv5#tH$HOp2ta2nBQ;Y{DkXGYT#5fD2(*ViDNxm_#0NxPs%&;ng)mvB; zG2ro}3kGrkY4f&)CRBu`U8KwM6BHxem69|uSX9*_bUHlPY|{~hT0Usu^KZ=Fk$(dr z7fsX-qf}-k6trI$Bn$?~xtVF*FzP&J@z2A6+|@L996dhfxX!;JSLe|3sh&Mtqod~s zjzQu6KHiqp=@=zR)A8e$lBwD7J>R?~tlQtH4Ma~~FnZ5}&He>4^Y#&=uFpct(+*XZun)YkQcR5n-8} zwKr|}?xbOmvo=hZEn?yH|Bhe6=b>jDhpt19Wo&b9U7J)?cT zmzP+GL<>1g^_Bt6oLgD2Og&@n>K__uh|>wG`BW%U!f27l3aSC>Lgh81ENTxh8lo=9 zmOJSj@qm!vtF#~NkW(=zEW*Yxx!fU#j^tEX2(%WQUWO}I@W;;VAcZ0f#GRea?dDEe zy4_r-6@IqlsN5XJaEM1GuGw}dH?5hR>%;VR>-3b# zgz4p{RhUmNoubR-HXb`hojzphk&4EFFW|OZx4U1^@j%i5lun)Zg5c$^?R5WbCb>*O+m1xv`SA+PcZuKR$f7O@pmu zHGYJruz=CdtgJ`4)6x$cpE)uGzItO1NfqDC*c0$PvoUM7$|14epPW2I^T<4>*F&KV^j%Oy5W%H^9Xl5x<&k|t~O;C-=A!FUdywg z@w|7NIK==w^4kIFB@}KxMr0C7K>iPgA$?1SM5~u3BC>%yVR!Rj!*@9y@cSP7j^hMq z*zQ!Gby(2Q8*ZF*3t(rR`ra`sQacua6J5lP{8_iW^sM_(fRxjF94j$<64pOH>sa`T z268>%giQ2LOk`?%(mkP9JL`PxTy)kc0YZZsY_vzvC+*OjTVXl=CV=a5^!KtH9}SSI zkN%S7_&B{=!M--#_1GP{o#O1zuLna#>vr}ZJRVBJoF0{i#^_J`KgbvFuGjE^!ooZ7 z#FQtNWgvnCs?U=TFT>+)c!*X%?zrPw&JY(P$mb;7h^@CGpr(U-cs0VQr=52C=|e-f z9^uTh&N}<-b6C`Y9~5>t@4RO{>)EXAz|sy{+u?cqpuocmF1qNVi!Z)-lw}?+x#Wc} zeBp~;^r9EP_$3Q};TK=}vX{N=<*)c9AYFx3W3Qt_lVg4vueJ{aTQ`bQGc5`@n;rW~ zS~6(hSVY263-zsaeE%i+e(W#9BTDRke(fcoE51zm8o)Vb<-%kacWDh{i7hRG189h4`JNF`5<;%}C`-bTrE&k>SSBrHKrepi8JXc{3>@ z(OZ3HCOs3dSS_P3)AR(|X4?iEtaBLo1T02yG2c)#=>_uDpoTY4@uJVnqzo5$L4Yx0 zFrLRZ)J%FF-jLcB99e*Y$`XBMCS@;DnWFf{g{)W$^(l_NzbBdZg?OnrX~6CWM)kGn z&OhG)+K%nrO=k7%x$T>Yd(X08utv|Xz1So_B7u1Q&(nEf>jD-?$ilh&L3dS8E^mVU zL>QZ)!LUOEzAtLwxwRLYT{Pa&PlwjFqt8rtRIiWxIk`yW?>U)gU^KIAOaG1!&I$W5 z47v7ee0CP!(M|nl{hr%Zdk2v~vus{s{>gMb9*xU&Wakvy|( zYo)JKOWrw!D^DLGEq6<>eOPp;Cq8T^ksZI0tc}L)KqTbtb|_i@lln@Dvv=q&SZwva_oG92z>)agiJvj;{Lbsn( zfmJ1YC_bhz8m-DiT77EV>C~loHb@QAx|Rc=MbJ5Ww(@~_a+8$(&7nh^CrgQjf;Il{ ze(aumJ}}tdzKKxP8lM2&mH^e5AE^V72ShP=jsr$wq%tBt^=lwvt{!vZai} zJxn(U=x{?Age@gI@QSa@W+{($n(WmHphmMrSX2y3XR8%c)QGQ^QHPFHkesqay%Zyd zuAthHL*Jns%0k_tNs{`6=gN~|jBC^}M*p=IL*c)wE@`6!rB3Y4`xSzZG#COw0}LKhe)Ny zXt)0$4Yz9eciAz6&>He2$2n7h6ds9 z0DZTFpQt}Gk3y@gU21Nj0Ss3D1t!z7QntCy7pe=Keq!VBi}VSvZg#$JAq<*^X+V`& z$Px$L8vz6(>^m)HIFMQ=fSi92L_Yb^U$7}IKpXU7544yNJ-f+ zT(s^sA;-jttU{^ANn$(3`q1hd{ioEBp+RGi>qI$*Rt11oEo?%+0Z!gwsD}0t9WNw4 zOSbe`1{_8Us{sM;o5w6--m2@B#*?LlV!yov%S~}IhG7LM{?`x))-te+xO$A%P)cNZ4N`) zP?sf!2ROhZt~dbPB*#w6f#F(sx61~MCXhJ7bMo3GC*YdU(D;XVKq8<2MB4DWq+wZJ zUngyNL(;G;Sl~b!EO1lOFtEA@v|;ygHJ{!!Ko^Nx5Fp{dpT|d$KTYNU^kfHx0@y?tkXt?GE#hJ!~rZB1B94m)r`yc@=i^W>OP z6+*Ei5jSwVyL;Ur<8{3l#O}C9wxN_IwTdpvi7HXkL#sedk57&VF*e%c0`VzB$@yM+ z(7ts4H--t>{(~bQ5+eF3bwR|v=|Hw50}0392k2j)Dkq^a+UtKn*9-D8zZ5lg<-Sqp z%Wm*NaTfWYnlaPdX!oYGT#r^HDJF3}Uw5csEOiiXw|4~B`fl+UFCtn4tDC@TGYIVx z;s1>0Zn^U6j3z>2`ovz%LXBiddt6)&IRU=!b>G1a_}#o>>Pp1-yWQ_C{XL1}S=I4_ zy-JM`>}qO99>)U)wjBRJG2Vv35g8fp!(lw^x(y5~oVaU3my_Bhj9Pl)GB*P&atc;N zi;q~_DlrwL+#ZL0*cLiA zCZ@WSa!|R;mN+t5#F5bc+R*-K!hqGKtj&G#8dH3dgqiC@YuhRcGW2-}VJyRn#kICh z#?C{eDJo=Yrc;d!ZJ|^{CCfwN3;pc{Xv+g4w-SE0*q0$Re>TIPr^&>6b#oZ{S5*WR zrKSRvbW+xZpwlL$whDYAHActcJ41)IRw~XvoHt{;LOaV{p&fR-JnJ-9u380m8fM;Q zfF5BvKs%;N$7jfp5cT`Q5GNFi^M)-a-*;pbAoLtQJ0qgeU%;>TCm>^$!At!h4NtMg zX+7sPPU|@@Y49swb;fPbRyJUpGo(DXoNTt^j4wI?vGAf zTGA29;T2j9OUs|Qmg@?4j|l!OQA-3z?4+K!6hgEA?aO-r3#`0{AW0cr8x9M9LUA!nWyFS|Mit8H0+h=`|KHcMSfywsQOG+x7ib+aSA#|?`SU2kupHww;O>+& zid$k`gWz=T_T5Aqom1oKkW2FOy0UU!s{IXl?a!Iui3mQr7bl`#RbWia;)$>iLZ}i< zWQtr_C8*xDo@~9DvP?pKS>M5`MPzxM}gT#^~Yx4;=EhYx1$s9m~Vxtt?{e$z4Ng zSCH}&Qs^!xJry4Y?MT=Ti*%fJ`p_9?o^|#)=imkw#OUz$6<)q_!G$B$y!P7>uYE3g zZCZd5Ta+CurW%HPFtkFn9ae`J;TH=QI0xS^B$Hs?U&nZMUc11B%VPiO za_E!NtItMT`EF=u%)@aDV;+jJfkGxaei{}kOE}(Rn3IzcDvJtvQr|9OwpRxj#%yuh zM-%9(k;K9y3S_z28l*h-Jn0-m2d*c!hAl}y`nqugSkchT%&vcwow6@cI3v zOaI^x{_qdq@P;?O@sIxKO>g?+KVG)%&3_`FKmD^m|BJs|E}ysj)nEP9U;p)`mtFSO zx4rFcoqDJK_WFwY%KEDM>iU}cSbe;HIsUt%er0`aeO-Nh{i-@xO@$TaK%^OL;Jdjh zpK%=2%8qYgoI_eL5X$+8)isQ>DVry{1TFa!brF}|%K9FC@|1393`|a)*bjY0(uqs~ z4r_K|F}v_Vzx7fH?9Yy5%}lzU*K0R_dTCbYBl_{y=_9Rp{NId3@g^B)w}~@yY^*qOW-6{pCcZj9@ogXI zVd4|LyfohBrR?ZdLuM^2|MrS$-;zulZ+4k>A2*jOYDecNYl}xzRNp3uCKy1mTl#$~ z(aiR8vfDPfmv;5?(vEH~H7s|6c?5qYLmH5Epv3={a;(2SS%tSGi;%q;f*(msFXxom zEziwvVu~?|MkuZRqI?h^N(S*4$slwDniL?g{+zI6zlsX|NOY2aBmlojMZiCkje)St zW7hB2pXO$?t^17h{)$hNuHRffqmPG9jbpvJVn*|++lhp@%#=A1f8QjpGh`C=ndn3@ zfxqo7VV?*z`OfRZJFH11@B9wm z(dCxDey8M}C87i4#Ymak9~Q{=U^(!S=<20ws;+YyZfqS&3=o$83~VfLkaiN z!(Cr0a#ZbI=f9Jv^y@k|hA<7o`dusn@`GeDzfK!cIGHS)1gU8YX34G#%wKcsm3whE zc73*SidF3RSMkzpGqZL0V6kh(U7y|Fz-O=FJG$%eeeip3*X^BG^BvuF_)BU>y*j)z z;^4fJ@93=8@|{S(n^tGtuomX(zA(O`ob@kh0S>Y9PF=3Zyb0hnFIpFCc zNn*sy@RjB`mfm_VfB!|Myy#rtqu-+!7V-t1=q-GKsdj`g;vl@3FX$}a#TQ;2ckx2L zpi`7CB#kaVhK%!rt!j3wDg0Bmvkfo~*YwLbW zD`DBqfeE3G}avS7&N{IB+B@&M0_a_XW!dYcy;UWJH6XO;C&Za_l-sU2;&K zK%Vkc;?>fE$1D^DIHNW`ew^%xxNcvUlnffd! z#k2*$F%BQ(Y}-bd5@j5gKS)NK1I$gj#&m8wOOcBSX{q!W4`@r$SpC{(uvTZyXffH= zt)Z1|D>u+tSsAN#6Njv|6S!ez7!zi2O#o-1YU+f}$*eaLUcaJAx(yn#b_3rLdzj(- z-Ca@HUg~sFtvDx%K&dI?>ZZVU6`~!SZZE01>Z{WTDt=lGA8({#U`Xz2*16os3X8-K zB8vnAF7lVLMs&EM;~N+qvH|H3)=Zz3AgEO^Xs)t$sXL6Ctl4%rSAQ|*KIXD?HPehF+t91!nSb>`oV=)9{wfF#G zmjze>Lzf`&GX}FE0fR;c<^^>H1G%n|^$8eOGGIPo3}$lzhQgqZ2G^~~XpmOuSU*QY zOKJ?}ngk3Q85p3r?CL=7c;zm)R%Hn4r~GbM%!dO;(YcU)4McEf{QNZMLlOM;?nRzq ze|&Ntt(mRCTAqw^tH9=i5jK-~bj4=hzz~KFdckIGmtr$^6z!+LX5Xn{Gbe;~Ot9I% zXM?l%5^Pp{VE{lGzO3!Ua13A0Y7X5s0)(L{FNZMtHAR?-1dbsL;5_GvL72Ok+~w|N zYK-cCK$D|$Xo9pJEN2CNJQm>xX3!l!d;{A8Hs}REv|WlH9NU!m;X5__P&psDs}Y8* z>G(Hocw+fz)z54UVPngX>hiKCM80xL2eYiAbmxX;$dU8CmQZ?aZo5AB@B5nExB6v_ zT5gOsZRgw$Hb!Sa>YWcUM6X>N$S3H{_wkIeC4EK5Hz<%gHLq}Rjgpr|2bZ=>x3VWv z_nl5b>i)ecNWEWm(f)!Y6Zbp_f5YUD5F%zN4}>dvgja7u-iJAR0>qVoD)>t-76yB9{B22@r4{6?v6u zW$40!B*;EID0D$kBYYHMB?x6W*Eu^xn8fIm{d$k^V%raRe7O!9Cl)5YDvatYI&rf@ zWIwrVB^xY)gunr~(#xu7gv)1z$nd+|cxqc*b{C(p4$0@8*%psaxy8$Drnbe)+ttocia`%b~`RR42*C)E;kH6jyt~g(0AN}c>H$U zck#2l<9?9;@c8d|hXwu}jiL1 ztqCNRzHFTUwQ#6vD4?9h>`zZHf4;?$&N~9||4?Ly)P(bC>WC*7KWN8@9C$7yQFx)n zB$i*nQ&J%4yW zdlE>8k*ePpfd90q`u$-j6;$o+!hP(A)1~SU1lS2xKSs5?`PTZSRcg0U@ku!BDD>$Zqmd7Mm1t?`k0v>*u;+6r{Lvg7+PvUKQnW}|j5!h4yXF8DT2K(P>3 z1-@-aKskIn3z``FX3RBqx1LU#Ey6x#M8^Izqi)OwLBh#d?ZC04`C zyc|nd1F#vB+%d7OW^rV$yt3o_F$7XNS*!>|9=aIO2=Z-qYu3HEMPc^6xbeW7a5VlP zXTphl*pT#~r~6`r9%y~4#oI}fa}ejifB9>HHs|DMv)}%re4hNpLIduKQ zJhqzaUFdWqN2f-!@V}cYTn+N(2X}4)agmyvpv(!5;p10$?@KK^ez_~K6;+qTva@G0 zXW4-_c4}|IwPCgiwyx&wzti#8IXM6)|1)a*Oy#oUxvv*>V*e`4kGmq2rf?7RebX?zx6Q!qMttKS=@RT!W=(LJZ+!8L!A6_c zT#;G}Wd)5eybtT0p`$ys2$r6e(8;MM2n~XoRe^WsmE&!^Xb0%vC@=WP^t{r(A}^sF z!`$+i8|(-p`L8FE8)JI5Sqc+emA0Zh66agXh=ztsR_)d%=kn047FodRH5ia(c ztfqpstV2%MI* zCD3QtB{|^kh(AbjK!HE#1%i-)vjbngmdZA~^+5=3)tx8-ieF^OmPZS2l@jI^9p9rd z3nHOo7KkCzKXGT8Xyc+r60(^UEGSXU3Xw_`q|&QGCwJ%1A$JPqG)cy%mYl8%T2I9Q zcVmG2F};jS!&?omoU|4o!)Pds8#`Vz-QG*ww3ScqT)jHkt>MJuOt|Wb za>o(fBlnI&ikRd?=;YDEiEvj3xF1l_E=4#)0wA0>k1)I$qs*J; zoSwxAIAITH>k+Y_-}#`|<v-cZBJ!luOaC|PLKPn?D)>^(M3u( zEpQ1Rrj9i#Fe0~7F}sMF(yGwi9f~8mC)R~9rGO)ck14GV{TfqZ$h)78^lRHMxM?_Y zh^oKDzdsH<>46A886L!C5qJklILUW}D>=G_67QH{zqSW1~#n}OZ+xhfmpJTpElCbu(d_)v2ZUMx8?P?_iO{yFB#z}m)S z8Qkmjq$iPesesuYNH6euDB{Ipe4hx{iR_BG&x($3Vl=3hvt6V+1K#aZUng^8JSw*^ll^5mB=b{e9_^0h4hTdCFu<=AqYNRGMeF@EeRZm&H6QtZ2IWp=DF z=!uex#4rV6&~!W)gHCYchA<9WA!X2p8>I~T=Fp}KgT@VFiY|^>VOc9U^eqX%!^5Hd zVGi|)dy;3-ckC30A%-{%hOHMT_Q0aw5r%r`Ec(^}Y-TL_odH11qNh#3I|8h77TwCR z=>N#)rKbsv5Q&ef;lm7dDb(XxZE{iK-iXhNt~TVW94w3|dPT=KFnnbLm`BKDJ?{`5 zKjN|4F6FUmvK-Aijg>AQhtem*mD;m0WxJIaWzg8qDA?r@cq+LR!07p)_W0x-3u81! z!M9^Z(NaD!--H9>6C)AR84s|GPtg8=aWEHMhlC4jTdd5Er!7cS&Hys%FKz2vC4NCG zIiRE6iC;k!&MvW^U(6U$Qus;F<=cA?cXh^VK>&$<MHkvhvhh_6hMHe$w%0F?j6b`aP;Yn#|(NpW99Yz5*rGdhuRG!EIFJAo^n9SZ1R=d4ym4+f?r;rcS+$>nkUvR$oVM zMqVbyaIAJLu@j{>?-5r6e-O;B3iGyG8ASq~dT<*m2d82$M#GIm(0~SFHs-PMr*pJTKe+>dYrN)m@Fso7_;asR#Bxo^ZJedM&g^~8*h@MZt zt9g1(qgS3R39WO00(4F{vNu`Tb*8i)Cr{+I9J1dh&uz2rIU`21<5|6%?=TIvVbv#z z%@vUt)Fl#5yOXEGd_1+gNb$6e<3k9E zv0fEkzYsRI-UjA~r$vZ;y!lhbyul zgOl2oa_89~YK*@HFtJaLbv!sDZL$PCH|z2T&g^WQP(^CX9b0xOrO(r)Xf#|rzvS>h zWr7K|2d`l0A@B($i|6Vy5vS%x!{*%yCPT*V%uUH~H5^&pnT$P#5s@e5VABRoV$2U( z?`S4tU|~EFMTd%m9^#3Y4tfZ-NgFf?8EyTls<@$MCbh$281CRP8d{h;M;(J8BXCT? zxWE#5EwG`R!i4{$U$_9z!}ds3{lsq`35&cdhnK1uihzgq|3KfD5`FOzlMyu*&DYRN zXL;)^vNXhWZwKL^d)56O{Ppk3ViiET)I=%zLeU1e>0TBp?8l(zV$dr?Eh{&QF z?qt!D5@aoRnBK=4{-+6oVY3H7NtvG2Jg@ZPI(JqR+n+82mb04Y=qYpC?h-pYtoah} zu5<8-zk>vSMsp~d)wX0-C^60VNPu=&pNi%z6`ko}EuEdL;D*C#O)Cg1Mx!yF`qP>* zUQ#zY?Rzrmo7d1;-w+a*nsJgoDLJiobJ48W^TJ%D?tpkSbp05&g(A)vx?4Zq=b@o` zvVPCN*W>55?=;e%kFu=AmR=9P^N&l(v z=5$W_o<{NM06RJ9zesydeTs|2z$#BvM(Iy_DM`iLwr)rK*CWO!NBn>{@eF}DvN!M^ znmVvhFQOr1F_Y!|2&2b39$q-(L6!5lPX?s_mB3g=y_!PH-^c@5!Cz!_{s#S2s5yti zte0$|M=^VyNV-+!mFyMWN`{AOt}Ws&un=}dXG0!H4>vh<~*k0#r-`I8Vk zi2B~ovn>oP+1BrLH`9smHcz$`;+xp&=5SUO2iX2-A1T%44zPH|R&;y=+bFdfv=Dti z#H|qdMkg=YdaHrz&iSd~Ds$K6d(}uzt%aKggfF~_tIOS+C!bO??Sg0DxwR)}jg`DY zOpSZaEI>oQcl#l(Rv zSI6r{abt`(Dkx zi6{nz%kSK>&dkYhWdL9dMyy~FXX0Te%^^b6;`J;_(iQl6 zM<(Xw_B>O5_Mt$c2&o>u%YWIF_gnwJGJy?2jaGw z87btB3a2b^m{t|qimsPC8rFrrua2Ur0{2r?FM+94K2D?mp{rn6HcwUY9dOH_D$Cye7Jav!B@=dRq&@xCU*B zCeY`tiP$xd7h5YeC)zdL-9J=@OoVT-K()0{(Y%EKV0!?@>~uF)>;x~4dc{efzs%gk zu>2@YdV-YXbSG*VBY?&exS<((IO_$low8uJiHvY($8V^~2&AtVy}h*bq42s23bAX> z3k4z|fZuxN%2V5zYw4*i(t+pwc-tM_hy1ou;+J{ePUmu8(42+y=MGkW)v( zE<(|Hn#Q}5lW$<;q_%Vwy!yQ0RW}K%AN$M7vAJyxhu&Dn1G7_BL+k8h6&tagxbS#V zChG(F&1y59O+zuTUA=CA$aH<6-&WsiiFqs+K|F4@kiHF*LH+49>Ka9v_D566v{;g3upIJnROMHty|0!Al8w80n!q4h(>@nShRk^c z^t5a3{k6yDVnAm!_s4-{D?1*9EtTp~`|HKSrjDtfNR%Z#h;pmoa?BIp52$VtsP6Ir z{u&h$RJPUP_QDQ1xFczB(b3AkHH_LlZtp9JK5EIn?~l8?GIVD|PJZpxG9mH`QTm~O zb5WIeAzNVcqS?8dD7`jxXri>Td|<BG`0l2Qns!SyyLsSK98CV)R6pkhl%_b z`0WvLXU3_yUvrNS^0C>qr-ihBAk#(K?>>-6T2&r37RC`~nP~zQ{oURjI?{SjGeuet zAVJ!X@hErlOkUlmWFxYTPp>xVMlDqSG*3bmH@SJ|FJv-THIXRxdaUaB7KWlUU*f&= z+&+%yb}sRij*;PB3+9hwxQ-dn7W7Hyd1D!51{P>PMGMwBaGOP_99x5`d3!r9(4C@1c#}^r{cWc};GWZr#A%j-{ z4hu5)Zl{Y3e>)?q_u7u{@X(RLgPJKacmN49Jap_dEiroJ^z#4UDle$v<8({fM`<9X z*+%XbVGIgvqp*u22xb0>_&fz+D2PI7wOR;6dHSiI2f;g@9AT3Y=ADkW+uNK*z$}=^ zMYN*hn;7b`iKNRsyKy!Qra!^w7=}LD0VZK0*}n1XoD2awM7HlEryD;o(cjXEf;_c4 z^z(_i;??3r#H7afFVkunSt4p>(ta$oH(WhM+M{=`<(ZlW!yX~y0|#E|5$I zk=4uv#2rCu0`1BOg;ALkKVgF=*PkkODq5K&D#k@KCed?iL!Y+S3Tg*aj!dlBR-#T} zITadK|v-OWcmXjAo5Try59AXPSbr(O*dP-;`?a-uFM1$%u9m8)QJ zZZ&CWLkJwKMz5mzj}g9NkSDq+Cwp z)|r~Mx35yuA@aduL*zilT()oL3DGKmgQSrlQne+<^ znn1VWiJ=oi0+xLLc}J+A7}0ZiG_+eomtR!$P*=%BooU;8PxSKb?GakO48xb%I$$7# zxYWLaulQBr);dOljkV~yo!OxOJ8Uv4=sR{iDEO(#i9@!o?9`~vvxWDDCcBi3G=O}f zE-EDkhD!o2Y7B9Bc$VSsvz0ctpWhhJW&9*eciEW;ph5>bGkk*u6-gxG#e!p}Df%mH z)7jN4JN<7RoDEum=^A!%{?pe&S<}^Y*}(SxTA=H zOH~f8*&t{LQgZ1aG8ghQx#qJwMafBI+mKR~EJC#HcZL--%2IQuu6mBL==+nn-Ac;( zPyl5}O9h}8%F46;948?B)OWtJYcF;nl+pbGT$`FaF-jbtt;KPUMyp* z;ruYx$RGR8c{rQqO%a!@gP6|$W5BrJ$?4cQ#^mE_gFHz-qGU7nNR(@+))=)SA4)Q% zn)MxSl6KxveQh6fnsqpvR&@NE?@9QPTJZ@@H&Z=&!p5@Qg@>FieDtEm7n z)1W2l^=wpK0^B(lq6BEY)qi1gA^thy!sebjyTRWON)JE;2gv4{O9zj%yeiD1HJ6I5 z=35}u)P>;m-BQI?3#!G`oV|??(P5tv|MV~a`vNj4Q4g)#oirS%^AIm7s z=0B5l)V#;P+vDZ>T3mq`xqO+VV+FIp7i>uC_$Sb%gGck9 z-E~X{|L(01V*FDKXpxR*p$=ychJ*F-^O@V4*P1IU%`{PJp7@T0*6{_$w2qb)KO4`V zA}c=cLR8ej`e6B3cmxb}2NtV!RO^_mu|`CC>>y+>{1z(&8v{C--GhN>9%rzuLTL`C zw7H5K8q4GfvEzONCUWlPoeh|~DRlL05vJx-efG#GQ8ctaSR9)QXsi{4y=D{))lL?U zAtKJ>pUVdu@&htb`lQQU>M%x%rhg~i5!5iXt|OwlPvKVfyl7Ts)ztNeq&K&`f=@n`cNh>|+wtBt@zP z0r9{BH54@*DnJ&{mu-OP(VNDo-A>-6CYUhP?O~`NQTE0ToZ*6f`#j${{Cn8gUeNZz z0vOu`-U2SrWPDHS2*hN`7fzKaWg6Xrz1n9R0b_u0EEb(%X#Ku|Y7MqSVpycbGA1YCG1yMdR^Bz#tV@w%M7qQI!s? z*SAq)QRwIPq)m{w?_{EX-;9n)9EDGvWQ%HiZLxg?{u100`5KmatmCJ3mC9C1#Y6sl_6UsOcmzfuP?Jf1vv441 z8putfpajzrAxD8lj;e@7&J@ToT2QH1U)P2qd|rp3(T$h@_&67p;lf7HvD0~dXl&w^ zCDyU6c$7&*F4~c2wU*(dTbh5%qz;JKZwn=XU^d3`3tZ4P5^_=G+98LHLSxn};g1VH z^X__H$Sq+M@7IM?1zZ=BgzqJ(nM^yE@Ap z?WP;r8K=(gzb*hyr1*!sd$=2;{0|J`=WF=z)MJM9w6gm@;;-rPeB?Ex>Y>Y#9EZ*_P3JUes(NY4In(Z56RD{+nD4+`)W*5d1l~>H-y=I zzh6WU3Gf|GrD=^-e{Vf!Q#34U0Ee&y?IGEIoGH+a!H~d?l#i<7fD1102cBR++~!kM zCe&Bt(56kj)xxfmc$EY|2`I!BhP$G(+acaZl<>9ZWVlj+`cn*VtBw>>G6??zxLhA_BQX--abgKW+y|PTq>z+a8pwcogAkcCNy4hmFcSzf)Yn6q ze9P6~ufQqyyHl@guxIcGe#@PPpVa?6l!%#f_k&9nd3LM#p2>j7U zX2L+Wdt$T7At+G++!qb4AFn~mcfY~FpY^S|6apkM9VCK(K{c{Ob0l#fx8E7;47EHv zxU%Et@UKV79;+1{yw3yUD!Nk?9SLnUgrXciWr zHa-&~^Ma%9t%UJ8G@UYxFEF|dp`(>`nORT@-p7QF^2|Npz-(h-)%*UCn}RVeu9=xs z<9%;cZhOnNoie{3V?gm1mp$5}l^x&TR%O|0)5IqDJ+l3h<-=0?Ef@}4P?~EM)@ya> zC0VZr@(D1_(ZKLU2AX=k_Li-ex+miG8me3`XQ=k;rJTXIJJ}CU2&^Ih9GDiTTiNj= z{9b;Axq6=Ws>Qg3zvSs@b%1o(SMdu!^Q-7bc;BI}qKA~M;`{URQyv#Vx&0=JD{dmWZ$utot zlzl>!Mc*5#Q#qWlv$K%fMuf2NK@EFpQO># z>uw5yh&D-N@;20Jtf6p=pI*IF&74EvNk~!NeiEKu%zwvT zDP@ctOX%X^CBLA3D6J>CF$~9yO?ekIYh9ga#-^?RV8$kj90R@Bo30M9&E6!(O<;Fh z!V6CnPJH``z=^jwoS4-sPWWNX94E#VISva>_~BIG#8V6>R()goIN@Pe;e>x7!HN41 zyIgUg3>~Itm4cd{(`SuEh;c*(Dv>MHw4-u`+H9)j3O^=~3nEug?pOJuS%~c+=-%ZE z54`N|u!0p_WDPMinAR%+K&IZ76o$_WhZ{P+pJWp^=jB;yR$%U~GF8l$y9u$h6$V!F z_RbI7R@$;rn}&)6(+#VzK(6&-tuo3eyyWxwVMSs#!hZRw)6h39K|3Df!Dx)+wPB1b zHY4(PBhykaw0z_w^ifzj=snLFg7QM7FJGYcpYP=-q#CSS>2B2<9&9O zo%xk2MqJ`yMaP4+-62@cT_e-NKCTLHK23}mY7{XKoyKugmTcG0oZUmI8l#w?1I+SZCgR+=*ocVym6;0La<9>*b;Of&YA#?9Vc zG86u4R@0K1@K-y7*tX@mQcF31HR+VU4!K{4WEJM%SHlcxJW}pTJI0JQ9tZu9LwQ7r-=UqoQQt4Kia>5~GYAN7shcRLdl79~IPfskI zUd|{W=);#4efVq6?honT0UO{o>_%yvzC<=$#Iy*Xr5s8tRRc2 zUWjecLh$@<>*1IQ^K6O7qKT~$W~0U$3~4?XqP)OAYFYo9RWGP>SxSlzK}}OXr}xjc zq9t6_@#C;CqhRU(>dYs1{WK@XS+(lVst+Uav$-pzW>G zocQ?-?kSUbjUvI!v-!FGZDa%ZW(bYnxc9;li4kc1{2JD?V(+J11V7qj5#9~sw8ffF zmvVP>S%Nv-*Y0~i;`g|o4g0?v*^vLcnYH}ieK}m2mBW?UIb4|oT;WG)yBuFMQn?Gh z_*o@OwR`4Eb=x$TN+}-4T{ed7nAf`$1 zw|hWjo2{fMO`c!F238>3lq={bo2=mTJg$lKS(k_v*^BIp+gywxPdJS+%(+QwbGx)% zzdzsBosK!3;R{cKF?2e$9o<3R%fH|jzg**Cuik##hRTbnSy+G{78j6@kN8C4Ren%= z6%__}(FJoLc+UlD3=9rRk%3cBJq375N0T!valf} z%+J*@y;Ed*=;2@_A-Eo?qvZxbDI8z7>D(p2k>4lX_aXh=FaNN9PnQ3RFvL&j@-L9J z!Vno4gW-La!yDxAxSRR%`cK6Vl1zfCY%CriFW3UP2ka06x4vPM)=Nql`@~|ltX9D5 ze@<8+p|x`1(n^TdeNv#eFYDm0v{@}F*UK<*?%K|5($dnA=fbRZf;X7)4nUL@g7}c0(JO^Di6XG7pgk3OwZ*`eQ>t)&x!!-u&17O zgr4jIFfAwmY%$%4ppe#s-hm-}1`f>uFXba(H6Jm=3;N4Jo2u`*n@;oY(6h}^>knwp zZjMWJjxH1EASTI$uSxpGeMB@wfy?NmZb2TQ+yjqLd=L-{lMv7M`GA3(4=EN3oVWmA z2Rs5`^CMU9-C@{f075a^CgAR9$jZpVQ{eGIKOeRhX(FJeYk-N^QoEcG0xCos?fR~m z*0JC`V_R045y&^r^xw^mf*C^*bANqc<&k9E@Ff=0_ZpFZs1hA z)*hB3tr)CvHP2;t+k;8BQSP2*mu~Q|z2Ls@;dl2kzerakEUeUY4ju>44j%W_*t~uX zbA2$()easFi3eAgtu?R4XSk7K7Q#l&`XeIlgNsav1VMVaT6VCaFddK^W%*;ZTf}DzL>cY&s2QK65o|e(sXK`rGEdwSHOs zQj$T@^w1dn|Nr&20+3(7RIgEhbtM9%i1`5SWIGl&1z0^SN!3LqEGMb9S}hS(Pdoke z(}(yu)ZboTQD0eKRbO3SQy;63%YT>Guc%*HUt3>SUoZb%RoDL}>Kp1C>sQw| z)i>9-)VJ2R)vsafx*F-)yGumvk2p!vjGxy@tov>!Ya_ju;v|Kt6?IVcwRM%)4m4O2 z2JXr)U%T;Jv;Qx9Uji;yQS5)u%-wG`5H;>|FZfIVH7rV0kUK|_xS&x{;?t+W<-Mp+ zjmvw+_YxSA5H1iPAWOgimpvg~41y3@FMHU71PB5W1T_L`aN$Ko`2T)Y)!k=K&&*wt z@bUdWXFkY1J*T^?tE#K3tE;Nz%=%W&dUVI2;T4CyaC1>gsXZ;#!Yh|8{X;IedDU9j9f2yfFM@QJPj>h=zYm zO^6wP>QQ14Gd6VuAm2=oj|Q3sFO)duESgX(XxhLV&a?UpB32wHnZ|=xwOgzWy@F5x zvC%DB&}aDT8ux7Ce64#nalT%jL5;H4luopsVom8N?QwG+wv!^*{F?wm^wYO7@ljKG z0f*j44p|uu9mTbWernV_UiCwtwiSo|gStaMqR!BlMX>od-O#aeV@cJaAC6`U>FS4{ z`K$USG5He8Sa{!Yw=ZZWr|yEXg<7`xiS=uwY$ud0&@!nUxOYBE)4_PY9mcl+szel++)w+&sE*QLuLHptv;SrI|zUaUoxxfu0D5kJnYGwOk; z?YUvpTXQ1*sP3r$7ab0yyK;(WW|xvUhly1Yw7&Arg{JPYPMnp-PIdG1dt}F}H*G$- zmFy_nyYC5$KCtAfjjh6Zya{Fw#bzZE^xw_!otN|LT{k=zH>t_(z~tcz`k#_N|BIl> zk{D*de-Vx!MdbTV9r9fnA>=!Od|OkPTwRxZ-xl)eF2(KMMeF7i&C&0g2;5M67i{{+ zIn0*Ey~9bFZvr9l((=tZ2)Qxp;hO;=Ta%w}u8WY_(qT0ATO!EZi`9&;vi0lajm>xe z>Be@^fgYo}^mXCevzILSW1AG-!@{pg;o82+!ZzU|G35Ox#pwKqo4=|^6Ai_4^BRZq z3^!v_I|63Dn9TfT0xYlvX8tmn`T0l}nNKY|6(oJ*4BWnGBViCAZ(xaL=8ClJmFXoP56Tqj!1J_ zA92yafxoA2MeX6|b@_W{ZT@~Jg3P_>_(VC(3TmDGCf(#4mImD%vnM~$Atd}23qM5?#%w+#KN!MAvuAct+#~dljFnC%D}9o19KCGusbd6= z-w}>aa=OK=^a+I{Vx^5?&6Nc&ypY?CS$~V zu>)L(S)1vG8jL}k>Ez)n6^l8V4-$?IKUjDAc!A?N!tp`E5o6;6IczLq{r5ZIa@hD= zgpKz%z{dWB;;u8-|5~A#&zAQm6tQaaz8n+_`R;yopr{;{-#G3ULje;6)6pqi-hOM1-Z6g8#BaBL`D09kWv%VO{@;IacbwR$>BtuwGf^pUgPDG1iE?d+*p z80m2V&vtX&JBB3W@u7|pe=kSKnGqqsA6_;>zP*}|tCWyaw+SIns!PbX2_aW`Lh5== za?JFE>>nW^H+e#$=4c7IhY&LHggk+S+C@aIuMie-dWY?jk+j1Qms7sU`K@{_Xsj?$UnV5$-Yo-c; z68^aq^rNAOeeNO=xhmk{^l+(%-;4!04GrP*<)CU7PA5sSU{wGa`PtA-rt-z+1gDI%MCroVz#G?4den2+f5%I%D&kv|MT7F< zsl~XZ?Ciab)RL$hCWQ7=NT*YnLhAwnj9QGv$<1DF9vjVE24vXGy^q~WyjR1S`(Wrc z@(#Xp>)!hXzlQfUHK|)eEABoppWIIUbm7h~{frwASBLHG19t~;&gK1IaLuJ>E?jfL z#^xcgwnlF9L3gfe9s<~XCgrs*H#ylN?^{~Q3p8ZZbB&lYZV8RV&bYGdc?U+O@5PqV zyA)zu>39}fOHMh-T>N^OhUjv7GJBvvCw^P&LQE#v6zGxoKDpy@rWwws2$lalrMJJ$L_ zRTDL@u@^C>i83bixWTze(SWK3Q*}gk>kvmG_ecQ=VHzD}jmIW}SECb88PxH)Y$29$ zM{aPxvny-ONV~R93Uyo_Etx6wQYLx;^FA%KB*|p6Jmw0>Wa0tL0#J``&($8lOeH>I z4`Al2B`@SXfM4#tJ;jxTZY?`h6$KAqaRFwoZn^+V`r#^Wau_EoO-m9a1FWdSr}aJgryfiLaqx?HO~g*jl; zy{<3qeGj}P%=q-}_BSVq$`lbq5&3=^Ks8@lCXn${!{ke^U~iHF0Wz`~_(|7rrM)V& zXRfsBTdD&v$JpK)uC(t4P9^x1;11?IX=ll3Cdr zG_%G@ZG*-Q!j>I*tdiF^SvRq~=IY^P$Ck-!bx(crQ*cim^H2BG-opQ9UnrKBGuv|3 zVV0^S6iK+u(rK0#$nx@7)gPfk@&Z|Nmla1@xXQv&mLEFH?w)a%g~#kWvktT3EK65e ze&87bYu{ zAIf(ixhVNjvMRYa`LTR2NiI!(l3bQto~+J%f0|s8T$x;zT%BAa-)ob>yrnQpC=C`4=0Z# zzepZUHYATFzl8r@BVGPRr-qv@{{-I;$~-kw^Y&fK4bS5V7fhC#w{P%Nd7P(^=ng7Y zdg;2S&Ita3k7=QJw#qR(wYd#i7+ipvPW@3W^e(`iDEmd`MLF&iKpsJw#(K0!-fqCWk{AMy39YSs)(pK;+B{$5lK5Z56?*>}ykgy*a-A zo50j0#f)K%Du}>ay%Mg^Ek1q=QESs9ifq+V^nHUMUW)Edy1;T6|2n~mx;%C%> zp4ac7jNB6(!%HZk`U~OgLbI8JX z1jxe7L?L+i$nk6@3&rgQMZ}rsL`1-=tPO75J&{c~0Rrrr)niLJvj7Jr`WThH{&`+q zBHZSPuttWeF3;r5DHuM=z?kZXn;q#bHqySlYvhV(q!pusl*!#(cTmXr5d74yW9hY8>YdWxiLz@lZw3IbMyYd3&yw;g zzOAe{{N?2P9K;n2mxv`fimkz%B)=-6E?#BV5g%Mr|IHUkk`LBpgP%G!xLl~DKG~cv z5(|Vvuz@=IX0d!(J*3j14xX*eUN%A#yk@6FVluH8Z2G&C%kaAQs zH-2nLiRgbvG*rB5Ov>S5eep73Yb;v0gF7cL@2Wf0i``IvBts3cVB(~ULeA3Qm47d1 z=|zG7b<@pq#egB8rYa}P*7OlCTgP&0t_-jRGN2G-P}j9A6c>6ZaufFchzxj@!d%_t zW%Q)+2RB)41#wPou1fiMxGo)6I67V+xC*Z48%Qw}Lb$2# zc@|gadtB91G}$h;cZ@pP0r z-}UU^mhtU+3zAHVX(JxopE!=wxL&EZcD6qh*Xa*g?*PXJ^r`=fvo=Z)Iit?nLL>?Q z6yEi_2in!t0;tx&yvh4_VP=@OHo`@9D}ZoNU{yjU1XbdJi$Z{|KG9jw86~Qy%FWzo zLI<{K!mE5UnxucK|E8#;B5EO@;2X4cRu!tIRa5jYb*CtTT@@(^RCNp(_y>hR%CXU^ za=b?hRZU);s`=%{)zdov8leD9D6-tbDlKe7t@9ssae$av#Q{QMfrAqtdg3&ln#Yi( z87GUg2k(Jk(~?JPtHO#z_3vJef~xuDPhvC5zfQL>Qw^ zv*9w!Sopt0dAv0LkCVt@;)r(VLo9LKx9YFMUYUQ(?&c5#fh$mj(Vl}b?_0Ddx@Foa zZcWZ&3;(Tz?gcALEPP4lhcyi0}%660_kuEBPWq z8eRBKmKA3^yyRA@^CL#lc*2OIme+l;YMr7vWov8+iqSfCVO@s$hB4IFJVON=E(Im*ZXbmpz&WR%x& zNun6zJ+4JDMpNsysKXhKqnz-(i-S8TH;Q{%h)6|pT($7j7(YMUd-&pk;YA8h)PkU` zuG>_bFWj%4e@+qTvC5XeF6}tTjp6Y#FrskV4u5yJm1E z$??^YX9IA}wCF71HwGGJJ!>Bzy{8e!4Sh9#5wK>ynuseLf-W0E9izX*7dE8jFQYo| z8M2=zqB><659p7qI(hp4I=pT4@6FR+_l~6h#H~$#uF_TX-)P{(^xxOfzhLxV8t6Z3 z)b!s6sOd;UsLHQM|GfoYjeK>V4p=k#Gt95?y!?HrWAvAZKF-TI5m`2cmyIk_^JI~Y zj7-Z(TbnGj!&Q;xk9Enimm^ENk!6mbmD5H|mA461Lj1!YNR>T@q{_1aX+{;s>?Oo- zf6V!t!`p`9-Sa3`ZS=+A{J+&j@oo;qj`RBi=bM-Ma5f`3$@f;lap3&_BaYuPB#xgC zSTh_m1h0C*P`gbF<9!i$qS3!dZCWb2c;D_$?#7vHN31$+xizUWKX1?2wF|*3Tz@2f z7!|2WjpfXh6@U~TWIEhZd&VKaO<;PWNhmS;q$7Zu^K=Co%M}QXh85^=>pYe~yErP>^ic~K=9tcgXdFcwe$S9NK0aX0 zaNLbL1#)2_6G^4f-=bg8)4u?(SEr4h!j4{tLO5&7EgC;y!D~@~P%LBzVB~-K1eU>D z-Mw?FKD&2h1269|d2&^7hq%LMnEA8-u&p`bqu#L2vZxNj!5Xh^XGC>;_!rVg%xWM|Ej${!RYz24=vK>tF!=qL z-NvC?`PqG0=+VCxD+Zu`DG~H2k&Y@ zMw!72{W^RuACU!FafZ)rh%U!@>%x& zFb;%HPqqrN^n90eu7Mv;xWgfWxFJ+f%P2{p1~J8ch3JxBO2xgK_DAM2h1jufnrzgcyDSqudYNF)amVetMi1hH{hMIl;|}L=?E?coN!sJ89#Pgs`E?VoewH z3<=Af2!1rInai$FXSUIQN4zCl6A~z=$o2;a44HePIlhRY<48fmt+4A5TMOc8Mn(1W zLML{eI$LxD(p74f-B>4Kv~V*%L^un4UdxI_C|tB4@ruVvp4C=_PH)vH5~c|8L`Cpb zsc;Y}C~gJ1tpKfNO4~Ustqg4$mfj**nhqo_mvHL!q&}Q|?}% zlOzV&t!aNKWQ2__l9KlW;}wDw%DbUR^J+{Nl+g$VtC>(n18V~3|2V+?a61LU95Q)1uFY;v)E88^dj%soTqtAnLBj&lhEN^%Fs~p1vJNu45E6Y%9@B7uMD*f z&8k})GZr*0>5doz(Y@4xX&f-5@EHuv8ym7I&xQ!w!h`UiSiomCV!?vZ>`_iZNk-vh zC$Xvlm$&gZMBl0el{O(ki+YF5>qa|@JHjYTgtDnH3jVFaK!RIIBDk|Kr-BMHimqm1 zuC;`Zi5#5ll0=!WqFO-V#a$>8T;>@>Wms*ulb;3HOrBByuaakyRFXlY9^{Nb`vV~o zUET=c$3j6oltgfWT*eQ2r$OM&`vY($5Ox3*VXm!b=Mq_pz&4v~53+1KyoREx+2-X4 zj{<=x3leS0t~);u9op>E@K2re!<~KZY6jQ^hM0Vhg#K*u=`AP1(ink8;nfkTWM8m| zXI_ztV|AiJ!+=r{e%nZ_jENchX_hlMb5zsw$pF4Fw#Ip4;9P|Px-~ah?EmET z45PK)siCNF#B0P*%7E#ijovZwCm>{K1GORT|H<}R)1Mn`3d38Hh%BZ$E$gZq#*l6N zF=`{I(|_)OI$hi%bsFmLYn$+?ic({Qnu|^Yyr!qtx?t>%oTAE*`EbD)ojG&M>imkY zV)C9<#OpJ=t}c;PrfOYXXf@+?l_B)dTp(1`zk=7ZGRF)|Ak>X{Ap#8yg>>HBw8(6C zEP*^q+e-!a_=>Lb_9(@rNQLyJPQ&@bT6p?)$bmjE#P%t_mCo!wm_95q~0D-IT3~ zPU*2Ch!UrnRgLg=V%;&RU{WGd^$a64ouPK;ppIB)#3VbX1Y@~aSo;73b}*%a+^qE) z45y95;j#kLlRufuL%U5$wk4x(Uk5o!TmBe@pG0Gd8p6hH9Aw<7xFKqb= z%_>6?>ePr(R399jF%vb-!OJl)u^0@8PBumCUZ`5=)PU(Ln}@ii5i;#%P4?lY-Y#6^ za-gE@fa)tZDwVZ4F-BsSC&?9v!Z=fMQfy(UVN#4WknRV_E0J3I=OkR2M~Z`?O|#ieQ#T`d3?YAmMS~8t*dU1IZW|zx^_gd}HfRUiBn*5n-f}*WPGz$^ zQw2(E?(B3WR{)LrehFO?#&1R}T|)Iet)uVD@x+afGPHJPJVr=JD=FQ)E+5E}jH;iY)W+IBayxYaA0_O2` zBIfzcdy2`St%v;c61qa~Xunw4S0JMXKisdVrM?v(W^I#elwq>xhc_uB&xU>^+s5{| zq7K%3&9@;bH(zn2CmbdaVWs2Th z2fIEk`?$YOKlz*-xW$h5*zp>>4;>&MrstS0m)XgEb_X8#3CYmG8|@@J2X3^(m3Bza zAy?Xcg*V#qO1p2#jdsk>@jrT<-Mm8%$=_(VNN%+|0yo?7Zo817gE!kTKS#*W5$?3Z z`fYo=O*L+`dpIYW5Yq%HyeZshw?r-kF2Kd1kalt-wTMmuc5~f$7SQr%m)313`p#q& zoRUD{!8P{Wn^FH^AQE+6Xf>6rDuCxc_e^gIJTKAbu+%TEcqq-jCoxG`(->8ne%auZ zm-7Vc`x-M4T|%=YG-Z+%p+f9b?u0R|PX4A^S1nx6wuXaZC&#CZCh{%By4}f9kBmuj zJv!~qWUTZ&D)p|hkX>p(#6ngAmc0E%^t-Cz8>BoZ5j}4$w->65Wsp|H-mkj_Jknw+ zu*9k(0*Q_TEy5J15qrl8t_D)J!UN-Wa76n%WH)53HTC3=?9Yx6h*mNPgsTFyiD`NW zYY1#ZyK;z)i&EyLbHqPP)kr4)FNiZxbCr4=;Sbt$;J|b1;*Y^qsvrAR3NU!^CV__x zbG&%g?~C~$2pHL%5SA|`y8vSnjU2Tb5Dn3J!ekViH-?P9X z<%AybO#D^UokrWem^1M=bxHayN7A8|!S&f?kPo9?2J;ksDj>)x`c0$gH;gVhVfy<} z!3d}kgo4pL0juZa)1=ooG6eiB3%=fPPX0OS?(2bHUZgqsY+V8(1W`rlP;*l9)=KDC zJzf`71#{?ch#H11I{Ebk3%*KRX;?= zA@zh3?k9t1lp2^(R4T%=Srlh>J4{v3)^55)Fj;*@BR)QWd7ldVs;JAN3{=+dgX;|R zq|ky5^x*mf4I}*pM{41kRU=KOE=s2!u~o*KJC8miK>BkXYgO!JvyAl|!iBg?Rkb(g z^_{aq8@G)UbvS8d=)yQj13!g5>P{I6 zg#Nf|5<1^joiaH@UmQR*b@yY2h3WNZb4jRjhth_x3T@mrXv7ma2i2va3!}|P45|Z2 z3e9S918E^qr!}P2>d=Cr9yRN&V%2AQ53=140sn3hyPpLg%n&5j*sh7X`(WtKE% zr@~?DAM6bp4Dpin0ih2(%KX6|<*vhqKib>kDRq6of-%$kjcm9iQ@YEoDK~`*Mx|*1 zZH?8kbtKCE87fH-wcW5OD2}Ogd(_?gLU)cz+jy&VXI(1o=cv?JE!$!$-5s!CRC+IY z8+zEH=`RN$eGI?gmqolWb9P5Jsz$NFJNZR37^ z9_m;>5^>rlsVpmC>-aJ@0q zF&yZ%klFF%`*|wVv3?lD*%;Tq3w5j?#%ngF>84P}`q^d3e*PHhSU-$oY~0UZLLKV| z{>(#+=l?<->qq>Z8`9@*p^o*#_`k+@doI+me!5v_a&dKVGNN-j*CKT-5`9B&_5l%B zkH$Qr#1E6}u=#$gb**ZV>Ww@_%$o51*-%)Z!4&3`40jTLV?qm%pCXk9RQ+RU_Gge` zLNn+Ff(A$9jnp8)V;k@<4uJB(3yVVMwgTt{KYa{dnCa9{e~X3r1+NyrakLml(Ps_C zs~;T_2hzd^CrnzR&tr6SpntqfH-!i!HPe z@xMNfFNrHOb0MjYzrim2#l?!^gDneRMj*Ng%QG?%B@QHsm8JP6%zR3PChjDOg5cB-dz7bP>3{9$R3u0anx-??y?J|RbnEhE| zo=ajDjF?H6`X`?M5nSlfc1U4fVJ`Q_h2COs;h*1ah53iO5pZ&zi zMBPl@FP{&{=Yt>8&jBCS5B*N$^HF%7@bhtVKKT@#PyP*8!+Z|TCtvsiuZH=LSzrFj zSK)i|HTs@>lfEZzYmG?a?E#wvB^XGN#h;cFth~WPCb($WuuDJz+@YM8 zj5>y&L6n_Gl)+(JxbO!oVe)PcgMFnCbxfWCYwSJ<=gd%;{&=pce;sSr(v zOQIp;RnhHgx~7~)lp?!08duj8=}pp&10{Lalzs6svySIoQ*NNZK!R~FH)>U~Y8IY{ zbYZ(Lz-+!L(w5VdxkvB{toWv&1Mx|L-sggVN8IU+p;Pls5%0cir_?K<#L_qA&m;o; z_<$$%P5B*%Y>s{En<9~v;@Kz6lw-wPLw6>o@T#Zv5b|Ubd#972H?aPWB|cAi-aqM{ zs58q`EjG1M%)CgXIeQM ztrfqG`bTY#8b`WPMr2Na2+TMG4sWe+JEE`ym)Tir=D}^%TJcm}(giO?51)lRsJw$u z9;TZ5nH)y_1O>GP-lk~KtSe$i*MA}0hK7s%pX;?zlW@7k{?{avZeJUEcD z=b;w)e?5x#zfhNOM|r?Jd{uMKvb#q!Y{6k(<1_h3he#!p%`knEJfaB{ zHI!;TI`ImqJL!(D*KkeR@Yr~gc=hQ_WlKmUj^2k&9MaNU;MIu=;QNR+7s=kd9 zO`J^`piQR_Nhfa3rqSHFFv7{9U2rGY$>UPyT*5XFK_|7ek5y3%bPhG7RvoM3au#(% zd4QCg=h_49o|HX4!d=BUx{hDHUe>;js` z6uGR<`t#jZ4Mf~8)l20O5}}^^<(*NV4csr~Fdw6F+t<4}nydrn9V{>h%xHM`M_sAw zB?d%ym_`cAgLSG_shSf7&v3zUkVjCrbkrZX?opzk^dNZeao4Dur8eU2TlIQol}6f$l$zsPI&ss#R1N*^*U* z3d5JWzpG0H?-H7!g1AE~75zFMD7s{RE! z-Ncr^lA+V}EckLAIz1P4g^MM0`VXZgzEG!X6`e+=B-WtQ@Hb|M%~zE!o-MN+_A+#m zP#>k!zYCp$G^RtP%&r_yFR~7h3&V6q)YNHcH{F|LrvGFR#@7=6=93vot7D=zGd`JF zVT^TE{3P?UUOX>#9ADr#)U!%%wf#b!ahw?SiJER4d6i0qv6sbHb1$Rbd^|N2pPyV?7-cZMI{hlG~+#l5`4_Rk@RA*>EyoW*^!@R3POhu5f|KZH8gkNV*?>gSnI$NCXJJl-VWJziFMCkbkwvgy>j0szb) z_U@FP!#uOl$PFDt5M<8=Aj}8tO_*EGxo4O@XoT(WT+9ANT)2wm`8*HW$tGz92QNGW zVb~G?(&elE6IA5bTTSd_Aw+sH78bwZqxM8$>e5a+i_#jzflW zN?W+VTR!hnr?l61mH$YjzgEuAT{~RioO2u7%uBhx(2hBxso!5@9XT?*X!PKV*@G=p zn@j$DmM6&A{g;~O_Oz7LMs*@b{u+$j0pPZh0SoUQiLBLU&3C&Eko z^s@9*>i{+=cJalQqR6o5nVF~K@OAw^|c_b$M^n{p+`RP6WYM(u|*jxDj<_mwg zFE-Up=lW{gTkv}1J7TV*f2q2uV9&QPlaafg03K%hz0Xn?efT3tS@iJ(nW{*f#Xc*p zVqX-w)INQnM^j%vPM-iXJhbDeXaZJYxq9CFP%*5tkY2j(sWa5ag?aO7H7MW)^%cuh z@G|QuH~hF7ciGZEXwpQcVLe#No;vrM6$LS!Fvlx`C)3IT+{KLrPznWv&*4p!OyIJp z&J$w#OpA+b`GWtbzusS0tl|8P6+ZM+OZeBx7f2yl2!=2&r7eK_tl**u(;x|7jD*50;X5R#xSkCFgAx=i(JePGcAl3xdKRl{A27@?{1Z${+y71)F4OL zU?IKlxZ4-#5x^_)({zsXqA=2ZP=?Sy!OVyGx^P=)|HEuw@3fZof64X_unN3mGX2|M zFMYICSav7;#IU|Xy87W~{;DinLK(M>^1>(?k8uS3}f2uGeo2xb#N5Tj;o1VE;- zLd3hWLyUQMlw5T6rp+g-{kI1oVkena@=Wnw1Mxk6=mA7*Bh!lBFe|tcE=sLJnH3&6 z?Sv;4S39GFvf$-`C0A|KPI-+*FWac(r>JZk<6(||iV7eBa%?iwir&{Mkl#Qm?`@F3 zi;%DFt1N7j3U9_w*kGoE^Yc)?vyLDcHLr^_3{XxblzQ2BMv%xRv<7aH(atcrbzKG#v%V2>mpbk6RbTDG8x6~ons3rgAyZ>~f zj{aR3{jThEMUXWjn|3j-+Sy|@K)Ew396LTILMIbS!A9!T_K~hgCqDGVX&pk+8%feP z38@}>=)~t0*y~uxJ?-Gp*120W-e}NbM_EXvl>qHds8G?1-!trp&7_0YosEnX+P|J~ z*GfGnxS4=;6R^ApE*W5NAYj6=0WfSp(~27j_v|86C8kZ$I9kA-yL9m->d&~2fH4%U zkgmDrqKc-G4|ipxS3Z0413HAe_$EWX2BVoPyS>ajFpkGPuA`LS0!qNcE7_|f5YQlN z7xLB%IFz$VY#D<4+J?X3bLsqCtC z;k<{~!*+tQa0R@0f#N1PcLjWgk;apeYG7y7(lp%qE(pMWD;;#2gXfYlfqgTgXGH2> zxOe>*95ND&x_j3%qmy0OmQCt#^Z5q$gFTwN`8?2~)o6i0sO%->f`ArQaEqQtKyyHV zyE|uO^VdX`-ozq;d-&KxJk*K=o2;b96&2W~G|M)n3n@t951_jU%9{4Mayv~ER9*am z5=D@u>uxUp}< zMvENr*xGUeO_DS@yzfnR@xUBVv_~>Eec^@Tg0#KQj%}@U?Z0+(vqP_Ylb3ipa?%Y|7%laNKxnUQI9JAg@`IY9EWx3#kuYm+S#-weAMurxxZJg z0nqErkpBM_dV6m+^S?%NGxb01;gflFZ+*qCFUK5jrD8YOBsvrHg0%mU?wlI6u;S~i zR*my5sAINi+C558a?^d@T^PjP^QgC$3X)lb`kfxdyKM{f2L3LstJ*tgwGk3B7ECym@< zD}YS`*A5AVo$d2f`Ec9n|Wx^eC0sgcpTuqg(|AIbV z*?_LJ2jf!Dlq0XEs~D$v0&R4a=N)R%m6pkub(P1rQax)9O3JeiYs|Hv=9gON=>RFJkL(L3vH#Ib5;^I^c#n znc#spWgq)C3_5q$vY~n;Q%M0Sv*}u6B$ox)Y$RiC^tDEEd3f7K!qe^% zj)dnfVrwB(Q>sTY#YVERdL&ag5-GEhK#tbjrw$(Bt{Wckw#p|PrvZu~ftkL65QAODs=PK6d@s_A!us=LM9;;Rss<0e~l zj0_UgF^??Ht)lzlRWpxJuJvNBm0Q43@1_)koXgF<1r^_baqPS0z23Aq;Up9CY4H$U ziZEeRu*>ey0t6;9nG|lZVTVEtDkR%0@I{ZJUGX|KEk#i=j90REWl+?H78ONY+;A9#Do9OTYI9Xw zG$U{Gq)TKgVvhz3@PbgAlKvx_R|#)W^XdSF5pt-l^0<^|L)vPAeAWRz>nYgpTyp6| z2~Rcjs*U5NG8==6r5Mo%Z5jNZAs2%6tRbFjL+7%F{D>QaOHE9`ao|$RpgI=7tv7k< z7+Fl}Yg(4PKh-&5ircnB-4HWcler59o%Fn@&g%eQVk>^_elCdWc+JT>x94G75!F#Y zzwG`tUuR`h2d6oJO-(bkVH=3*P;J7kNTw^&lBm14fP)`Jb<}aMQJssUIy}}%N?nLqdGr{>fp>~h<+}Q>Zp%gBfR}Is-r$~V>08(! z&dxBIJKm>1vovbI(I3qT3m(SdG+cfO)A*!{N9I+k(Xtz#uM&fBuI}nuF;%i`^c2O7 zTU48A(5?Xy=4~(jY2B+hga1%k&x7xJs^<$QLl)GGV2SAN9osi9heQ8R;M7y7cd>YN+kGWT5- zXW43b@qB(%N5vUO(zv%3QO#OAo56T5wK7z+O<0g@n|Wh*p{`_u)SA$wAC+2^SipT9 z$#h~)GRfiUnjo2`N0Q0cFv-Lk;NGDm6AoSZ-b^oAl-*}SvQ)6Q3nf^^Yd2yUq=+!Uyt+|PoV)Ryr$Cl=JjH4@0wWD#4#SINgSlTJ0 z4&$0%@zsAjM$Z3rTp+F=mk|%+$|5bj@Tpx5g?KsbvA;<%M@*6{FSQqh4hLGLLl}I4 zFwoL>2ts;9uE`>DEg!7Ksj+}+>MAE)XG{bd+v`qXhuD|izaaHNlq_3h$awd@z2zGI z@b$T8S&n<)a-Ec?821dMJAkxJa#Ds#nG;s?E55P`D^|wzG})tzs@)7SySoLpi&n9f z;HH>XZtGi19ZVzMnl_7C^I9xbABP-6U=ywA^!A32H6O)5a9gg1vj;GU)qe~1F*kWb3Xmp z55P-pb|WG${{4`&awuSymwD?5H$;>0lDT03m?|NSJ$|X3Hh+4ke?Y1yyk~ejJicEZ zCA0hu1Zi4VnYIkxBob{EPY76kxLqa;UlUR6CyeHRa(*$I{m#$TKCJ9%h zPK}1ryG@4zo`-VZT`co7WgqEEh~+duUPD(+DYq_>O!iAHGNsMkxcyBV4?~s-ORL=W zi+b9~B`;Sa-IzrS_4yV0+`4EXe|@DqEo5%NffPTL+GxtrYT#`1(2_>+NH>)x%q8L5 zNf-}&(eWsgl_nP26EV|dw?xYp?1`ypqSIvZ?SUd%4!I&pPqH;Yuc_pZQkOA(m3R8m z7O1cKVbGtc878b7^@0Lw_cZ@0>=?BRB-NY-Q>WUcQ8gMV#Z(P_y#w3y0UY~s1)^QOhrih(Hb`;bje-Kr+#pFOx}Q#s{@p_a%gyQV0EnN z+?4ZpR(9egES`w1mer!WApN}BcZ)%Ew}>30DWl39m{;+1xLwc#v&#Ps>Mk56m`e zn8BPh#XgacyM4cH?%gAIi}-bRT6z2oQ5$Ast$U5lrAhjuvj|~_C^*Q8^Wy`AkE&ga z)(!Dp!{V-HvFT#Kqf#z>G(caY>g^`=07ykkA`Ot7y&+z&GNW0_#Y`E|Ol`)=!!xBR z76RL!7=~h|w7|lfxW%2&kcA7qFUA)W<>T0}Vv6YeXy@G}onTNJ?}Pas)_Z(jg{w;3 zEhR&Qb%SU+&EWHVKyz<)QL9wW&CN6(sF#-{wq<2*7ivg6la~ZOG@s@+t_wmNHutER z^F^IdNC_iW;5CV^j)P`LU!CYO*`H8jmW&s2AdiK)6aR6g93zMGh}#7F@ZtlnwD1ZE z|F9uE0PTajh!MF{Sk7X1A{vFTY0sK3GF$4H_JBAA2U!1}dgjPy?x-G!n)4?c; z4*d+066}9{3H}vsr}QMis=ja`)j{Ao4W4(H=ryT5+aB`#ay)Corrc?=flS?0*9g zAp4*o-X&x@J9DAwLZO7$N-@lO!Q3u>_Ii0PSJ1d+jI-C7X=={i4mglthIXaM$m3=v zqjI?=v6 zqYzal0i0?@nKoeBYfS=oxW`G*ZWE$}znuch3E&h{GQT@kHO8;x5ArULIREt{=lnSt z#%DOZxRT@;->o9GmM}~JZu@jH)K~@wvHS@lc}lL!+9)RmYCCPK!xr598Yk1#LAgBP zEkBcsZrWmD9uH_cJ+xT=O5-u<$I*@qPcpG14{~2eKNm;!>sY`YXpnz_>^3D4E1#u) zS44g1l0nit*OB3pUiU;nxw|GJI~1#)yfGs8vwH7WDO>9c!o*S*m zJw-zut;N^lTB7qK4Ep*oXv+ts{ywg+T6J!W>Zrd@qdGT7b=2P{yD=S?TY=U@b@X&! z-&4lOZ%l6sb*ge=HG=JqP^T&ls!&?hNR1ZSeM(t>|$+zu?4!}jj~;w zB7gbcog;&ole1y(7&T%BppC)mhCd)FfCM51rhPMSa~Q&>wDwbP!<~M% z+Nz+9j-n5*cnIt$S~u^&qSU86g78%xaBCbzFA5#nQM8g`Ql>*J;@06nI+CMkpw4^6 z92xqF!p@e_k$%e@>9XVovES9ikBj_g>_0x(m~&^2jk)^OjT=ASTSGE2&uJCGVo=IvTo zoW(5ai zqU7zbr-w$(QpnVwfgl3vY@mml3!TMj^anQff(b^)u|a7baDGl`@=m=jn{I|`vyrx` zx0IX8o132N64gbt72!PtS`?csdx>%*h?F-VsJe^T%ruK1riMsugx$iAbW`?Wb9lfM zh$S<;-Z|oaLN(<%NMPu#*snuZZK0Q;43_&3XcctF1O{P@WetFtWABw==y&MQ>9#0J ziCdMpu~LntW(xzMh1;|R^%tDR6B+V2uszF~G;v3W;MR)fj1yoHC9tzuWFi^+ZtixJ zX0;%{DD-=~_Debokj08tw!2(^T8!hiUZ$EWqUMvq^4Uzls|8TxbgEP zF!99!ALc8|9_l+kO;w@QoDC_YL8(+sryP<_pGy}S&EY#4(5hMj1c-$P!=0%lqeUJY z)Cz{;VN#XWZChm^g0md!T^azsFA;@^OC&v36;U%4ZE&Y$X$AJtG9h8y--9q(M4{mA4hqttsO5ONKbiZ8Eu6MM*Np5CGm_I(elYQ4WOlcd@^NpLf3VUHI(1_dfXW9`=3t=`G`vrtiV$z3<%*pZC3Qe|)A*;|=T| z_`nB0DA%tafXml$?>chlejK;0^S<>@eBzV*9E8t|8K1({>-zchXFl_9pXCkgGY>xa z^Pm5MUc&w#v+(&cK40PItN8pUu4Mn(*Y)#_*|Wd-t#5t%+uz~k?En4U@6P$&|H$Wm z=gysX$RURwT1hI&VffC+cLBZ&{YCA(qCI;(`;tVz$K#52y`-I2w4aomoSb6crHOud zU3>VRmgv>(%aYUm_l)FBeEad`CGKY@=OpLamzTNgh3@Ak;d?=HL9#qqf$xRM%H)U1 zKyp#?qhwWbaq{EjlH}6lC-S{4xh%OH-_`j3G`S+VGPx?bI{IFd==a*>+GG&l>-_in zgx?$Ry)n57-Y-Z_}+={UCG_a+T@<(XUV?d zd>>4Ho;;L1EZ;|xUnGwv8+nnTg43&az88#&37za2{y_*R%Qw0+2HP}ja?iHTY|firkE(d+ zY||iZd3{Heldx+L6>T}XqOOF66^e+V#fdV0a69~0w2LMhD06g3zdcj{f7y-cPq|)x6rCnTOkjTzQwmjR(Y2!l$bo(d% zTu8@A$)9xi@(Y zXLmuXKaRqJ`JUdv_E2EGO=u4c;9!$hz7fZ*(*W zA9aN}c-BSLH@G*&VnLBfVZ-?YX5qf9l7P31Mvq@}w7(#5MWe?CmONtMMr`;<)E{1D z7hpo!`(X=>`VXNHUC8(^pnp6H?6uqg9*-JiU2TvQDr$odN`vYh{4{$&LG1>A8#Tzf z+8`-p4L%?ZDuw>Y22oJE!9PR|vaU8r3R#2qNrRdYT!xH-+713CYLIm^IOKe>V9kFJ zw0qG~dMH?7J}1;Y?8p)^9A*W2503nNcOs4oXiz7sN#&XoI&CZI#RLDK6u%SQpyyN* zE}z1t@8B2;sU{F#%#zz}RMAX5@-V+5nt;Nq92I1!&Qz=$O=E6FA^a7DGfuDqdo9Nq z$3+dYt~RK~ZfWoqSD34QVpM&Nds8k+ER?1C%>qxSz;im`K|yVJPKz33U4@4i{#k=J zN`qa};5lp%1+^ROj~Zm%2xHf~!rTDQi>lw?-W+1;D}k>jaMuyIq7nFFmJAxW(bT^v z>JP6HTtD^iX8mhWSTq951=1+6*Kz~6G-{A_wLucNSe6E_k_PSmP0A7!)Nb&Ks6p1% z26->0HF$+Is3gCEAfupmgM(3ntg8)@X?FMg-8f4uFhnGo%n&A2z z4jBct8@wZGkaaT+sw|NZigg6-QnVzpt9iKzY$-J2Ke0z;t& z!Ri`V5FJvX`U4xiupVZgj#|a5hFO8Cv-}q}upFfrx{UJ-(h3E&Y4yjbMb=eX5zbEB z_6{F|Qs?J!4g!CKj?Ys+dV!ss&o(t~<#|4zhv$?cXEBj|4#>piK_1Q~Jfi+B;BRM6e*o^6g^>nel5YPfg`%x^lx}QkwM_)(FP_dwO`rYSw4*opW@!mwR=j`?o#(A zcTYkD>!vp2DDY>qkCP4fNKT#^b%IyfD&!=g72x}zZf1ao8_AXM{#?$6PsH2Ezbt4v zl?;UftDhUrc~MWSD?Pd4$R!Twn8N}7!Cy$AQ^j9DW}hdp3+0-N`FuQ{g}>yI<>QRM z#Vt-zaC;x%a3!1uWt=UCj;%b6WWVT_B|WVv1Ekrk}+N(yWOj) zuzi<eBW<#&A#p} z4KT3t_sG()Au#9@YGP;C;!)3iKH&Nx;rbTf90@>We>ncj(7`pjkN&1~0Dz!#BHPvg zcRk*+(Tt6c*jt_?dS(lHDt5FiMc)9r^=!HPd%p5DY0cSj0Hkxtqpc-t;>g=ro(_PS zeMp?v|T2)j;N;wj^I$ER6@vI0Qqs0qe z1FdHP0r_|GeUY;b|Fvq_m#WH0RUl~^{=r!h&jSgu^C0%zL|lSg$YoDqjtX?xXqpFO=CKa9K)TrtYV2!HoOpYgZj(sUk++iYS zu1%~k%g+z^eO$%JK|-o2e(W-PmJ`rVV%XqXnyIY)a!oVU=;Y0c0Ew|6vJnLNf@#f8 z*UQAgNVxBX{86h5-!n-9OD-kJTF!{9TpjLAxG)0a>1)`ex}*rx3=j^u+7WYqt!1Xb{bFWY2en7OAQuzwggk ztKNY_PZFC*!=WugQbcWenmxXkxUFH%9SmbLBhh>1#jrV(TG@%yFXI&>Qac?5IB{lR znptaDHHy=uRAAa8xp#>#kQW*nd{h!04N@-el`Szi;2M2{-UC#jHC?;du@H zKlf*g7!{pgP}?6B`Dc?3>OT<}{egVrjFxka^X!dB7W<3veT3L!$eivC9_HiTro2AI zhj%KE%HQvBuRX?J5OS6#U|;!ZFJc3r_UAx#QIrO$hn(vOUe81Rcz}FQK?~b;@)y2! znw0(5>>e>|GJB-^Juy4Xw)!N0L?(y;+wLQnI)(IAG97-;R*P59uXoRG=Mp=UYFT?~_d=fmVGIrKLz zQe?{SZyEtIK{+{hYIrt<^U2))`1vpblQwSze()Yh?3R>?_o@Rq1S7*S50bRdYR1_)!#CB z2AL`trl-T`^tZZD9T`ETp1=Vrr(2QgRZsvY!&LdScgHbgK3z(rxrh;u3Lu$U$m^J;ngz6viocEz12E5IIuWDw9Dgn42-Jai6#O+S z$6qIgUhRf>`Wd@*$4TUE&0l$_PKuz~J_nT}?2E=znFg2f#Lb<7*dBRSn$(u zwN(?t^|pPO0i4Te|LVtDusA1qR+$jsr%M6@r7mOI3vqR%mH%Y`;IWN3vU}#iR zzzT*fSb6T*or!>vVCDSKxPc*V$Tf(wBD`r}P;bs+V><)mnkPpL#)YAA10$r%IGa~H z)wET^Z zyzFVxWV(RT`*X@}bp8b9>O|PB&iUNE9j}%r`WT%lnFy2#*rycI9mE{XxHcwJE2LlN zp%1p$ydnb1GvA>7nfb4A6@vJ};4TE3vF#>)M%avqTO1M>IPF?Glf(sx+Y_HUIaOe^jOg4_N>isSWlZcKLH}{zCq#Wy&&GSI zNlC8BU9`k(wgd-&$T11i(J^)(6{gieACpNljz6G}VJ(c|H}sY8_%B^$xsw?>tf7xD zA%q@}uaxb?PI%_^1?Y)4i)1z0v!WqTlf`=(^f3w_I-*0LbjEml0lWe;xuB1k=S&ft zmR3Ca7|w6;TKT?LM1A8B$n_1fF&&*Mf4w!(M~6FJSdF>P0B5gcGkt^P#Uq1$r6<{` ziQ|<&%1z_L`)(g8?u=e})$wRj~Dmj5X%%R4Ra3c@n=3m)WzKza0uVATgH(z2< zwIdI&4r0Qx8sxbmLXm1KS@K942dEQ{KGK^6K@)OM9|Xq9bx}q(PawHKUE-f(?zlec zUX!6)>}6RpEfA-Saw22vgu@@g;gWGe0*H)8x=%v@IBC=f=e20s==~ZC!yN(kA(qJ> zW|zqc!&$WN3~djwO0ErW)>$RpVm)#w?g?!Vu}H29Z`N5PM-Rn)q3vjmypYMKTP>wj zLDogAUPUflV46Bh%~iRjhS4`Z^K?k{fIXReK)7Ofm_TEorpo4i7DhGq(2lbz|1g2) z?S9W4Hp-f-+iiikFL#+YxHZb2M&xh9m|yXbo9fCzTFe+`h{YMz%P{?LJ8;!Gg7jO! zB=X7O2pnm${1q2txct}0?O+bK)c4ElHFJErgPhnE%dHR;Y=hX5u(rJYWI@HZV{0zO z0;K>gD7uaFwnW`@_!Q`~O&2!%oJ+k%&8;VPhIAW16W0 z>NCr5#qx*EQs?_Q#-R%;-fKhgKBL=X&q$#kOr%ECcnLVSImqjgtTTH^N zKhuzYQ?iUn0xQ%(E#4%h6`2@NGaksnb7mXkCIzfUb_I{x5!?hJJza(m(i0tH9aeg} z$u$+_c|+HdfP>#CUAe39AqGR@fbUL&yAL5}P$8JRmJYz7gSD|v;XHi{hDB^;M&^=d z)Ee3Mqmgl=0%-Za=}a&_!eREpzez_cEl~IBC^eJSx5wZMU6P?O>C%|PYu_+J>7vs5 zrSgBsx-UZ3SwcYB>WHL67~J-LoAYX90(|Z3ToORN&6bzha(9Ex&D-9-*VK2s^Id!I zgKYM_HS^hj;*&f-w#cJZHBuGam=m9$B8RQYrYayQ))#P}TdJ`pG;hyPsRJht5lm~4 znSieiGJ-~4*NMEbpfhN9= zFbR%Q$l`|PsD<-H8ixr|VLk5UNG#Fkh63(WLw)N;tgGC&9SE?c)s2ODXqNFs?I^}E zu(giftT8>Sf=pNqsmVEwGftfH*?<5I)>?tKz1)c=rVAu<6y{oQ@oi*l;smBOk}1jb zf;Dd&iycb49Bod*J0B*>k!q8t{mcTUam_Af9xj3MCih7P z@J+6CG+1N)uEGeQebTX_4cWq`9O5JGnLfUhISe?q;@QDg4V?D2>edf!K*lQo7N~E+ z&lP&Vq)@je+xf542uWob8S@twTC z9uaIZZl?R=fi?2&`DZ&(j_|N7bZ*SR6J?JFH(u(Q!^H!}?sJq77Y;8}AKda=3lC=m zP;3cJtMI^yMZjt!0C@mpu)K?^7lRk3+8E0At-}ashh7Z*Qi2J*HZnW5n?>aD29Sb?FWG(5x@Lj~j(BZZfd%8Mymte4 z{sZDUpJo+^GIgDOMOwria zh6M#gB051AI5^Jb66O{Zw~n|72^w^G9jYvS%aQ!rU%(E6HzT8lYXg#&(|8RCAht#3 z>BQkUN+A>mL6CIt$1XQ@UR3Dx53G4bpo%5Y*jW(abb{r!U0CDN4cn?syb+Is2{F+I zxnje~fZfw3;OzJT` z_N>~&tfmPj!LE7nfJWxJMzAb%W%uG?J!{G-Cn;1zKDgaBC!(&F0h12|@|b*3LoMWj z$j>~tK~9KT0J$LYfykmh3q+~1nw1Z&A|E8zx7c@ca?7pUbp^!FBj7Z3)KI_)1*Ka_ z@mOa?cgg{0Zr;G~Na(rhf(Zw5tvZiJbu?FIqdJd8bu?F|Y71%|%ft3~R3{ua{&jn7 z;Kz)>Jh*kX?$~%A*wloLx80;mOCt^(@sS&Kbra5HG(2m>b-HrWh&?#+&vfIMaVMTK zN~#%d#C@h2Y{xO1ZKGX^GkmPc?X%y;<)A+#_@IL{^r=L4G4yod<61n5`~(wWp=E(` zG`2><(a;>g(X!c_3ca={dE#gr+k+u%OZaL=05y znQ$4*_i#eg!&@DIKn@2v4UIL+nJ7*xJ46a@!miSGq|LHnM7xHF5(Yxu1|c5dhIwud zsJDpd>wr2X3k)$}cT~2!<~mAkqJ#FJ#?FFfC=aEKC_&m~?y_P2!o7WB1>^8%l{!Vj z@P0EnBPC{MMv91=Oq4TfdkgY!SwMuzze%7n?jqKX8s`C7wZhIg*O*YCM%*evCT%^{Xi`4n8r7kKS-58DW zQ6u#%uhf2{VnKCJrroNLDl2PFHj9ByhiQnUH)|Hx|Jz^jw3>x&-_;0en$+a$M%J zh}(LL>73)TOCsQL938l9OMnN|Wx@rON>JTIqHz_?GtA`y24gaHuX9MRRp+Ns9qM1e zkuin|tqw97rYOvT!enxN#(2C5OW)j{PU9KTn0W+*lXcsm)rnh;>>R@~ z`SAn;cr(>#V~y-*cjR;+q647w3QW-uAlL}DAtiX97VHic*@HkDsck9MYN%aUcTt1#>zsszJZhhf;Jgtw@N(p?Z&Vjo zJkCsKQzx2!-K+vtx>;ra)-y&l1&vn^Oxn)dv5vLI;|(hXVs^tSVKEGb)|H|bQ8-~{ zVGnBt0hsKmb}#~%r`HsH4tur-wDYzWkc1}8EwH)1i1#xy_z`lty9?Rb~)99U^<_z96DE2c!b#RWWc+Zjn4Cf|NrZ4W!~i0XStt;1|Ta z1@F|*U)5IB0ZKWQuk(Ybj&4OA1!~nfJ*uPfuu(r}Ms+9&4-38jzkDIt z4^Oh9y@p^H|6B3Cm0fY|qv>+`p7-wezWt}Y{{tWV&;cKo+UnoL;O$=ECe7qC~2YSh2cfcRL6$r$!9y2mjr(wVw61%w|V z(=?=&$NW9*aMiT^-|#rowe#v|8*FyvJ|C-=WC9lJuPXs zOjw?w|EG`?)ZDEJ4#K=nZ5RZlLFKD;2>OG7TO;UKwmm_Yg-(s2Umg`fsrSx$sSwmn z9}@3N0IDVZy-r0Id@)bA6h{Z?l3!wTOV>3DstSZDC(kte165@X6n)Io?pD0nMx`JB zcF0v62ivJhOKA)hI4G)eh3MaS!ZDK_n|X)_x}Vc$(O4HSs~MA_(9|d^OQ$$9eWojY zGtEjZCC#kK=mTapX|sib&;N?&PA08MH|wBS_$fBdJx^;2$0&F|jwv%d0*+tuYEM_X zn?$aN1J*%!xhvfT7k-Yp078qGH_-D6eG7Ao=lv&8Fh+EA9$eCCszaV6|Ln){C}%o! zHXMV1dkQfzQSi+8WB3&Vm{)2$1n3%U!l^WRd5k#uD1HJ4>CGqSN7M0)%RU7shY=_6 zf#q7_thDV>;KN*PZfUQuMpSpXA^x+J%vYWf*nQPGZgfy#=C z<8fK1;YS71(Ro-FR{3q3E{W6iSYfuFDu|(l37TQKN74gW9GihsxEW||ZEX%)D~hdW z0!V@73@!-Zqlt&4v*yn2!702P<>6mo79JijHSgUtp)6*k{R6|N7gc9D+`cBtVevAS+hUkpu{tfDLk+qeUx}4l=3!3w(lwK?^T6OtOj8*cT?iQWqoE z4Z&s5$?BHbdVc6o|z5I}3QA2CoAV*gZHK zVx-?D{;)gWOn39oyQyu+4+zIwwKV(nf&Fa3=ZiyX_7|P<=8R^)ll={D=hPfhvwtvj zY70J&+eV?;iyy(8G4Pj$YF}gH^hg+~p?Bxupm)nQPQM798hR&>3ccdSB3?=_iJemo z^!_r8)X>W#z9G4H-J0ya^pzvz-p50yhTfejM-607nhvy!t>#Uvzuud z9V@5Q;f2a!-XLu+=)s8F<8bej?{$8tQ*}_B_3O*mSs2v`2P5m45@hRLyIbfT>Wf1M zqykA00&J0Syf02tfdGAaDKFxI$K%2{$p)e>dapv5oZc44o8suGM^8O*)SJv};q+Jn z*st%Ow=Q>rfXp2k|Gac?Epo1aM*?-`S9}$lhVXlX5{|QCT|bsGxnZivRzo}j@rBK} zIn}>IbBBlK?&uJ1&>(~=*`LLfi(`F^{ zqPyZ}XFb<^5H($?=oVdEG`9z?u@dbC&jf-hMkV+r(2@lRc+#N`Zx|HKW0*EDnGB?T z!A>3?U|uj!Cq3}92UPXH5D61}1C{yi()A^1&uR=nZv*xp-Uu;q6*J$bLD;{qms zuR&AP!kPR|(>TgO2rV(Z>T3D`&Lg-NWJH*#+5$k*DG|=y7a$+<#t3F7+ERg1UvcEV_q=R?lO>kF*CTwo1=K@&AOmOUVCVK}CW@Q-5 z34hv>bn1pFdTnU+{&tz7NKpbN$8=_jcXAOUo9NSkR%Zgo(!8*f{w&s2^;XcvW!2`} z(*=gm*G-|XP0GY{br&&W>Ey*cL)S0Vo7#ION*`$wnaKgn z3;Zx-_>BY>w@b!QI<|sXTbvTk+r5yIPQ($zqSVa zSLl5yeK8w8pPdcN4Oh#{(DEeggcyxlsS6_HvMo_ zF?KO|I5*2air34lnk`>kI@qVOLu9OXCm_`;`N=WA;@i4XRlVtG%drp^hUGX58c3g{ z?_N{+i6%@ynUBALT2wV5Q4knD9co7UPHjeVyofky&df+e`=ettJBlg!AudG&=@Gnq z(@#kmMS#&-w}RTUG7shlxr(NPkGw%@h3T?5V9|uw2Lu4jyUZHD7ANzvM6HJw3WL7< zy#aqu$Q-eWjG0Q`3%xRB93;&9MSH=E{ms>mD{Doa)rR_|QDAYc<&EfX=Gl$@=w2i< zOhOsA0#o=KDwV($-9<=3IrUrK40WARI~v_DjkN%%R!tXy>AW1Xp7r|qFZOb)W#$hS zg(23HLr|_NMZnMr0Yg`}ioU`VE_#!u-J*i2D<|{`^aV|A@20zi&)6&}1xzB>%yXU8 zNRi--i6`){bZW(b1}dc9t4Oa7Ir?G=8-!Yb%XB4(BSpVjkl_Ud*Xs<+-7}@53hM!0 zBH?FN7}!Z+V0OaF4!nd!%%7K#A}yyXOURP#kcr*~GsuK`E11blD7Jz**nnA232@k) z>J>PMDx1#CiK4kk(Aq{RC(#8xhBzwNmVy9?6F7jl*79pmz7G)xP*)RF(0?iTB|@Z% z`q2cro)!jRh-8P=h;+!SMkOU&A! zYINv^OC$y*>;+*EG4Qegp5gahXk8c>ky}~jqX)`6RTr+pA-7^UIgD}Un2p^E4;vU{ zK8MfRI6E@{WjJF89%mS$T>3;ARK#-!lj=V;}GGb zK!jSDegPQ-Uge@b^L?Hwstr^=PN{-qf&Kg&FrP*jQ|1g2L~scCS^%l$kaw0wdfI&G zKvdzRDbjJ1DEqNngY$sicN0oLG{L`sa*7fL2}D6cQ<|iyAPS`O%)1>dBMXfSCA&+| zg^&f^cnbziK@^h;u)(BP4jn(q$YLrWf&CVkW_P%zIO$9lfA3HkS+IloFb#&TWbs@f z3u+pxp~RiKED~Y#4)H8`3@pu|%bw{R2T&;qlR2IP?Dv(xUb#@Pp9ZiIWdd%exh=TC z94D?g@|vaofP~MafyHnk;lpsTJjdp-h9sb1=TCROLSmy|V{nLDGP%bJ@fpNJun+ot zCNN2(co4ZK%)A|=gK4}WA*HxcNXQKI1l|!vCaO0@Ts!6nG+50XA1EPC*B(qB zCAcRuC6Liz;S*H8jZho7EIp+SS8Mu4qIo;B%EuizV-*by&V@QkP{w({i}370ac98L zMc5Z(Sq?gR)L=u3ZfGzMgaw%j%pl#J5BHE1L08Q0k*E{HdjnQTo4JJCveb>%K}Q4m z(k3v^0y#@BAhqE=VoXAH%Lf~?Bum8cdQ?e^K$bARE{I{ircAbpbS(;&lsh|X;?I{b zb?m&jlM^z9oppFP+A4`&5Sxxgn{3JmAQ-B%HontgF_L0zQH;2vHkSNS2{MZB;1u;` zB91XCzPK+Ca1lTFuEmMyOic$IE~6%Pupq&!)C7o%6$|e2wk=Sk;jeu?;ulbH0odsv zK{${gS;&<^BvaMOq~itW(XU$Lgub41TTK$*}O`_f9GjU3T0*^{-JyRs1edKouno%3t2 zeC4ZN{c3K`!tN|=&-(A&poJY;*rN3sZqnkUZOwn;3zUaH)>lLV1iKn!k}-`>ws`d9uL9ZA9yl@j1QaI7{1? z4!I9V7UG~5twZe4!p7q}GQ99Q_QY1D33=glXaftNX&Zl4ZUYgazQ*6PiN9bIZ@%cE zk9JENwxuR-KC~=t;?LVO@pd-xXK}m^#-9<4oh?K8U$Ko|4xz8{R=)hFeEFw8x%KOP zf*F<_<(`=S{Pt^paEtC=sN>$B5H&km+WX^Td)WWV?IWQ*2L@Y8^5(XdmtQL{pIL)% zt-##Om;Zn-e`(_OgW55jH|+e#o6Qz{a_>iBP6VH?XA`es6aUh@WPCvSf12C^>_2P4 z=kK;@;#xNGJ8VK|%7=h`ANh1E7~J_$1;)i}AJYz;e9FC|p1l*|xu3sgU1XD{K)@BY|BA6OLTiKr3r<8$%TU|HkKk ziEX^+^@l%pth6CT(-2$Dn;TnD`-^Sbko@}w+qmcZZ}_;jAyTG6M6`0$sI+mGbJRBo z0Mh-{da(FhV|j&%0OF9XNDtxXxUo%?t+{?i+yVQgxFcjB9~c*58)*lUIF~itud}1G z2Zfdx*K0kaFK_;XZSZuf29F$eGV33s2)rTw{HcUq49t-R0<-_2GBcjhJ9Qq5Ce*{@3EPY!Nz_3`*cu{Y^LZT z?hWC+l?Wf;2qd-fbVWGoWc4Bb+6Hfo5Cy#103KwI$e|bT>*x`6XcXN3N^qq|+4phE zVB^Ppd3b@~%66}l6GPqkQAWmE$xY&ThV}TkQ_!m2#7KGhxe5tPBB8<@i zT;@g>uzNXQ#`%m3!tP~!>4d??PX0wQG4>Cuuuh19JdvSUr)OahP{S2`>v0M%3Q=}| z_pxPoZ{W*Fuw4+mZ{$nxwy)z~c-u!QKW=0*kI(@ezre|Q6W@hLP9Xt@d_fcaX1;r@ zzPpTw!KrQtaH$7jSk1ah=)O4b3b`fT6zzp9g2? zbkP-nkS^q1T-3Zb_zdPwbCn6tiC~w|6hGRTIYkfJyj(vot81{44esepAn0!6GXkpP z0998wr2)C9n7ek4&A|ZVy-Q@Zm2r-E$`9(K6-Kq88DFqbX<%eDZ+eE@NIf&3-PPbm zfARB!(i5f_=-?4n<8?i{jM<`+W96@H_Se2SAg?WfHQ-g|1dm(_u1WQV0kkl{h8YML zZe0T(W&lW6xwTVC>Xao3gM=@Q``KsXbw)1p+3!6n2_1zn2PX{Rua>VI-fa%=Co_Q; zBnztqQ4#2KN;^Z>uuO^8Xf>1Mlk^Pr-I;jhpQ(hYk?)9A|%f829`u(+>B zc@dD2!Z>#M8+Yn-X+95+cw;Q`WQj>ODh^T7WSzU1EH>X{9Z)PzP;!c8=Cqum$N*p) zhy1<*-7>SkQIGz3@p!@w&G>?0fG_Zb!H2rW@?LD~%zI^9rv|H$`VjLySHSe@ZuEk( z2##&m#*B&6&oHXihbQqa3#5kxVTSRU6j(s)76)WTlg!9KvaAdO5s<`u?m=@BRg^`w za7bId!lK2Z6CmtK;trZd4GGJ^wJ z1YXy?D~RM0AIqIO7A1Bp1%#9TssP4Tds={-U^SWqh9(#nyE_PCk@I4W*%>-Z0b7v6 zlUbHsNZv{%AZVyZM4rr%2w9mdvYjB5p%{txsR+h`45pF-IDXs1+0%qed^Z4Q#WeCE zeE2og%fRdu4lo2)hk?4J1_Qj%0IZFQlE_3wBrV%av-_@c%Uy%Jy1_l+Oj9;u4I#af zKNvrLu-5?awqcLM1@@qLXbc;B2qcI!Ox>15n}zg*Siuzq`LUrH+jIFrg1`Wf>tA?! zW98HJ8i-NaH+muz1?Jf7Z+^+8PP=}#_|paz5Q407aBf!5V$>Lc>QcJ>4uADiO1V_d zjo~tTiQc`2XTo*QJM|E>_;{Hp5F~z(4a;=cSg5)EtUXYeHCTvAQfxW5b3-$}VHn^W zc&^R7R6Nbvdz`|(D>aRb^#+-5~W);k%%9NEoq0O4j zw;4eP3=~h$nDE97UyLodHGv!_k`E-NjEJWki9JHYV9oL|p%g0xwZ>RwttyN)a>|{o zPC&B6R7%p`&u)3Dkv)`o{zUuCWfGuJlg=gmf|qJe$Z|;jz5fWwG$VMgxafJg59RHe zCkJ^C=>^$qctO@1lr=A)tWs`>izH@TXtuB0Fjsif+tn!K8ck(pZlHnz#RBP0x@$qe zh8xoD|4&H}5Ud=mI+qN_s~ig3yr;@#I2j-i(|&wDpxxfo*9NFKmZ`Ob@$+>Wc?g9Y zT$r*FELVF2rL#39ExxCNY>3v43T?=PZX6WZ3wZ#nwh`Y=A>>Baa_S2V_)`$QzomL8E&%C~qJRl?)sNG+Y$Q8~tSy%9?n;8ptaP|4sh1b+v@K zuqBjk_2+EE4AB9#TT&<6{Yh&PPf~0xhsfHCrE4u8ii8o|BOyBT(#VlT;Z+I&#~i7j zyxF`f7Gwi4t{1hIx z8_+Oak>$=-D^5_B*}>eGRg+rUm-j(8b)vu8sQ-c%Pw3Jgo+TjLH2U!)J|ZgMVi0X8 zQfUnod5?+&vA6dtMV`pS1jW5fG^+X+2yo1374O>|;(d8X=Mb-<0VW^nttes zv$fGyZ*r9LqTb{xfL=Fea@6Vot`Z39$jxr`#CACt&WWrdWG*nZt?Z~pooS*p(YCyH zZTna}NKZG_w!9}Kk93zZxfImWw?A;YF+M5(nf94#DXj2UN#)%R|Ite2tG%fslgih4 z10|_^)iQ9!!?QLI9s=i+eN2pVvu|AMe&nNY0>@)ltiVEdSmu^(y^*u9DpA@DHC_<+ zC*$eHL?{G`18rn)Dfi0RG=&?JxIuekcH6ZfFhQ~A+6;3`!p8IRrt`ywX6*DMYHBlu z?~JZt+I-yT#P~Gy;zgiraeT~o$T#|nW{^D@4+aO8@{dC9+$?W?_zIN@;ww*LhcD$j zcKS+XI>}vXbn-}Zy6FFTDJ`lTzR4?4QhgdNAJW*BIQhElk0t{O-Y>~hx z-}8vVK(_lpCNxyTeW?I31+{J|ol*iCY2#8ej;CQTQ4iO06kNZL6)vqEYRMvZnwQrX zHy+c{g(0^VelLo_4TRUaSRH=}*`2F7!se*9U0*6DG$q0b1dKVcEcS*H!|U+}wcSSX zCzW}j_%J73nb_z1av$xpPNWH>g*=|)G>7X}1R)W~coaz1q%uF3cqmcM$lziQGH zVg3$+0kf2F2t_?wJ-5*4o4nDFtB}xO)heYL8b936ZE>pMA|IcM@5FzKIbHMQ}hv-BdAPq|t?Z3DCYb~`YLc%QP1B}@+7gMEoJZbE9cmWc;s*Q$U zD3qQqDilmu8|!OFK|x43Cl(KwzM~kv-O!A0yh-gfHlFV*JvinM-l7jmAVi~Cq%W}} z8ePY!v3Xk>nCgxr2qTeb*D+oAG3&CEk26sillV9qq5{e1(^nTa$Zu@MSCSpTMa{D! zSY_bE#J3kl<}O?qO|721;?APE%E@{w=$eS?hE9z|4|HDZ1o2XQuSRyETZYa zdd)pD{33)b_APNpc3y7tHAv5kFrP?&FT&W?0F!%o5I!Wj~S;7c(gumyE@W|#ZLn&RyO-;Oyn_xFnU z)#TI<%L_=1ctH*AvBhv`fyxYskeI_O1{V{O3vF-owjXrbscb85#IUv|i*0QxwWZ{B zSh2P{Vy$Ud3g8y(MD~t%3XpF0)<2^{U!x^HlZt+!S6#Tcu12w#2kO#^eJtJ{P2_xfU%U0j5H6#IRkZKMnh}^8 zwPtBb3GHK|f{{mS3L2T3pZb1O0Hd30K4&p-wAov=`P66*-VLEj$h5p!Hf6T?n`X+$ zx~zpblu@hV?c^^2W=t)O&tb>!@}5kw%Q6p}Q8}*eK#NaQ;SNlcnsKFl2Uq@EB_~J) zYyTOwWgDHX!pn(6=vs9N-hdc~Zx0KKleGLiWf1Jw5bd=W!yg~5KF9jamV4@MN z+wyEjwf#{R#2V-jqjW8BG@pQzvy^?PKg1_qhPqd*dL>S=dBixBQi@$ACvZe8!r&-* z$CCwBgEX+LF&?~Q+QQ7D6NZ|!qQa~v#XY|Hg>WIb@^>23P4HBIod@~$LxbiQT16s8 zO-?0W<`;6m3~hu{aEZ90Sh*|v^QQ`%Fw8d$-U*exPs8=eco1nclFG@mv3c|$H?XZl zHj~`sL3fhr#dQz#KY-T<&WAsRTpA?H$zHC0){l{==`%i=O|l6bq9!+))_WpuW>oMD zWWwAW#vgGcGrC>$3LzWlUBcHKDajCUg4WpbQZ>D zgdjw&ON4%-KW>D6Y_b{?t=DETnsAH1XWCm*TjJq|B3}XCB%*mB0GxMlA?U7es9Q)# zHob*#5C@`$i{tq1-n{L^68poRQ?N9! zH_xhxh8VyW2Tl6ow<1LN?wPe?RCO+wj}Yy)$D!VBA7YDA!;jrybDnmL5Aj=JUxj8x zfM!MfwwPoFKOj6*FQ+n-y)MI}~ zJ5gJj5f_yc#kAT5PSpOsC^gE2t+GR;$D^PD7^k)$oij$E+oKzHMj-OeuaO9v*^aBYNG12gWXh+$hp!PYm7fP5 zB9r9Pa_^#+doywm*+BfU=Vs*|H%a=vLvjy^Kgqr3_u0oL+(Al=y*nZIHn-f9=Y(tX zaemE@FvZRER?by!70%5+@S{_Vr@@?g(SqCMxV-E*VPp*ut7At3kF^83^GWt69Tmgs zESaI^BDx-F#j#jc7}_3#)^I#R9Lqh$@j}P7={xDTiq`BUrE#f%svOr;+i@{NQI`wa zk85AWxa6Lh+Z}R??&69;`;xCg+*#H0_MEf7z&Wy5;Kg3Ys}=_0J8@wk-~H}wHHaov z2(=f~R_h%|w(LCE!;wo!Z~5$3(lBa5ado^&K_8cO#+tFO2L^=3H0%$01o4(kw~hX| znQr~5gD5_KKjuXwBdPJ6R(eYu!gExkiCKb0ZN?yI49F8%UV)Zz@7v;j8k=WsSUV%jz|<10qZJtn^e*ClEVBNJ!utlCJ4U}JM1*H}N%RYflw zz2h`ayrLZ45r1LA{ae+Oz(zNfWP8@0Dc~ZBas#A8|0vQmVYUs;_{KMs+1R+PGsh2c z!TCLpnA7M|Nay|^V>uaP$;3QkMn3Z%)5I;y+hW>Q94~5#mIKmXD2$l}z#0cMAf2+1 zag%KEi`44z5Y>M_{#eRFnzH1afdd;tXQuz2h|XfLwU&!YClz&P2*hb&4f-|APr`Gv zToTmvS3p>vc2&&l`6!swsFAQvWufT-hVASm`@m&bP?RO80UvI69wi2zH{GJ@KFJcw ztA;DX$!D)Q$;E~BC^sA%TO1o#sGMLOGK$Rg_NqloVy$;@P`>rfR1+(2d7IXFt-EXal@<&(%N*fqIcPyo zBS4RczE`pLgtuyP<+1aZD~RbA&a@0a=N+FTfR=|hC6&hyjMJ93~DV9@9aY!z|9sL z=PGZ<%6Bv1EODd+!rj~m*xh&nCgfNw5(f(anVI^rvn2ajGvxq{%lb&Jb_i^GG;;0J zlOktt&Mb{2kyVa0pV?#S`fa)JBln~vqE@$%DF=%tjd?);9SxFe99T0*xU_HL)E2KR z#VHIp(4`o3Yhaa}0*7etqj>l=7T7jRTy;?ffQs-qj%J9t+qRp^!s zEW6>=H8^@e)gF)1 zk%>w}A>-Rcpc+}zUkVNn{glHct8}w>x1}a7Am;;dE`zcVfx)G-F zww~I#U4v8UWVszXA5UbqFg@altg`9h07esQ1(&Psk_OA+!ztw!#r1|}Y}>@OdYaYZ zIubh(uU3&W-k3Lavq~%V?f`_%Wh$tm8;hp$$!2=?s%G#j=Lha0rxiQg=pEW775W(M zINY{rg$C&$hZZZ!8;GCugOQ%>!oCZ#^Rx3fowdXFZQ<}=Sc^DI=5T!q6^p7Y%2 zKJR&FpZ$CupfbuMRPtYB8OayD_$8 z)^DMh|6n!A-_dH4zxVs7Cy8Q`s3wV8lK+#HB+vbG){;aq$=9KnuI%D$BD*BJ zG`lRjTz;>}uFS5=c4t>-*JRgb*JZC~zM~55#!N+i?!5)c@CM0`oCyiKr*t2nK&JWq zgA8K$`i%Y}?{YN(BK?XlZ@o|JOn$cu-=jN-@ch;HQi6d3 zaa1Zcu(cT{;|7&~S8*~@c|`d+EyGDH4~Vt>VpHvhO$CM7+i2E+w<|J)8&SDaX3Nor z+m1G9*NCrnMtdV#BRd?x2?g+S0!R>5M$16``JMj!4t@SI9gu71@FoplJwqg_h(k#5=8$H4FE1>yO2jM<38{4f#PE!a+wAI_^ZJ(ea!=RZe3E>y44S$)Ybb=lAF zQY>&k*fzmD7lRbTvZll}-R{N^z8(h@OX^Er!^gRO3fF_W7Nw8NvXno*SrN!C^?Pu# z@BxpQSqOQE6mrVn$Zngc16tsSF(3FyS8?Eb+76tliW}MwoMm@e{WlDp>6y50H*h}A zy284p>FCCN@KYa~)kM(`Qzo-Oa7~N<3Nk*xo2UpZ#c&I_U{PQpI--7M?R`4?68*27 z{pX-5R1MZuM1?w;{Au>|*Ny|8f`ID5ZRTE{M)_difE_LZ4t(za61^hwQJng}NQYaL zg$tKQULW}L9QnCK49cn&aEv;{6*!g!iAo$xg?&^iZiD2{v8z9IBugRxKW&R;dHjzB z%k1*#uq;KA1FS~W+G*GTh6+RZT(@}0e^#E|Gp3SZoO_t zR`U33WWen5=msq2j+50|0=cU+U{pr789o&Q9=J`pNNS>0&hWQ50@O}!GsB1YHL52E zQF6atw;QlL{#!C&c6oFI-hap2n}cG>No~Y67+Ed9{44ifqxG6Ep_V~?W!&_F%^P?V z6_%x9bAc9qJ)#D1MFDdVa8|3ApK`3Myli3x7EAa@^>PurdZnXAD!INAkDE^6Xpl|-$5u|fL>X@yFk^?kHZ$KHVHS;cEGo=t+R>3N~7uR{Q9{* zV5v%vBj5rl7pPhu*Mr*F<37)pqI{d@szitjV z36A5Ww!{7$zkae0`!jmoZrJkpN*Ol0Ji1{gHR9PTDtAbY_`*E%6nWeNH6v>%8YqX_ zDy6&F7WV42ndfitYZSZ=`uc9YZZ}|gTo;qs<1iy;rwpkMl)nc8iyuMc0vp-VI&%4JSg&lvSj&$tioqZ& zS`_vKGp-dwUKoIihLy!*nhtvdwt$8?=Mha(Jqv#&UxVnF4nZl4IP4FxFh(3S08@^o zhbY%Do++-d|J1v-RV!x8ieFa>Ui^nYd;b7~qxA7HM^|9`s`pmZWCdoTY$E zs0cR<@@!izygq`Q2|cSfkVFp9sRf;hE7z3p%V>ZxCjTu)2!dR%~`5LNROkp4}k>fzL0| zcv|K2>{9n4Fu|N<<*bQoe-c*3*o2WmWfR)vH}6ZIxAf)8=h1QIe%KOjq(>1j|zyE1BhK3#S}mgLL0(AR3LoWD4U!BmQR}I zAaFy0b=v6(TSTZrPti1J zzPWT#&^66SVkMe?FAJD-O6U;EUIxm}GE2uFU`|jQTK++SmN^&k)CbbXXzOBy<_)+N zv!NMVxK!04Edgxc8bayqS}p=6CVrT7p+=Aysc8S4bS(rKOof$@aqsSO?T#7xoEPYA z7!!rZxBBC@K2=N}X!(5_W}F3bY7S8%i29f%fSsu_RTXt(c!ci*0wJq+{q=wo=k37MGHC zR8i8x1X^t3$Vh3uvAvOMsaD5$Gj_0e^2}Lbt2ckmf1%KdV{Aie#~P{K_PK=A=BYbl z+nq>lS((&!(GlsLS6MB%9XPzD#nEnWon2m_IUM$u;kfshb-M;(D(2~Ti&;%h9~aFu z%p-e(+Cj1>goy?sh9wofB?X;subAM}Y&hmzuci-SMdw_)DNxvnfyX3QT|#YY${~tlb$XILyc$-KCMU92??vgLUP)bJ z0m27{{iQ?qBD0X85K5y`v?(I_=NYusSaIO57`2B8(440;O& z!tAU5K?!Y8abrp<1ty2p%ClB|%b5!03j@|#s>+sMRqppUcb4AttnV2n5{E5~RgN*J z5Y<@|7oj~3?hf#!iQfy-ps@uLd%8uT=poP}fa@sn2hya3BxDv!Dl<0t`cw|7`OFEF zsD-~8FN59_v&w9;1*$q!GYt4xi2RwCs@v{ucalHHmgUb+kH>s>u1HZEU5sDQ&1e^X zD8H;aEMkR&gU8^=h~tiv0)JBBFQ(}-Nw;1fLWRE*pZt`QP98o5XS+vQYfN{S_f$>> z{2INTP6nIq5t%2#?NCp?T%uW^X=)#4+U9HEUMcmCG!=W~J90l*VUpPm>Vw zFt(=93q1`l7xqhm@eZkI6BCS7WY^Amo0}0x+e5{Mf)C2xC_tO|8#gpW19Q&Cx0D*! z6+)GYE3FKDvqsrO*rad?<=tUmhyAX@AB^A-FY&~|Fd8!(iU1rA-=hNy^hbt?&kjdz zA{D%&A}|jmJ~s`#m%JTR5)5;CtupK|&_&qxhrSKA1L4|ysM&B$*zo+}u#jPfZ0wit z;rn$3QL)o|euMUWvP{&7txR#!Fa+DVh$KknAEt1H8#4ezOlB=N47>+O;*H`HfQ8lh zsP|ZO0;{JwJuT)x>JJ9gm_7d#0TB3r@vn5Nj)0PG69x7Rzo@;-3suQrkV*{%a#&l9 zYL2J{6jU}0pqQLKQ9!ZoEu6#QoQ>hgsSGWsvMIE7BlE;5wJEeIb!NKK`?dWgL((s% zIHCa4%g=PbRctFe+1R5)f0Z|7L(t-nIt0Wd`z4gQ3h-k=7;V`S#p$@g!i)$~ieNbv z*W5O(HT_P+70z$Sm%!M>A7A*rtxjOar{QIk)$!E{Ep9sT`i!< z97+N+A`}@JtdgN7eVp&m4PUyrOuZIyM(1umNPD9Pfg;Esue+iJN*4NmeEoU22st) zn-b4#&3u9Y@AtMlSwXMg&Y_XR8pfDJ+i){gVZiJO z++YTbtcy-12Fy%qz}R{Y6-{cuFxFf&U~o^h03J32hM5*+1Ewg0OR|1*GXiM_jHYZr zW*K2}o@qgp4VXC_-%@H^cdBdS!GJ-ch!`+4ZonKwe@0(4L}q!JD&zTR7}aXgfQi6D z+M3|1G+^R$mGX9nkH`!dI^u+FU+B+ZI~dFYupPgT?V2_KwYMnUo!;^r)j+A-3m*-X z2{TY)zv0F-01*S_Fmu6e=firW1?!` z?TM&bJs(kZxwmbiDmt>dw&fD{N`KUF%T$u~xSdRKD;Mq51HLRE?<()h)Pt@$&09U} zP8v}4;Nga3VQG2UIsGpX!BamEA~*v1aERby<3Il*IF4x1MR08S#{Wx2a0KwbUIa%_ zj#>oAmL3KX9NV5-1jk4J6GU+A>qtegH_$-@A72*1_s_i)RvXn{SiXq~t@Bl4Kq@ybw_q1Y*D_n$%v$3dp`6U02oOcU0^K^W4)%@J+ zoy~|KV;QX}>57+jY4y75E`QgUBu!s|okBwoR!Mra0`n=E(Z}M``T(NdUG@VOduF)eA7E+ANWG|ZJ8=A2Rn=l4fkkJGSQ!`pQR34BS!bMzsl8^^+ z&txYi--q}I^ZyY4AW_k$%ikCiG!OF9GBm4?>9tqBtc&JoL0-XHIw`pFl@J>tD@caz zJO;eY2mB^gfa(l7g~rG>q7*HWueYct56JLv4*wp2l{3lJ1JLxl-LoIkX;C zZWWObjQv3{0?}=h@^nE8Qs;Q$0H?Jq_ToFYs1%^CkwngVMh?TOy6veUiw$#*L5AK` zyhIcfaR%-kHAbhPMFS!mz!>(~{ot`??Alx*-BPh4tfawvQs8DM2giDAtrJwUdQEdA>4tg3!0kiJX}xkl?pz9>X<>PGI^bQ(0svx51>A# zFF5c9Y~>(WnR~8gtO`~NAxPF_!GSL1GF^Bxyg>{_GP- z+CCxl9zxuPm}dfMTCiUPZ9EDhl@(@g2J3@@5JaqESd9eIv>-gC{n)`hG#o0&<& zx*mWD5r(kYvdeXp!|Dt5fJo#t8p(o)lQdnKwp2jqM0tP0re=hygwRCxJgO{vjuzbq z7K-kGUqiRzH=-LT0)40Gjvefs6Wu`x7`idBi-GRRDs)GvI-&c~Wpuwki(3I}qx=O; zqo_Tpx;;tH7H~`j7*Pa~TN2Ol1ryJFf%LeX3|_!6Dl&%VO}`S7wpHIhew6HaZ|E## z&$_4@Ff=?@>^_B$w;i4kr2STllRr7u+s zf-a*JH1j}~f=N`tB5)a7btX|VIr%2^VLq5@V0%W3^HF_{8s}q$&Bv1=)#!KgmSQo3T2xzry4u`uN$KF$ zH?a*QU6kP^Zn29g9gRBfU|l!Z0#vf_pA%bv55N}?RCS-)|Su~oLDKok%NyEe3Z#Xm29Sz zxAAB<7N(8q`Y2v&;Tcz$W6k*FO&a7n4NtZPexYkEQqMm<`Tpj$Sd${V<}>nOtNa!*1Q;gk~0<@}BweB;kTYy&h9 zYJJ22)D|D9Whf8JND(24wmS?f8EHQKZ|#mAq|te@j0*@T90ey)0gP)u-}Z5xgK&=C zQ=}yavCQj8#V>s}9hb^XpTTXVaXqE|xMtdpi)&3!j^o0#p`XIZieY#MT8C%5tz?w) zmAOq(y3p$8{(dh(((1)xebx^aH^^E z$cH%Tz1R?Oz}eKI4e=cvhj@c`ZbQ`L&=z+VZ}whnh>sr3_bu8GztE8vZ}HA;h}@#F z*t7T+@5P4rNa*cF8{+3X^5WaPa~q=OIV|ohzQcR5As!DE-foDgIDDtSX{SZ=WHyuV z6n`{(PbCy;mMi9@q=2mb3EKgJ+ zVW0PCNT8xiQ>o{L1kIUui{icBtRVqwb@N2R`}|!)0z-L%1Xjt{6!k?#!X4hDA%XFZ z1tXzoCcfXBH6--S8wu0?t|0+g1&V|ZbpZQ{F$R$!t5Bi_xjJ1H7`qE?E%Qd`aNEjcYYt zaIKgrgG0B?waO=NPxv$csdA(mQu^6Pv7s5;I;h;Ko9biA#44!^(GL`p28iL2y!pfZ zUG;7$4MC}b?Kkw6hVz*R>tfbkkM3gWkq!Aa+x!jMu#a8ou zl}ea=DiV*lk8Dxz*#I#q?Z{z&Kggl)h_WXn*o|#v+*F2wgLdRF7EidR40(<131>%v zaHQhkp+Go}_6^PWq^S^CNv-mVGv942$cU!oCXznZwW4aBp=z=fRqN=H%02Z6f+LP? zT{U&@wF4o!)gZzisahyYD^i4{hx3T+8&vm@6EK;y!P=iSa6Vt{#k`aD`tWXlgPVD% z1xcu@RFkd69~ALJIufbw90i7NLeu4wdlMFFq1Lp%Yq6#)D%%7EHc()}%m(5M}(`Ka4vQX7{5|B1@o`OuM_@wqT8fp zvKU@PDubeEH627LrP9#A9z@=u3ht`+lQ6*c{q;T}3_eZu&|B}9xLp2xCWbTDwr5cG zqcRvRP0LtB%?0*N{I58(R$j#yL~mPqgdsZ!{3k>%4s}D3{S*se0I)V1U?R|&tw)pR zJui=>0wZs4{%jg#XLrF{ww&Lf3nW*O1jTPyJl!744;;K+^|s(4pLt(#hBq{0-(Qll zYs;9Tg=vEACWU!qBWgZ#zqRAEvC-fBmcFUSDX&8B&F1AYB7(zEyuWXYVz|F5oVCkQ z@krAJkZnlcFtS}+Alpq2nlY}L^oYg<#wEdcAz{b~kuo@9L?eh?xyLc3!o^&nWqw!W zV(b$a7FLm_a)||(dZZevrs9SfX_>3y^t8^Xr9PFoYO9aNxC)kh4X4+NWK3O!?e=8( z1X}{trX0~cNvZm67uz-APNocVcSUy{n-YO*aA%Nfv}{p%`~3VuJA0TY;)7uD90vaR z`3tv<1)7lWK)H@FJ@j^d7`vo|F{aK{VeGQD7?Wj*szl3qGvEARy`lswZJa7tuWAcx zr(#nH`-^H$>E&wg+r%JDBM47t^6UJGJv}FKO@zzem9!u$vv+VMKUA2ijq(>_agOCg zl@(YKx<|FFEGMe0E@po$ugu0dF{4sZ3!xwiHkc$r>)%!>B?Hh>034|pbd9d#)T-aU z1n>_mz>LG_9vOwcnr;;NG!#_UV@uJ?T36Yd&D{lYPwCXylLdnxf_xIQus8phOLEk9 zzz%M6$NfV1BYeX>Jo6Cvv3C>r+)CjB+UI`E;WPoS<`2)-frP&n$@ln3YglW-;mO3JFi1a0tcpapT4w9vWBef>TWi>2TP;$fQj2%fifi*+D z5YT;MbV?$w8J&)jQEUTp zxS#ky~$1ir+c zEbCW71r9EIhZHe^uP^hCQej&4+K~%WWy^<4n8w!UBTR2&xxtWI(mkr`Ap8%(Igbr1 zlY!RFFcz&G&M(hr5I+@$avX1H##cVC^1gpC28Brdg>Yw3kCZkbx6wj#W8U1)21Nhq z_7_Vm1l^+n_?%~S)k)0t?z6j|PH9>OY@@eyrvk?8f-}0F4p~DJiADTnLuIg#gEywT zPor35Jzl$LR2CT5_v7=-q0gHiwqo*ob9w*pUAEn>stMJEV?*8C4)XJIfH}zN54!Nv zx;!UpU&x zf6>kY|K*qRB=DDG)=aZED~{E^sX(yjP%t$0RBdPp2sWH+gDJ<1)02G#jAGmzxAJ`x zDBlM?)r+_zzI+*uaKgk5b?1k-;tym@x1Nc^K=H5Yo4b*kI%b(@jBWi292Hr`6lKt$ z0{UerIEF#d51y`trx|NlO;cT$1o8Yve`>lbJjP}37t3R^tk(KivnM>p#MfVv$7E@$ z@Yq0jjA0!d;D=6Sd8hDL90}t)qw<(6krW=Qvo#=a6`sPmd}PA2yIw)=6IG-Kd!tIy zh*W)4{0d)dFhC}uz~@&t4!) zMzVK8CBhf+H>~Ir!xhtK_Z?$<9Mkc*nzdiE8V>~d82~?=_=s<)3BOF)cLuqiQj+ImkH{EnGR}|i+tX#BVO|BWZ~-H5 zUL5~U2iiDZ8^ugTT9r1Pfv;nHFB(`yi(shr}AwRXq zN+jHKN$Z#rLM-NodX5#0<+F9GcX^%8)@jnE51g;BqotIdRafGZ_jo(zi!pmpLdk|e zzOozp3qhSP#0WGyj^RK97i@~UWs%HStT#fwj~7a&P@h$HwMG^fp()TyK6~q93mV}z zAD*q6o+QHqSEEk`@DWOtx`m&+<#e0v(s1$vAB={Vj7Wt<+Yyx-h+TP>m0k z!3`+GvH%@X39-}Z122&&)`^!ZXTxiuRv>td@{9Otm_3SOJUJO;6R09gL-b=l;HbGu zDTt+6>DTf9HFP3_fMxOFND_b{EFH)yV~|4Z(}ouN_@MV;dCXd~723(DD=KFh8pjUg zmb}&%fbis$PmbbH!9mq(z3QQ&0W>U5B+K}MX8Gzb$iUWdIO4a`j5?$16%q;f5+xBT zzyg72djcaR1YjK6a}xY~`YXY_`}x=je2m7Qdfu@2dK;hQ7mq{y!jkI{v>r4v-bc;Ks8U2ob}}2Dh>s(}Ahr z6hc!=X>1T;lM9C;;d% z9@(HPd;FX}fECyk)&)M+V}M0#_*8hFGY+@8#E)2rOMFfNzn}HyEbpVWh#VAFYP5dN zAGhcV5}$nSSvcuVVnt4oBL)u^xKs~lQluVCx%6OyAv?vX%JcrBLtvgaS3^|!5V<-) zEfyc?lkzqgI@R(vJ_=F}Pevj<;C)(TopHqlu+>+*fr^r9LA)XiS5b2JtNyMLs)h&w zsHrZb5{v43;99Z$6u0Z=Qw8d4-nQ-Y;{gr5)HYzFUJIn&%L(NwZFe2T$gvJ2(|kAY zBF53`)k|(ynV^>fcwppovTNs`NB&Cj6tWrX8Qk;_w&G^n8YAtE5w<<{Ym$@R% z@?mIV0C!uZ=tghEq$ptI!o+fO1^e-~Y#>WLPU9l+B%_ZUb zk}-VMS06Y}mSSYk!w@&DHPnL~5NPnFd;u@#HLSfTT88ls(X#?C_16c)?q%$W#m{gp zi!+bMwWJskjp&t&`u+Gkuu@uDQs)J-jR4mY=9KY$rVR8N$}KMdhe+3#Fezh6KCoqI zX%16Dntu!)XH|K8z4YuZ*ocI3DTcL_gCx{1+=6Hv?m>LwtHJsJOkDhX)d~0vG)QSf z?#|%$a9LnMpqY4tex

#HS@va*5V6Lm5~DspAi%yG$x=tkg5L3UN_MUE)NwQ&NkT zv7RIHf7RR_C5J*is>!-amuKp_JTs!JGs9duT2k*_1N3ko)1ao{Xp#^KEG}{hfhjd9 zK?IdqNf0uyI0ltQE@ZB7xUbViX~~+6f{7ALg_OT@mA_*OS=O?mVC6eT>=8d#m)_C5 z)PPgs7t3CN)BCx$^p0m1y>msf9#WJ^^Sy@bdQn$bmSr{kbYsV#oVSB=OZ@{VxWvi} za_o*)U1IqK?g4xx_W(Zn(T{$NhQS}lJ%E&4ZG_xZLCA6cO(Q+qX*8iQ5{z9!q~)Kf z@J<{(8=A3gOSUH%(JK_=eAog6=1@g4P|ri$zBwXah8W(*Rqy)iZQhv;iMH8d59uA=iw%huRppRg zP@_@Ud6qu@y>v*LcH~2Pr*~#U(rCfr65g%eiw%jX9Bqbl=G;T-I7@%;o!OA+_b>J= zz1MrOAu%_kU^lF+w0^9Y=nf z!(=08xM8tJeuwvBBiB#`NX9Lub|V+(6i6tHoc>Gak$B3K%2gBe-nvz<|N4>RR?@K#WL#FS)}nkK6N`L=k;q)PE%3yDdUp{%$7h0u13U$wOv zfwbjX)g>B5Avo5&FIuMItv7VaeVBiEYnwx1;VnJ(NEc3Ixt1%~;lu&Jlq{p@&Wsop z5%<_uQ>vZd=nu%~u--vG0X{j&C|$2BucNqh-{}y4P@_*O-F1_Q`E5xk2*J@ZDH6GS zVg9i9Fdz(}faMj5y)dCi9w~PNL|uvV>Ej{0^23chGuNd)*fhdanGg; z=jyeGjww^~7tUi2fRUrxV+G+HHV_ttvy_w$qEw{a5esKkUaHGNi%?V{1|9>9n;l{! zN3~f9N{mbsD7H1@uuO)kW}K%*@tNpUF?6g> zRZIYzKhbV?D2!;ygB=#k7KS3%!@8}S%L&xO*of!rvNTr~q=z3?V*Bv_KZz|4>qv-g zCdMpDY)8C0yS*8q`1v8Wuk_AavdLz{N43Z{tcXY{YA{us#g6?2dSi^QaZrmWh;UmU zoFA^{L7}Zz=jU7#ZnR>TRXRUGxLN8)+cnXHZA|VU&x*p$^)jN}eqlk?)H5Ko1xIRI zGY;4&QCI8cC-&;uS+!MN>b2jT-i84l{W2p>F!PBm(AZA4a&5R#`Lq> zA3Ge1`4RWR=EEhadNf=OE_pQEQ?VdPdTC#>Bv`cJxFiT=tyN@XnXjM9p$#2>vOve2 zR+Ll-o6ou=HF0nL8L=&_h=45f;~Sx{-CXl8UO<=Ho}p%QMtb0lSxz7R;uU-Opxwbd z+a2jh_k8}RCphA4n1BsSa8!y^Q&0`k#50e6Ehx5Rq>Xu7mf)xwI%OEFB!SXb%6fSd zYxEQo%?u0q@@aj&CTscJ;uUvLTD(iyb8b^{lS5%^^)zm|IUl4DVrW6lhLE2fle z@fPRU_PEuaY_sjLvTR4PB);7{O1C{$y>{f=9+fs9u5FL8^)F})rQ;s*_pubv{7mt5 z(I1>1&X#Yf1EfbMwdeaU1WLDzB(7J6!n_(P3i?Y*dBosd&|fUsfP~QM;GLakKwh5_ z!C}lDF3i+U9Uc&+svsB5TbmI`(>c16JY^wi(Svu?7si(PO=Dq)3ay_30|74^Sat(U z7*jy%@v}p*&7m*_p(|{Oe+X}6InZI@%Hc$Rjp%1a-+~gV5*9nW4-*#UFy;J&1^5{cxxPAu6P3<7{Zgmn@f1*S(dIJeQD#rzD@+!Y@SYIt1j4NrkaB z(*R&g?p#=P3mAbRTd{bNr0G=Q7h)NxA;66dMw;@dhj|W>2tYG<4iDr~g;;FDJd_lc zfOdG>St`2HXmFnVy~UApgNkX*^L92S8n6gc+%g4?je9hIuxWIrEAAR?Dp)Q-#=Qp% zaVd8L>}cqU73ByJE(pUDixcuOlrIX`vQ?mtT}aoQlyEp;!UJ-{LD=db*lE$a0-+S3 zmdzecm$x;=IS3%^<980;G%sgDo+oL}X3~4y<~`b=b;&y&^#0aXXVM-I@Vj7E&iX}u zai=vIpfQ>D;PFzd7c+LYJA5YA)uC~*P7-smg$i@B`aoM<@&-|`#FPDPTR=dU>`Ak< zr^A)y9hiH0u4)BH>2%44IER&2q_*`c%f~|(qeA%Aa^O!URdl_b9WuYe!Yh28{y!ITT=tR zmB*;V$CaMOV0npul`3%1vaNtWFDd9r$eyfhkH=TdAVl zO$c03w&-e6qD}x*qOFS3(C0mF_a1G`s)*7t?`s`1)i2eAM)>$$P?S`mc9HMu6d(f@ z6T0f8D0et~rYO^(2#v>TMak70Zt?>8Po#=+Hw9b(Uc|g9%7fL45|2VdQeUoPTf+${ z1Sv~}64AH+$MM_n9H zJsh1rK!XY22GNYUFKu1f(2V0SeW0?`8HhYnp$~-3nt-%bSRX8!j$__IV&TV?d$y3s zX^QR0q_P?b>Ix=ixCWO1kBMw0H-qW%z4A|tRp8{;FiR$AfyW%;5ks{kyyWIFrn$r(k_mpgS4w4Hw1Q~WGL7U9NTQ@)U4k)R-?0$35%nd z147OERU3#Ru2rBOC<@e#{%T?gM!~=q61gR|ZBWG_pcZI3T*LjZ6sQ_lgIbFWg2SEz z+$K;}#+g8Ea%x?mwn%dkwyxwTY+G&KlIqy(o!LlRMBrpA9Z^Cj0<|Qbx0G6INg-45 z90h73o;#b!z;{A?odoK*17HHRGKGwrs2OVpOH5-f>CuQlZMq0R?2guCnAXI!Y|K;$ z2R7yU+$HIe8^k+(C~ajL;VsHEf*rk(L_<`9tuk#77rffl`AnC%!e>}=k2XuLH=KA; zjF>Mk3%G-Uu1&y6z%LkOgocEF6xrKCsRs4%yhVhqe zN|2FVN6(F2M+%1G2^ZB}18``B$ihcHh=7enMa-f>r=0rvW5B7M4lN2C>VLtj$f$~5 zmsHA-vuQxJnu!9!Ec5Dp1zzQr(?$#ma(ZTkv|G|q+SyYYIF55VV1yndw5wdS|o!Etf_LL%GBnnMyJ1|}I+3&9?Fx6NyzH4=LboCAW;9Zu4 zYc_u%<4y`3kvABZ=KpJ6y_d#hz31$%m)j}?HU1av+qdOE}dl#?apOL^RCwP8_@ zT!+W;zUkMP^TXSc5)@jY%@bc#i$|KwXRj=*dEvDJ-naPJ%%Y(LF3uSXu$|HM@|99G zk}_FV&w+HUU(u`)37iRtU9HOwG~z}x=xCrvCdtNPVVZPBp(SiP`JP7<;N0eLT4{C_ zy2C18WDe9d(>XAA35yO$#|_ojdtsdkN)j51>s1nl@As&_N94oSiWXOi1Olmj@7WnEwE~opFFM4x1h?gJxv@Z!+5@ju^&!JQq zX22)ZHKu)7?SmcONTSR&1l_voVCqc;N90sn@>Q#Ojq5{(ol z?qcumeiaJ3YjOtdm{d?D#tYGP1cdgyxQ2SMf(264Cyc5niKW@%S0FaZFix4k+ad&K zwbN3*)`SCTIuSrtmZ`tgo@|q^RTYX$9f-@lqcmTu>NUyNI+!In6RJ3%H0C(-LxoKt zUu%UVD?+QB(p|^+U&M3;5)MQkFpqPdLVp%ph<%1qk5c?{Z8<4We!Zxjf>Z z^r=B80S zkq_&_8G^wg#*{`~w`?)31~~6jEVa*orBACUq(t)keYD0`&FPAcnDmnt+K(JE$NDKplHBLM4W7=2fNQK2n381CnBJ1z) zvHi2MzJ`9NqN2gkba{f=DHDepR}XbM?m+oM@_9)e2x6mfj~@2dmO2g>Y$&0QVN2-c zXhw>o+0cydyi+S9sh5h;gMq~CCzk2I@{}etVRitRD4*SYl28qmBfWxdz5^QMUor8c z_$D${u{)7$@~#si!Qx9H>1eY*XJV`!F)101s1se(h9u>fOIvR(r&*_1RjoHd*iGrx zt-L*21n}$?XY;Jgo(%d(jsYsrOmUby9DJ*P==Gg$?^~cB9EIhRoFq`miG`e4#|bVm zPmkj2tiH8GExm_U%uDo&%3# z-jpRu;>hQ4{w4)q%0_=bIpXb%u3v6Lr zcKG)YPc@3E#tFElo1UvP&O|!+_W86sz4j4!l!w_;J}8W1o_jv&58KD^Fd}ia{4w${ zTLza^dyUdEV_(K{KJKf1+!k=tkiT*`=hNuXSis>yOe^Em2L4^c@7Kp>!=ubj=)XL z2;#=1lsILFHs_+a=N@OhHHLj+;4~n;(kLK*}kfZ;oUz+e(Ac z;$X>O*bD1q0xiS&@zOD)ppdUJ7^a6Xk)Ge4Jnz9wmj=UNq=;Jm=12x}Nog>;Qf`BR z@Mq0W7|!{je^=6QTs{up&{no@j->m`OWkXNO@d4IB2GN9brMgmr5+GNhIhW+g|jjA zJSgU~L;euO^P!GFKz8tJ6#<1ubgFO)M_W=;&c2a;opN@WufefPX~v=eWp7`fEz{&Z z98t~3IFPRpdg<0d3cZj6d%0u_%ghufYka`!k6%+p@!Nj`I&ApDhzhVD*$6mq?omOGqN{Itf+e~vkHivS;C}hRT8rl(~g%}blNp*sP)Im~h@;=|M>Q=)jAjqiHw13*# zI0T46i7<+3UZ}wU)#o8s#9I6U*eOdYHf0JXHXGq)v+;t>#tzwRuu!U-jgLZKmN7i; zqus5}kDKOiueCMJK_GobAdxysj`~D_GDz@^g@h|e(Dj08Av_@Vsm!6%%2+e@_eG@@ zjYn0R3F;GvX#bBC<0nBvw{8z z?G>60C*m_}#`0S+8|04GccpV1>;M=LuwVpku4_IPubb^~Bye9`f?Ml{Ct8h;&!g2s zsGEgAZBEl9z|B<_!Yvkpz|FN2+#%elF`#hM4TF;wzBv-OuPni>+x-%_sg12-NgWO! zbd5kpqro6c?F5Bv2=62o#F0Su`VwTiPLM#xUSwsKI1@Xejyt9o>ZzSTqM$Dm5ZyaS zUlt<>{)#Hi%1DRHf}0(rk}TLo**TYm4<0|xf}RrC>Ss}zB4ZA;Wy}F%Od6IJ*c?zD z1vXT(f-7YVTGh;^prWJ$&4H6kxZNdq;tX&Fr0_dN%ICBuQrWnxxjV?45(vHm1SZohMF@$C%+z>+V2gI|n$B?lUHPrG7<6#K_hHZocmnH9jTad{LsKU=$`M51UJY^2~ zVJV$1-0#QN@{zUk2W7v#Q2{FL*EiycLH@zF`9s+lF7Q8(XX3bNXFm>Kya6X5O4UUd?@ZRZdU#BMxavA$96W$ZW3%AS10g2=LVM2>p(TOjcln+ZkoX3Z6eULtsjAC{n(BJ`%{sppf! zS5H0lw9}sYw9}tHB4@8gmVgISvce_{T)~4G8oSc+*(34ZthR zI+&@94d8|SnT0aRFi$5R<@a_)4muq-dU$R|5AH8*uI$T~UNF?3VKuqlkB+#KB+pWv zKaB|GddoWe0iUnMpMVt-Yv6WbDEJM;PI#t{&t>fFDq-iTCF}%@5NnPpED`D0*U70L z7{>+Y@dOWuypi*$_3*J*K4La?g*d{?72*gmS6qY5JXw{Vq-fMNwUxlcDT2m{Pb(gI zXISvqqjj_mR&|#uHD{QCxT)$ajQf)r(XOEJlJKdqvoshKJxA zV5AT<*j;Qaa}sX-j$;mKhd#OT70n(|n`x083op11W19KlD)dm}>C#`SLAtU~>M@lg2=0wfw{w9Omjb*-Z}GrZFJQhJEz1 zbj5GQ9oIv-NSD|?0P{f#N{IQg)~+Y0`tbcaH8ioUq;f(0?5-DsU4Uz-9H?CtbojJB zf5H}|r}XBh=TEKo-f{wEOuhH)u9twj&?qD!sF8*T&)veEH7b49LHO`^EP6F^+o0iu z1}#M)!8YtG8WNp_;}y+_T{E*ZJF`MgNY<9ii8H!h0>Ep4ts4wUc?kAI_ZSF}7R6H$ zx^N5>KqI8snk*=$6kDR`jG?xx9JaePpr^42gF#F{lVKuGR_9AZ1|$KB)%EW4^1nV0 zHO4d|Oyx!K;Nl;nI-~2wD|>GN&ba^%5x{Smyb`f0+dYDDCX=rM8bnwz^L@;i;DYF0 zv`WFkAOsn^oAL{Is`rV{wGvvKk$*;Q=#%-w!qLF5_+0&bhV~5CRlCJ0g~iP!83z1~ zl~Zfm*&4^82i7UEb#rimYz7b+J9r+P{&-?C$pqKY zc`!nr3e-zVe(UW|OQ_}K0=3`>%Fx|EE465>Y!b=M;pf6J@SV_&(YM%5MnlNK5<$RP zR+?N4u3D=oRs#o{7rI_04RFQrcc63xAk6ArDSJtiPs>juWBkr7C!F0S%(Y%INBM+7kHewDZ5=AEVX2)0SkK33 zxhtVThfvfq5=5Zab4f{)aX^Ss^fFqgXsLiZk!HE3lgGr^^$7(iLY&;U_<&4a=t8E= zbsLv)CEz1pL6iaK7|KvjzC>by@fbi7XHfYhOtp6urT{AhnE6Q#(AE+_8nP@4FzN=O zMS~S+tapo5!svF{DhR@e&;(K#{sT3!cWn&XY(vI$(P zX7`!9*jup-5RGRUa4lj3&0`VJyu(6FkF{@4FPBdnuF zz)zBx*?K0dtWUMXtxiSgijgb)jEo?B^^9kpdDgR@z3Ms7ecsv6f58h!8~HE((u-dF zlGVTb(qH-2m%aQI=lt3$U-jx=|Bc^V11y`OX;!R3zb!~I(=@+@$FbyWCL(7z7K$JN zkpfa8!nM^rauUD^w4u=-sXqB{Xw;&}Btf{laE20b%d)NLHrg*^-olm3C5?!qNLrv< z#T;Fer0}+C>f(rKJRsk)7l}tTZ|rU6`0s-ASN7%;PY9Z zz4_VUInyVT&?@=a7YsppFitunt=AD@$rwVNLJSMU{6VN2EZKiFY@L%k$w04pV<;^N z_R00&R3G*hAGYb0-^8%3-K3Rp;40hrXi#ntVjS;yD#(g*e%w1S$?+TLpw*!_G1kJU zY*-cf4C8@-2|`_O9LVxP@h53u|2hn&5ed40eNaNSqFvCSXiB zrMHzsK0lLkh@#awj)9~iYv`Lx0AtMxp5L~ll5D% zi)}mTH0;gB$N44JW6OjS2&2N@Ft<#0kXIxS?02Nt?68A5MOe$MB&ND4bFqO^g?>{< zPw}4|2%8z^r;0})1~klGK@u?1*Z2mpz*JY-y$1ysz~ixu?aM2I$4}`)p_TAVT`wE}iZDI7LKI={Wi$*+{H!FUGCBD-WsUz=2+-e|9GH$ST?-THO;+bpQ za!VaNnZ7&u1sD0~svO2Na2jX%7f;S>LaHa>3l6kRf+pGyD|Brqf!)HJ!{V=meuds< zL2rZ*Zi9Gri48qXNX-{Z2)xDbQf_p7e$hd*so};?dM7ct3e8G#)d6D1mivgVfWF3E z{35LQwVM%kAgE<;(%nxFW2=5+}AOiBYa2$E|U_!NY?lp|R%MTRucD$%}1 zz_A3tZ!sdS6dIjCqJ5oT$`XKlo46>QMum74A`a~&+TEp5wM75h5&|bYxF_?FXkQpl zxluv#DW7#9Y|0t&ua;=g8A=Dhjf7Y3B~~O`IR=%A?sIUf>9uv9GGw|aCq!mQX^$|+dy=gy&B`4yMBRZfPRE7g` zDYf&xoi{lldOgt9WqT_yNfuqMNT8ew5fTe7a|==b!MxCU88edxxfSOqrqqQ&@5jBP+t@Or+*~$Xm5CnH*7RVjoO~(SdS(`FDZ=HVpZ0nF3nucjXd)?j0!|#g(I1#1`n947E=&2?a zF`4;^^4W2<(R+QCtUyp83#!8I8Me#~0zxRd45rBh=qN1T8JUD!4N?idO_pML*$hw( z>(?=aKSEhmSQ^>vaNV!OL8gkKMlqKHp@`sM(zse1cxp18(U!7XQ=Ya_dF-zavju^- z-hEnvz{eF3IPQQd0#%9v1wdR3C|AOm7n62WH2l-146B{@;oL=#wASx?q(gC!-|`>W{$>cYPK&gCtu)Dwon` z_*uJl?eG5X@4n_Wulc>-`~BblgFnR2YhU}?b?ess(I5ZupZv+6{?GsQXXpO;U-0KI z|MD;Y>UFPs-T(gIfBo0%`SUk_^EZF{cYpVH=bd-{`4?Q+%r43{WMkRJY*V&5+melE zTeEH1_H0MCGuxG2oK0kxWS3@_WtV4HWLIWaWxKPhvumXZEh_-Px_#d$PaJ{vq3!y*GPbc3XCP z_K(>e+55BU>;u^cvkzq-&OVZTH2YY#Kl^z0PuVB3PiCLWKAn9go5?<#eJ=Za_J!=u z?2Fl#vIE(dv%9jdWM9p`mff9wJ)6bvH?n`u?#b@O@4w*pU$bxG_h9y|?A!ADo$S8s ze*FGh_V3xD?7P|b@caGj2iXs^AK~}M_&uEc1iwGc{v&%pet(udm_3BwX6>TdhT2$d zV{KDyb8QQL$7@?_+iKhKy92*FYrF7!ac!b@iTz$$yR3FOey^xqS-YyXyLL5xuc=*I zyRP}FJ9bZZIUjFd!2;RC=No%^k~E2_AoR^t z+!wCR2AI}s*E$=TvDF`|*13hPVqY+=UD{of;`a@QEQf=lhoC@BozsOL$LeNu6yT|e zLx$%N#^_OJc(!M#KfiEj0RNU?ligDMqi?aP`CRG&_A3ng5!7V%9=8DA zAR`4b4Jng7>c8(ts+=76IjKm+xM~)Io9UJq95dGNr4Rw$64auV<0OybdcH-fnB}-J z)+X^lYPO4y87x=xVI-H0o+G{l%*z#@orWXh8t*p5JPAm+%n;K<#4ud{MBKd8 zFr$KM5}CW6YIR(aYPF<(Tz!e8SgkxRCRVLn#&oLXAe{R0^M{U=75E7St=T=aj36JV zseBsm#^&HUI=s03_awm}C5loeNQ-J|(<8ee0NK`>>^Ay9hMsnDXvgJadTSSN?bKT* z%0u5`$Z3b(c`TjJFY(59y|M1Re2H-M3~z4ZO^oKCu9t8*Z!2&0U}rgAQj8#cHZO89|B6063-u6-r(BhPXVNEQ;cYNw%%SGwETSuEk7xv z#Yjc;s{5kQplu}nBBA9pagWKDLp&ecs77p#-KHTT)0Bw9qWrs#)4xkOT4r&!>` zyxXH2tHKUaS;+maJRXNo6c|CVVVH9WjQ9IMO<)|F-#}#_p%U(MF+-Rc8RV0s#==J^ zQ1AC4J>Ku$H*d(5Mfm@8H+0bX7R9QXt`GYtY`VTP-%%*oBEn^H^;-`06FE6@^Pt}x z;!Rnx{-)nl2`_7~|H`|CDf=YR@h|fDB23vQe6TiU_s(~)+;}ar*`{nh&~O6CX#79Q z?>Xk<(+;A|$2ZC#I?F_r#6Z{L=ppz%+_(oNg0%?hpu4ldd}aMOu?p^?oq!wC+Y}9p zB!#6{Qdj~9k+VutMJ+sf93pu@k*2O2F*p8;j)AYM+xWE>45UJ%BvBVb5o6#zGVrgk zU#wAv1P)oa#7$@vy?@?H7$Z!sl+=#9luXm{w=qTZZO1`{=W>^0!ASMXZLt6=Khgoj zD^_*HLl9?*LYpWSj|HHK#{$Kfu2kcV@&Ci#o50CcRQu!Ix4UOcFoPQbM0zF&6V{0e zMhP-~-J+t#=R(w<8h^ee`kuc0d{5fb&w@t34}eejw}*3342740fGcs zj3OFT`XQlyVjw17i z0~Tyn?#<3h(C~h3DfF^zGiv*+@l(VJyNZP2uLejdljlid0p*})zk(itKS#mB+6)%% z%3`6B&9jBDKwF2SQ?eLkl*K?w;1`PW=4_j%!oW>9-%&I05p0`g^#y2Jm|+w(u`UD2 z?KP0RdP4G6^gAw|r=e_rCY_;#S)rJb0rP>=GZ2t}yXZPX!M&x%*ekQV5Wo*)P)X;K={XX&)H%~Zu} z>m%oRC$F)@RXUO$T^&MRz!Dy;6p_Nc|a?a)>A)Z7z&xcwWqsE4Abh#lsma zxWe$!NZpG&&7DJ+51!8~x#Mz0SUJU54!4}j1}>Kd^m-;w$j{~y zRK3m~Kmy{mJBhDdhS!9mvDnLvy+o1rXV&!7e-VGV7}H;MhpqxeUtqua9~)8hIjndQ zo8PoCE+?>f9}O&zPf0Q>_uBn{-7jv8=kc`*-55_N5EtkeFRJ0%6Zp&d^~ZRu{Wj_t z4`;=5*?cqFt%jb{%hyXX^epW*=jPa~^t=?~85b`W;=P{OL;*|sm3XgZ(K#$a${UF; zx{4)dvn1sw`!Rnwi$B!jCu#F39-46ktqd448|X}(*d)i-S)qtx+Z-55ILgWp{*|ja zyg|SKNzmjFxgFC`q+JsRXd>uOHOdFi33aY z^YJWdZt^wMRHI*&rz>7R-;zPraam%1RrK>QO;0{{F+6kXYC4SP*35XM-Pd692QZ$o z$o(j?_g>B-N;0zdXZ+#l>|Ab|?7cIL-em7lP0gmPsJDRZ1p-v}+{a-a!C@BF=j!%o z?%@xIZ?5s*of-dO+3~-cx<|&n7%*&v?n#n&TDILE257oxQFef@3cD^uzvJTLL`FTr zNkjolj*vSke!-FjT5_Z&@)W5xKReSIPfI(tO2?Wt9gjs;3Rnhec#Op!O*C!$1pBA) z^H2sq^IjwT9NesQ#-6R0W@**@aAr7c_B9Y@b4DEvk}@;F753NK=HOseo8+`|Gsk&@ zD0Gv$HaFs)!!I+VX7{hbsJ~Bw9w;7&<>5RoA-*pZevB0Sg%tihDL7t8emx8RM+#1m zg0(C-2nB8h`kgWH*mAr0$$!n?zQf;eAm4e3*Rk;1D6CcMjZ}d%$>Aig;~;)2AkkF8 ze>a0f(F7akAC8~6d!!@?PX|EEGyE+8QsdB-r8OM7#maApf?2g_c}~kV4_clL&=^|& zGlP~!3SuMC^5lqUc|HJQX!%A%w8#&eLp>vAje9rDgsRT-uLqL+1JV5T6iNP`g6%Zvf+Ma2KRMz*QSue9vcxYe+qyYTE5Z{E%L(_A;~XM=>9-$hF6H^FJ;ItV=}0HP);7YO5I)^S$1YN%Q&4D_yW4Ep_*n!lQs;h^V4osHv1Z=NMtq}7at}1ZZTEl=P+60;-hu? z4q?gkrl$`vvEC9&Pv64KfSDSscEF9cls4=1eWuyzOO7TzeTy=qVY9WPsUrzDKQS_O z*vQ1VG1ho`nEjby)}$(X^?d)I1W{rc(FyIhwWJkV9}B9* ze+P{mPXP1&C6@@Ah%Y=NdD`1;k&Q?HiK+IxzVMC5gAe&!hLB{o#~#3362QDrv$MY+ z*zkcJ2>aCgfh>|g8yD@wAkA3L7Ip{`z0de>4eRdTh+x!;Y^lVgrvz%_Hww`Nm`@2X zpQ72}V@`)`6qU!39qf{dPP*oc7Fm4;QNBMaj^idV_Oy7LL?69tcp-^fJg zr?TFA$5hVZ-~Gtq#ft0~F}amZv!01g!*zCm%cgt^x|53;IyGYFJhu5B0?UTh7{l=T zVn2VRB^=LiT;k`FbL@~(pPkPQ-5Wb=dMZ!>XRi@E%h8l2?iL-J#Wg9m21Fyp@+8>W zfDE&BegMnZn#rkN1-6#dQx0YISoFdGnavmP6LKtiDd!3aq7p2ME!BD~iesxbVd!P^ zv*^VEOk+_^DrKttRc2Ay*<~^*PmLUOniVb&FdK{ZlImr@x-pAhMU?Y`qET4%3f9|w zOyyes-A!3kwyk$H&Jyma2iJ80E}L?sSn{g(r)-ax03}uLO)O+aCE?lih(!|UcE8EVZ6Gtpr>bKUae8R>r*@mNSfr)jOx8PfMYzm6To>Dc(fbccvJ;+ z2I+B2fXq~Hw@igYJKssG-rK@EHpykYGWGa+Z8BeK{BWH_E8;-* zluX>Sa zro&Y414KEKFd1KWsOs%7)!X4z?>(%y&6vtV{EM_nMV!c@`jv>JHxV|cXzIcCivXKV zJFibks$ZO~v#drO9v8lvD@<_ml zZ2Dq=&89uve)-fk$Ys&|rL0lkmir*{K_3$z6pAjBj$ICgyP@=|>n4&O02g-ry(fG6 z{hHM2cP0<6EOWQf_{|qxYiKeXNo}NJO9$YU13LaW#9=~=u zm~K~|@j|+N$s_cA%uq-NaHg84%4gyaj$zCy^DqGJ6GYOQ?sm;Z8dviY)WCE@Tp~$0 zSx1HWfF`ps#G4GVl}5&wI$8n_`U4JLYL#3=Y(_NpJ0o0+%kR+GTpH=Q<2=z?7cDHF zq03ubdc~)~d>5}OVNhRx9y`l3W_KYZHpdHT@o(G$S>$g6(0PApyA{SSzfzD;8{VbG zr3Sa@3~9_m|4u1_)2H2BLA(KuDQa8FdhT@!p5KmV!CU;Byfnr)Cs|=WzCIMv;%3b# zzBUx%?$Ef<)mC{E-r9rLF6-Cb38kfk#jt>ynnjJ7H37ND1>|0?ZUeNS$h8C3ObfLU z2nAU&GaYAn8mO?nvO55r7;uL>O}iOT%X_9K5+(7&IT=0=Ow(je+ZV^@@?_d;zq&J-^8ZPMQrsVq5_#;f!U;x{uibl8a0jEl6 zerAItnzMwCy8%!aP^@$>SpsGu=>l)%+>vtzpsM6d*i_6Mr}ctL_8d!eqm5biQ~j0E znE_nGGW+mmR3j_{6--YCNtVc;Sp@|WK+HEpCE=(NKA?0^{_>rf3FE=*)Os@Y>;RY< zQZ(0jKa-#keF+SMfI&_W!Il=9EPy8U>ZFN4n3&5o#OUPN#u4MP0F9xEX;y2|)N6}L zQkY$rq_W?~PjmI;7=!&QEP-~;3%yusyYbQsn8j$v%TNs7E*f$Tu0qJQYjIhfTZbUl z6sj^VFB6S4ojfdB#_6PK=0t>a5M|R+D^eho!xiK226}1n=b5lzI*^YT2;5@FgCM>5 z>5cLebP(@|bubbEE{Zih0j^GcI=v{M#wLJwiq=kmnTSbgfI7U;lv&$U5jvihWG%wt z<<QOD-=M|xb%>ynk3K~ekpK>^~ry2J(*Np=euAg!20E*(oqJA?m;~kP%6=3 z&-AEiFhh^Yu`P#XE*FSZ^T>P4am(2#x0TKx;|FhY8*3ZzNU+>xyX)=QC%fkDtFiMx z@?O^X_FuYCwI$SfczK$Mw*h-z=aP{!J80~@SaO!>;-9;o<<365Jk?%?V?!Dnb}v(- z`ksgQ5PD7|lC8OUy++q#=oqav4`jtIh@WCuzXw7(G$8o`wegvd$}4=a#CpucU^x#U zdR`bv{LwnIDY4kyz7|pZ6CbJR=dFg}$iH2ZD244suh{ zHktzi7mEYsopJ6!$TZ#{CrNg3{#2CyH0Fzj+V3t{iY3;7&&XcN^Cb#G$p)@3m_x4|C6#IdH?lhc{##uEp-v4={7Zm@F< zBZB6V?{IFT4x>%%(4h=VHTQK3U=NgaSP5jM7pvDNs|KXDtt#kJsimb=Zc%4~&~f8B zw|+e>VxDl81(IAVNtG$etlWiUz$M!sAhGeXfui_>T9A2%ikH{&z8m8XUP^wLZl~I>Xlnqk3~#jT_Qce%T+GTiT7U&8h~vmw_q1g zR&Zsl2nuMC3j<+_!?Mcb?IaZ!!#s#-PnqBdh{WV%1!>ml387ghEIiG+hM?iyS5ffF z4V%^``CtTyMk8-Uk@(pil7NaZSM*(x&1J4MN76VHfz9)h1`kygqhQ2MrM8wDmyBAh{SNn(;QY97i3l>|%N+hDvlB~yhbi@?i zKo7c^8BZW~=mUibDp2r8@&Biw7&-6yVQDDTCQL&?M#SX$yMoBM@$fUZI2n!M5-hiP z>(ob=cpa@79|R-f$k6fWnk`g~2=E5R&xGZ?-W-dGM4#b`Bbvgs;}onI@~wLZ4ZBBW z2TfXQD>ntmjt-FhS~LErDFF`lz704*gQf<^`~l(%2A2IG{O|O+tlDT0dTBsY(Tf1F z1>GV`3`Hj>Xa_n=qJBd2##WbsD^O+oc0EYnP8P9mF9z7R({lCtR+Hm~Re3PvKeCJ` zMb1CI{{sVmPZ)rTe5I7tkucNVDF5Dse;b+2{r&I9-RSuDp{Y}+epvq@uloT9d@S6Q z{#pDxa611+(ZcVu`+c6XQC9eLfE+5J06?9QC-%<4WH8QtYy zHSa!}-hBa5yt~h)rg}d;A3jX`p8PNcJU?eiBKWgwlEI&cgz&W~;a4Cny!$XceE3}2 zFjf3@NEfdO%Gh0#UPis<6#lIYUtvgmUExgz4{O8Kme`1vtD zSK)JYbWL~n14*uru69A7x0a3VfSS0eWD$MU(VaCPAt`CMDL zws2kHdK^sn2|hRAb7SEq``lc(x$x7%E%>Y|+*-J;aC_m7!kvYm)qL(kviZ9U_Z03e z+*i22@Ic`~L~Q?@?i`EhsFt!m=+&up#V=UDQf>M7?)*+Unx_M{h1HM4k}&8I@s9=R z!3ev^;X(nVCYK8Z4$fXEfO4c6?t%lSYis-m!<<&;5JNWX`>-sm2hlEmgW<w(i1qT$kie?~gRo{t)6ufC2`8tO03$Y2#&24FeD?+7>)oap5PFVk!B zAXmGnjTH)Nbi=!T(*}*@ z4$)7t@*7vJ3MzINO3b8p9^;7alM&kXiyp7IR|k#3ZQvjQ_%gJ@Dw;ID6kA5M6X+|r zhqX(wW{7{5$@%WqlDEjI_X#Litp(eNUSLeYS7$VNc zAYvbUSWrG$lh>sD)q-6bB78F`_hm*Uk?hIVlX71|NX*HMx4V^7NW6P`25I1XnD%4C zv_GTMF7F8Wam`I%+V*H^6~}?8Q@Yjbf7j)OGG8KP-Xg#A=2nsjW|kxedTFJftPFRi z3WsGTFgA6d7#Rns;{`>Kz1b5PjO+lZ(Fzi5@yCgTy*9v6V)bNucO9eF1VJ|!5)S8@ zx(-sb?cZS=n*nlzP$9Sp5R5OEgyhzefKdR7F*hc|W^QDG65&HiSS-Cks)>sd5kbL8 z2}(-R*53eeBcd7tQI+B@f%tAR7z%`1!H|*~oiTmahqAKp8TZAnQ-|T2B=)As4NI7dHci_TYgNJ$(SI@!k8e+ z!k7|+ks-C~kS_H@l7#qg2e2q|L(+u!ya(YD9a6gti2)=RZ}}lz1lSyP0NwkbR}^Vk zi%|?OW4Lh3gK~jj_q$2#wkNS`6cb~Yp~DDA@q50zn_G)v;cb8 zv#i2e9^+XSIHuBFO&bf!M{Hf#Sz@BXxLm<Aa2S4A#FHglv>mQq-Nj- z1{5*Co2k*E+p$Aon(G$AbDF|a(mNGS5qMy~@p>=9wW3+LR%PIlwwi>C7{IM))U!n- zh-!(alneOV8o!A^V1d!HbbDycU!AiXpNAmO@XT5z)M}5nK_;nIsqx4SyMgog9Xo;8 z^_ntwHvThAlw^;lDAn6hr8WM&ROfew8jC?(jCZ40mwP8p0&>vE9>Snuuz|BzsRWdZYs0k1F7TB4PRq1)LaXED{Yg4Av~9+O!@m^Eon zGT5U41=!^`BampeT^cD}D zQL{7UjA9tH{sud43Mokj1NosqdZ+51lr%4vE=IdDKZiD$7`(j2Oby-z$|<(?0d{>% z2L|ldKe7d6Yeg~pu{zT88n_?94CReo2_&YPW~Q4~zql1+IT*Bd?w-@F(>fs2s`oap zr8$ZMYK`bqn80Vq(?_#F%u&v5Dc+L=y^g;e#a~MC?m`n%_efVa-(8A(85k`^qA|_GX*L^eQJEqoTT><1LrO9WAfzmzJ@Mmn+ZWu|&4Zsm zWblKI{~qu&Pv~x8#IUHt$WkaE*&)R{N*1!DswImwZ?=%#E4Vc-9t>n>UrBcMb@QP0 zl?+<{3Pl658=cg^qodJSvkr`AY3(l&_WlD>>?@ICUpEg@4w>h@e8!9D_?V5vU%Rz#pt!zvTjTS%ptBJ1Oi-fwi0YPza7<$py3iC4f#q6TojSycV zx~SPlF>pj$rm>K?#cvS1q!XMZeP`+*}EEmWva9Ysjh6nlf(> z)LVOH71i5sbl~uoSf2brwt`aVSu>tbXUX#{QNNG6P)=j%b5f5s2jb4WZvjDt!0Q>T z@C=%7<&Uo5*Xe?%LjegVVT5xPBg%?akrK|KS;F~IhH%z#NZuNUFVYba;K28~Q`)Tb z=os1c*{tOF6+kQ@>$w;wa`y&GXxS8L*<3)(JsA*=XjR-ChLAtGA4Wn}m$S-RRN2DT z>*K^_yrQACYBAk`k1q_CKfOk6h$T_JHgRXwh1~_SLj%WWM`N5oZ4{@0SPVfv#*$TeBR+4&Kif`ax6B8hB z4{f;#xDJ4Ug*IgdZIDI?&T!Lty_U^3l0fVb=G-yGjE()Pj3|TuLft z3oC%XQIx~;#Pl^XA;Cvfqa*;z#`%nB|1oMJ$pkbWk+TCC^l88ar4f|HRhU6INM!?9 z(srXj5bvZQfr?uaW;>c`hK)b$<3=?bEy%1u1RrIgz%VS*<}3k!HMDK;SMR za1l-ePzFg#4QR6eD98NtTjj+};3} zL12K$9L)=jCycByr%5cyKJR2>Q zOIUck4iN@li|lI34uQ0BZ1@F*h48~M*&kq(u+38ZEOscxB_$aGe*ge^892mIi{NI6 zT@Ij>IA*IA$?$m;ThwYHjLIK~fuAI^{J0@-$K!1ia$WhYqz%sb;yuA}@0dyaip96b)`89CU;eyC21aEbAU}15wC-Y?&M(5=^82{>{1*A zSHtjM%c-ESTS6}@^D=_Nhy@8AWK3ct&Y=MS*A@>wds?(~?6WC!EXHiDn5fWukit(bL@7FiA-_1NFC{he%od-->}cNM1c z@4&OWy{phim{+#=GfQx4Cm&WNA6D~W_;$ZXxCYNQJ&4H7reHUYx|`!&#POEm9gRP5 z&^b^4(N;ojzvfgNLb@7UbU3dAj~2~dilky?4TF*lqYK#pR3Dsr>N-Ue`u0_| z(f3hH-=72jp5(x+0(nJfSZGy~1gq3LDJk||$>Uuy;#Nfx041e=MQIK7OBT(SQR=CG zm?Qgheq*Ws;Xpe^{nEx}q5elg+eZC=!nLd-{A#FwEs^#T2M&r#Q$HwamNLO=FhL#a ze=PK3)c;3fp&9Cbf;jtwbWGY=HUjmpcGSPD0rlggqN9G+ZHoH4jrxyTzx$S@ent8~ zK{U=^IO-QTYEiHQ1)(!3{T)hc=<`4*ucc$s+29Ctw#w1jU;{dv8R(34 zo1!x)43V;@-noV8j10UA+E^@wKXKGgk#>+it@39+JxPqo!V;U%qNWFcY^)?;6MTxk zOA1AZW=UjmbOCQXf%mcgiq++OD2pDq8B7^V^4nwnH#S?(SX#^`hSSxu#*#GmDC)r! zDpZc*TaN&GrzRdHEunxV(ITuWxq}AVNtA}Tid#%2Jj|L8vu1&M1gb*nz|1nm;1d3! zf<@k7#g!ZT5MHU_#p7A}b3)`So|9Sf;70S}i3|J+)p$|b*etxbB(!b3_&{A={5i35 zKe2*&sw4AfC@&7x=fzV(FUE`aHp`2r5oh;E$K=H&BkZ`LoZg2GWmopN4&41cFkwSz??| zMBGmFL~(vmykmb{edXqBA7NfOkgWjk769DE=U`JCva4KnCn5$x567&$amifGCldy_ zJPh&}9ptS#NOLmE7~xoS=R2+aec*>KtflF(_g@Ma~P;X&?14J0wD$P$k z#39`%sO4l5;jKB!7zBNhA4bNPbH15evEC8Yr7QTSBhNcX9v~Akpnv^zJmFN2R0ZON<1xx+*yaERU!0J9@)c~PgRIqw|DO%Mf{kM75|QjTuEZJlSV{qQc^i||E=O1Q@1Sb z0=YL#jfwCpbZVLu;llGygwr431%U9p8^*@*yg$tcdLY4Vam=I@+x;1=T((hI=?^!~ zAIg@@<){7 zkEk-t-&SZ#1KN_xDFCq|sX3v7>uScw16+qITVJHDsbPD)-g}!1ob{oHQo} zHdKm(W+`Q%T9$N0|AA1PV`E6^W;YSd>gE^N*4b>UzHa7pct#SE!BDM}lx|+as*VAz zit1*4*n+y*6q(HCpE;r*aW>uRXC9Ttpw1I#GR)D4`tId0H>U5Tjb>Iqqt5$ZL))hB zPOq!)?j`7_*;KCrd6KHI3KF~0nM{<@4)3P;hIEh>uVCjd^h-HYe5WKyJf-+-_L@?B zhY`e+31WT4_xC|TuabDj>N@jOLS^pL&XPlB;{`UbooF4*)p)6pdhOd z)MbJSPf7sKW;8J`UhPudqH^r+RZd$JX+8LZ(BpE=LwkIliAjAdv00zPa8g$%nxf+QX{}`T&_v<$`PoU_S_XHDzmb5F@7rS4F(5AYomz(r++8V52)KDKJK| z_I*wY6Gql&p!hRF+cvr*Q=?la*8ZIw-4QanI{y5#LM!ImIb0zGm2p{U6tM~i85{3w zox?5;Ll=$rv#P)!EGB4<2HqW}xOeUyR<7sXk@-Qr$?1(XY!l?h_GbXlm5l;E46{1} z04wy`$ksvn({Ia8Sh@?Drt{OJinrv2#(Q4dwx1NG11G0EPU!dIl%gu$JG^y%=9LHgxU zA$=zE&KGL|c|KGyNWYNU>v@q}^SOk`d6@+V60acOrfr!&hK@|^u!&~G&Zwr$hS0Q$ zozK>a9hJV9GCJ!s9DWE(U1o=+U1(QA7^e-LehOny#X7`9sW6_;20ta3k-Tb^einR^ zm}yoRFFeFAnhYy^y&0^GDvS>aO&eCG)nY}3@e0EH3B?Ljkc7|?3pR=>M-4-Lm_~Ls z-sjNJi3#J63H+lAP*oDcvq zW?&P|FvF-K;>6IjF~bLHnL$Owa>D(7Wrj5t`-W&H3|f35X_258Q6ak=L;`9ItF!NP zHWDYq!r3h7Gi>-vQgCLQjhd%5ZNJV=BOl%U%jx{clk%PICdqfUoT+1qZaHv%5L+CS|>jhIP z(v+Npsh00_Bq@gl6yF#SWVv2=Q7LFn#xW4dX_uSX-EQoT2Nv|_IjV7o5UEsd;knNR z%v0!2Xz*x=PXL2Aye~@jS0L1FbDAe4%I!SZO{^h1kDer%$dL&Y20CPpb}r8W{GSH! z?cOzBe%j82AjqoPZf5}RB>X$$hhlt~20`7zlDDD69Y2?XoluZGeJ+I)Sc`#4t%ygp zWH-DW2O-Ee=*Yz)(IG$-nrhGY*N( zt3uIGYq_0A>K|mmTL}%2BRl9goh^;%T|%q*`wsZMok95z@#!siDoQy1!+hjDnrL3a z5~W}}$n|glPkjbCo{9odo7U>lVk%5U(c9h#3Pr=n)&Tn z4vbgjpg;nY|HuN~mBVa=azL{!?k%?o7Nj!ofozN4&3l`E#kz8_BPGBR>WodytMps| z+jxz4zyp`6rZu(bi|mef@!$t!7RCS9<5;ys^IOJCePw}qk}bYP*viZw@RDaYwCr8J zdU7}9TS_9HZEoBNsG8{%U$Tfm*n$ZW7hgwTkaU- z6f`7@4dESIXX1t~^yg%u36YG?^-tkFyNFTl=}NAJGIH}T;hmZbADsnbeXUU08wA#0 z!+V)aADYL@e zv%WB%zm5>h=@KB0uXD7*TIV<|Sc*4!?;85`ky7r4Zx4?pWM(-p`bK#VlP^;-OF{+& zqv?StzF{dCSV!+#=SAnc0QUv3=(hO&HniX^22!zdPoUrvtA0|S)lfLT;x_paj3x02 zGI-BQ0wVu3H9ie6|NxuXc&{2)x9lSP#H3(<>Epv0S3I-wBUY z&)b#}ysYZ}`h&&f6J=G#&)cGQDb}+G%pyEqo+Ij~z45q>{w#d351!wQXQMx7{EadN zNb(?W+fC4j=qpO+yfm6u&lSLG1#EgN^Dz4^^=TA8s7%66sZUugAKw}ZsYqEExoAGt zq&6+amI#3bypC?;_@xw=1YV*NcYi^2D7?&EOHIK(1zNHsyO8S~b=I5?85Jch9-(rt z<3`Q74W~&8$$L3LmP;GyD+3XmVw2m2V>h>W$G!(Py(;q#60YU-wyN`6{Y{2ZU*T_1 zC{P?bsp2RWOLDtm$C$CW-tcvDyP@cf@!M{<-S%(6^fu5CYf>8Gt*Bb*^%|lN!Pk1v zFqxhvFPMBXCYO?O4>50PFwy#j6!FjGF3bS$Co^9~rMJG+?W1kwWhJjXRG-LXk(9J| z@n1=6P{1um-15z<---^oQ zP@u1m*}3JUg)QC6#RV|;aSH$zIcS;V)8oF>DP&gU6`(}k29ID>R8d{Q+n{NYmGKAu zl%AC4aK2=&LDO1fN!3sMJ`&x~oZd_2m`A|M{D; z7c$>HFJTsG$}GKajK&Zn}=$1xMF;+atnN#MCTngpJktMWYFbAmWZGI`Aw z1}J{1gW3a7)H+hsc|tiPMoW(xGGOy^K{Ph)V6i`IsMM*7z>C6cv4afj$attq@3TK!@q zHv`Zp$T=*)W60TM%OVHI7KMuHA?Jtyj3Gy@a@aT)@FUg>zBi^EDkZwW#E0VPdDAH8 zr~r>4XF>)!O36yb4$cJS+@}^bu2Ust%!;dLma6>U+&RdsJn$Afc@8%uuVcXZ4V(@K z=uk&fp;V{1pW%q)LVgB(c*t80cLcYq4g%XYLjlxk4N-nf7^0yZ9=;~&5d)gaQ5}>3 z+A%P-Ydm%^MUw?ryEyyC1PkoS2dc1p2j96C4wTR#qIO=hBy<&yuJ55d3D2TWqg9tjE zM@Ix{sEO z!Df|gKrECQG^{S0)Vfu8gXFj}KxJ6sS&dp!G^m_Ej<$`=CE-Cu6P6TN9#ogd z@7gxWw+;u#_I^Fo+Sb=4 zg>odqn7&{-{)7pz>hZ*k=^%y9px9QQhfJ2c3f^SgG)U1scs`yE5OozE92%#ILuZ6* zB7P_*t{YmQl!pkrNnxU{jMs(Yaw_?iAgtbpS0&!&K)+q*Pd_M}mh zz9KqgI_9c(lFk;{jxFSo6jyJdWWU&RgMy5QFWV-i@Qw_~vv?5oRbbvgo`~Cx-==Y1 z@k6KYVUxyN<2ftN99m}2Zhf=Do~K#;m3WTV+~89&CCD8_lO<}-hxFmNKss;&LRyEo z6Z(;+og0$vI)_-jcI#u{*bD}EWoaTJCVs17;QI5C9Ywm`@)+<6kqnfUH75j+&7-1w zdQP6!duK`J9dWac*w0CscY^2Us20ea!U&!lNSAgmUD|-s2C`&rN|sO)I$07|pE)ja zYrJ^y8BanSAt=yE851i`%9vE~Qif6`jl=m>-|-LCC&Fo;lS_MS>4&f4C_Df_o6RJY<@wWCor4ntLLMMlWPM%hw2S=ip zW6VP<#wh(IGS4vda=uTTY-`+rA-`=mtzDHth_HF$&w0>D*7 z0TVZ|(1u`_qziCfb)933V~XC1jCv}U6aIAMB$2tM`-i(jk)E?Aalyq0y@H*sSMYB~ zZm6}R61~g?pQ;=4}zD9)caa9Dn8yl0{nIMe#N*AAQ(rpC@MVv`Tptm+rv#{|r0*LBNNSeP3 z1cc%hC;_cVvrB%O=e8UU#!o0r0HsrQEvHOF5=Pr6!o7&yz}7%Hz$bHGR@2?jQCu`k;XwLc-fjHOQ@?^5^MeEJD1R%jKdnueHQ zkJ!|}gt~v0tHSOdpp7D%hNt zdwpfh;6J7>JAIg=%{YC=r5incI%#1d>rUUVn&&5E=(F*WF~v~BhSNs*NCe-$LkduU#A{LIb*O;EkWP(=U7uDXAh}f~uh^r$?4Y8)`X3B-7d6hP;wfTU z<)1i4pyv6Hq6Tq;^tU!x&s49cbEA^$T&u>v_(oPc-^g-A^oh=y zp2RcqHnbw44_pcKVXkXU;nM=pW(tEjxh$N~T{7Eu0$LywvUFNmF9={6DG*(ubh_w8 zmeIH@p@gQfhbOA=mU}u9{n7*&bnb7zlYUkJ#S#vw?-7&;JB*m@OSg$(%Mlk~Vm&ay z89wHz2OcA7+rqN4x{eb>P1N&RHi?o&VfHjj%XF7DAm)WBVtzBK0$d}fk%*aFASq%7 zeJ6>T4!Bee(zi@Nlf>-7Gh#+aP=c7pZ2~bIyDw~y}x$EqVaP)xh=EcBD zo?9p&ZeD!m*{D$21)U1X7a*n))rkWIFD4+#}6cWiMlJ#?1v3VygxA*vCKqiD{qwr%!$QGoL+h`t;9z?sK32{O7;$g)jV{FMjDu zU;grpul(Py{_{Wo^S}J-zx~_HuYK+7|NbA}Xv`@CDNgxMRIT)wP=O4=7P)tS^-2;J zo>$!-TR+v~o_Sa!2Ds|`Cd501Ov)l!Q1u;{68WaqTN=NBjr|>APh$o2dNlA2G*F1w z>B%tKchzF}7@hpDMz1V{) z$P=P3;!YEJ@kPEkU0%eQjCfDJwHt~)i+XyNLxt<_Sno5aSBR%nfoH%g`pB>H7%K5; z{9YnhIN%|zujgBzlGd?_8ei!BpR3~Ij}H|Ff(tY!K~Qgn2C-g$?-<4jogV-~DmOg@!)XHvSK3~Wzl z-q|bNPiCH<&AhWm`kl-v_P2O=wGDz#`cV5c8GXd|&ogBq-JM~S@c0LZtgGd;nDq^P{w9{^~x=mPm9)HJq zb_naX%6vW`&{L%~>|w3*ClVSXIYlnIgW1binTL14C_(g9q%z_m_0@h>(i3rz7!d3t zG0tWwgCARX7Dom4;Vi>~T#kkp%^dy_3$gYFwbBGQmXGu+;X2c$GknM8Zo;Q@tJm;~>iEDbKb+?+5t|F{X$h1-pz>-fHKCL3r?Nk~T@CkwWpXH( zRx~2?0(tc$)*CaXGRVL1_Y}JdmE-xHj_{} z6E>-so-VXp3^5p`YLLpzK=kQi$TpM<3qUe3S<8!bUqP$l*e5k#3#Q68MQ{WSv`~Ha zxHEBmeW5}t6wVZei7tl{iKt6JeERlm%4($7hou3xH@|WDtU-#pi8>p-YL^Q|F6ggj zY*NgcKJ;R?zv@SB$;(L&ek>TF`^Rk^?~&yWD7`SKS+-qPT8h13KtRoJ7UxQHm=p%W z<)#V^X?SHIPgqB+KW?;&*U>}_pRr~IXNg2%PwMurb(QO?ADw$G4)h1e6MOS)0X(Ll z3IQfY2<*Gj!Y1|KJK-rp`Q$|NjT{V>&aBm}{>h)TgJxTrqS@>M6;!+%NSN*!+12BI zx<(-a@A!wqmRRtG^OhJ>1JYiSB5fRI%vXkjW5UJn2`0E!r^8H~E}5OdZoRvN&TyW6 z1cvBbQ3o3y%zLjd&yme~BLhZO@Mtocl}YC_1aTrl0Ya4<7;gx=Mjv4;T6P>h!v~t6 zNJ;xq;~T@cva>-xb^mHNCrKI_W>8C9McGWExCkR0DU5)N8;b3;bF@_H!Y{g8=8yx& z37BDyi4LVR#d;fA$88C8g6+8vKvy_riG7))+)b&GC*@COfJ%)La>fDOIPMS&StHH) zXH`96{8_z6x{GT3EY#5Bhyh^rdOi<05qKT_AP=89en=0k3Z63wJ%ohH=?y~VAS5F@ z$kA&?H=G@y{k=j<|C&IBC{Ko^?FvjwXiT6(8H1xxVQxp>!rcyV83nf=2zX``4k}7d z=U?O~oI%A=xDjy_if8fb+312nur!R~cRC6>6#Xcu8hAoNRHf2&f^yZ+t4rW$f)3&Y zJB?mhR`!jnsR&y_wcAL9K}5X)YSuQUHEfHg!7-!;qUe;AC=ws(`XGup2ro_a!KAW2 zKrEBo9g5Ra;-&#pk~!wNu2-) zpqT0o8+*>FOK|Wk@FJ4XECK?C(m|;^)0Ot3)T{`rH`xy+4B(hB0L##?N|t)k55TdQ zFrVW@VLk>edIU+>vcnw1mW`t->+6VfrOa!&q2W^IM1A@JMHX{8Xw1eWIG7?qi1m&b9S!!)cE;O_g850gY4oNfPBAYCFWRwV-3mz_J0{r) z_4TM`SOe60oKci{YNK-TQi!6=glWCp2eRR@Hn|^E8wCI)YFGm>DS-`eH#f%TSt)#S z3&L3!z=OYE4*ngdgY~|s0;ySiNi+sD+@n?tN0L#86BIO#lDF402^^#Sy4T~C8M@rpOukFRAO6UmbqJ>y5W0f zxoq6~QkGeasW@d303=S6VK2lE2QH$COfi>w0r{l4Jpn6< zgBmOs_RAv_py+i*AjOwMjpj{c`UE8hSy{fnr4lyP`1^6`H#R?!W4_h zH(18KDKjw&HJP2lo`Disgm;f)KiFq2cfL3Jba@;b-WpF^zc-qOCp0+@PvhPj9U!xN zU#AF{AnMP`%r0e}i>s6@{*!Vaq?nIPt4_&b7UcU9oXf%%w|pPKcdUctdq2K|5aoLn z-?8GC@3W@lu*8?I2TjSf+Sln*a++28ozbVKN)D4^i#qa!2ZMa!g#!7)3uWPpoT&jah4E5drcj}L z>Kh=GU#+w%QD4*tVg7kYauMV1R0H;G5iG}lok+EZn7KE+k^kQG<~P528|GOVzb*G~ zw|@(gt?=KDJMLI6ci9&1+jia=ySSEmWv^b$R|9kVf|TfgJE~STICGmeB27ryHxcJL z&l*~SrMzrrQZx5b4aAXuhD*J^^jlo@{h9RJvz9+%?0Smy`|U$c`VDf%5@Kx`=hoEf zhB~$%Az`#<+!>DpNpDX>Yaq|lhO6jR-W{-_WC?EQg)4-nv8 z4d94i65_%_`I8qA6_8v!ei4&LSttLcofMh*Njv$k*$~d~yDuc<%moEMM!8KokzFnB zRIqJe4FAuetA!?qpwpq3UaN=Lq%{L$~|vkis>k-+_F z?w!z}uz%ulieT(2s4mr^U&zt@TdQ|rg$aU0${|Kbdm&dO5h4Spf|iUSQfK5b3Tprp zGLFhEq#kb0G=!9%2&P?2gGV{;&mNlO6{D?z0e*g%STn#i*+$t6HbJu-o?*&Crb7$| z8zl_3OqQ3qk$G(H>e+XqE$$Q*n?kPQ7|O_uhkCev7g`jrCk523+N-f<5f7?(mDWfS zXmpl%==}tCD%u%S>TN!t&VRS{xCVX&*0?HQ(C#VJL)`Fl0A!fF;eKADgXVB_18IPf zrkf8*H?v6}c0IEeOEVi_X=VybK#v}B_K2Zgum>oxtc$n4M!G%V%`}p_bb)fg+tPR^ z(@57Hy{Q_he$T5jJp;>0TQT0jdcOLkE6HnY8!8!)(vxXMYij+kp+k8G9ozH`&7?d0hc3S=V^p)VB61znmjZ zd~dyKcZ=WKIpw&csG)V-oaAN(R(7gIp|WRDnF>g$>EUk2Yrz=;u2pxZ<8y&Nmndm>8!Q!aUo=HF&VKr-3Nxj#W zu(ZUmpfx9a%>E9lHJC(|je70sg7Co>NSx+k3n+Uab>8Hp4$e4>PfnL}jpfc|DY?V57?m|) zB{s{FFmwA~PF+qc%oJ1m`H;$-ekov`<@xxD-1}ez+afnf##wAD zV+}Cdv^#WC=nINF`3>yUDeOciH;)yH7H_D*SEe|LCy%gAWRW@}Xz&R#+hIQESAA2a z!3BLJlUlm)nNmm<_}S}p>S-rwFmrLbhXtVr)6*IWV7k~2Ida)Z?jZN15BD7sS_p~@ zG~<*u-H1+$i8QRyVvFtVzd?)Lwn@r-NZf{2(oN>yo3)<)zM$(nNa$7 z1jx>vs%yM!I>d8M^;8|WkY}9oG^W8(4IGNsq?nJ!L{MWQR%>}j*2N%LV;$wJBoF!) zN0g}xs=nTUYz(-6m1arPn{5ZigO zMaOA_lUn_q)%=`ztP9%&r$M^IDXhA#3d1=bI~VTG5N|sM27&}(?jemIgx!c3`zR8% zNpCnk%#m*q-pH|Yp)t__y~=P=Vuz7N4zEcza43V|rHv2PQVaa50cj9`NIGD?2ACw) zRN%6+1Xct{B}lGEU_->T3}}$|P+NGZ-V;LOT|BQ^YJGLLxR^7Z=O{5y6V6_ovjM=2 zH>DynM=F3tgqqt(RcAD}@pxQ-hg|qJkA%RSk^;0&5RMKY+UCUL-E@gH#x2V^d^H|F zmv7^OGy)+7Xsa>-uQG)%O$A&=hg^eg0tC-FF-*P9w+Bp&pNp+exnixo+*aR?9 zQ%iYl9Q9khXwe+s6uTc2Up_|abi~g^fCziB;;{#FIl0RA?Acx_d~DDd>SAo^~`Hf2Ue> zxqa5>{K#I}f3YcsK(!ug*b=Y*4ad{)k-`--|Q*0(I=Qy(l6e>mBRM7ueYSfbr@ zE-RC>E71fnBlqElK%R4r({6QiLf;+7kedG^s~*4onkzFK=wR5;1-~1lnEGyzj4pMZ z2BufT**RVT0N5z9`)RzR|EK_f1#)Kt+8sx|$L~Sn zd*$q((71)bX+kr#JP|5Ua~};Yui)FvP;)*hXEgMXZmXR|0Hr8fPO9uA0tPf7B86fK zr*bSO5tr=P>6HnQ9sJ@PXmbfPVlAAx7AuZ1XE0GPYw%jPO0XHX+WC!Sf(TEo=dG_U zK*M7B9}ef5me~W{(I(PHOY=m2(ptk|J8gzhPvdw-hjtv#EAtjvoP3k>M_6yND}A7$ zT0GbuAl1vod3XSKAOLKEh+u57M{)#$*LQgso#j+AJ5qjP7}1;2o8H4!?zi7~s<?Jg&ln8U8eRpafPWg6a-7VPQ0{_f+7iI3qyb@=7rnkX zFiGQ?hsrqX2-MiVyIs~SF@iNE`b!QI!UncS?vsFi@kmUQvbxX~bpenld-iH$AU z4LH#lVgd;vgXF0-4wB^|=NQ$X?uU+=O02)?`?KszqVB|3CsEBfQ%kc-d`~F{@{!?P zb9O+U)6d6ECjJGgNrL5so`QULB-rpc+Psbt(HZrP{((^5F_+kIwe*rAjo}D*^EMF3 zji+FBY6=(zVs;2I9j?oOCE}K8%JEZWR=7DLEFO>L$;$17wpqwH4`vLSE6oU5vY5;) zS{455ctdUWw+&bIru6tBRS%y{**2J?>d7AC@ReJJe99VL?PtHjio|bm0c)We+tbZR z9jgQ+7Y{z%odV&o0D}2BHO>PDfi=t~$Abvi<5XDL>1_ZSR#-LFdOG{08=*ZC65rLL zc<6q({{epB$0IW!aI4BGRn7)M=p6wBDn@K!)d!(h2tI(I&`jeN1EQjl*8r)H0O(Tg ze-##cp)^blDDk)KKtgnb(3w>FV(bN9qAxn%3cMJ$P{z%9DORiHba<|@E>2NGO=y;BziuonZu80in~ zGMMH3mcT6O2)T{UpDl6|{!;k(G)t2#n3aFK+Qr7DJCjU*kp8Km^%DY~kI=QJIzJBr z7!up!1UE8T=;ba{U3Ql)D={Xv5SJElWeV3gp$8dpfxz3mam0`&AEk!eyrwmJPz$Dr zq%GgB<_Nd9Q_uh^@jNsC@+fm8vmka$W)I6pb;v9@TuUHFQo>>6a2F(JO*}U^=F)IF z@B({dl0_3VoOK`0me?~>2T@AOTYrf;u~yizyY{;-9n>!7(<18BFl{E;xX$PR-p9~i zjLmyEorSn30QFoev|)n*c7Jz=#eVmqoPnFAaz|V=yMxZxF(fT6BIqaWfURGIYqq^> zjFiEB2}ifMbN56Q#+hIp!S}n#ByC_hjR4ynztW{ClZORIX%W4p;_gQknf_M!+lJQp z+zHPw`3>s?Jd@v$sG{5^mKc|!vN*x-Q~i3DrRwek*HvK-@wCq@{K2AXCjQ_C_5<+; zCxT|+56%femkB(5L1TEjNqcE5Fu`k*WdYwuDx0WwzZFiU#OZO-$&+#iDl^Qa%;5GC zWC;FF=Yb`Lp^1{81(b3KTt)c%k%YQyTs>GBDpF91ZZdQRp1=cacm4oL=Do(~MX8lB z8$#-f%0nbf+$Ds)Xsi}M0SOEUu=prKamOPb>gtNsmBqvvotR>U1c0x|3 z>~4dYt$*g*jOQYXXMpcq`F~=-mZ&NwAZw{b?G*yqQCVz>0hKWKXoHCq{oRYTOy*;=!^KXF%2 z>y;(>tkwE(ir#l8y)TI@T8mRYn8XL3m!*{@uKRY49Hqj0H=!oymgOwMGcGm>5AO5| z5$=i^5rdV|hYAJF_B*!;>&o{Y|K5nxvM_*fw1O~EK)~x%AGDF!Uk?Zaz$5`PIS(?X z>k!J3mLYu;+@AM+{e3%#w1J9I>zrq5#$=M((kae$_iY-?P@+dA-%?aT;XaD zqabU&tYaybt3rlP^8qJMDa)5c_4ZGQni;?#dRaq7?JVPZ1bk?~lug!78JvX4a*0o1 zeh`NfF>YG&Vmz&8SLk^lIZ?H`vqWUl7 zLa!qUN(NU~J5sZG);p7vGpch=+rX2ZXmOiqp5?<#i^(tm_Z|UQjX(|BM{bO?ztx#a zQ3cByXKzdK(9d_3*mje{v@YoELRbXRFT+D>vE3z_mXc2oH|^`6#oMJ67XLs} z@ed>w{~%=Imf~6JP*SN+9TK2|(|s~*J!vUB>zcm2lB@LmWsK0-5}3^X(XYEW3rehE z7ETPaFreJVlm#PLSnTJBv4sbNAuw?)z*4&QG$+xmf`?`AD5BM#M^N95}t=iN-$0iEN^F|NHI9WbE^86Tf-N8UCU?DC7z|hO zDAYI>Y+^8uMe8NvSQxk>)fmYlXM8EKhH&swclOHa4cByddgQBSh6GHvD;5s*OM zun_cJhF=&SHwGmC$rvIKNjna=FVY8eH-_|Dr4tdPS0&N zSY@~fVu+pwOX*<;xozme!<^hroJzIG`!B?jo>=G;6B`?gVlWl)16|FKTzx9QrrKJQ z&dv$)!&LpD&wilQ-i;sh^o5@eZgcpD;p79uY5Xr#IZpr9+X_Ka;jpmfDwDoph7}9g zmcb^j=4Iha?>^%`iV_GZCNNI&i-q2UKh75vj4O>JvX!t`KZjR64qs}Wki+RlwjyRN zV>)Y%ZD1-Ogm~+bm;hN_j9U=DS5__zy=D$)sCwC)rJYJ6mPa(z;^p3#TCOmtXe^f) zHlrCjXbWJ457(l`p0-*mw35xbT@5sP6JB52;tms`D^#tAWN zQ*8jZ?x{B+TWFreoEI$c|ea^01?0tGPbCixAVUpWYH9&uAfW&B!tu&^= zz^$agUZug$@YV-znt%`^UgTQ_G(1mLk{jRkhjyVzcOxXim4%hMQB%B+TZXNTiaa`m zWQ7mG+jbWZg+|%0E6T-MdUePX0b=X)dh}Yb0WlUx4z0Y319C8qBK{gfuhE1*qlc?~ zi|@{EoUUrNHgwwId8gFe^{dF%r)i!LA;T0;2$5lo43azXW**7wR4#XQbx)YUi+S{< z%&xobw)^gT?71hd=INcp%X!|3i+SGluE~=pzZkm z+)V^M_2*~xmz8?{CgA|!LYZ%1578wHgc~;!zt^Yf7vAHO%MnsRcL){6r<3j2tI1V1 z9Kh7Q|0Hm%v_mf|5U_@VGA!)9(2=;Z=?eNJyeZh6q}v$(!7TxoI9(~9U}ey0pGw9- z*hN%7h$EzS`8a-s`H980SJ>R+@DHn#4{PK>J!W-N?;$!7;c$%Xv!sDs6&-+4(lQq` zwra4W)92g^{wRKDpd-$Y&;9CU04_JSg7>h`NHI!FLT@nx&_pw) zAMnf6?;l#Hmv;XKt?w5IhX<+eeh(c*EP4;& zp&3GNSPSn|W0+|xR59aB;rxyB!aVOl-FMeO!3fKi%KbcJ^Ddis?ssA%aI(@Xq8)^M zr=emi{%fo7yvRP>n85hO0Vz9l^ok%()~#wmsoptE8uqGKXxQX&T^inu?9d9ILxnS0(DP14d5n`p?>$2ba16`w$}r36 zpieN1lywobQMd)|$_+;nC`00%ipht#Gv=V72^v6zljDk~*xOqJfT{voE042$2bBNs zXBS21S^}&~DG_Gaz?BoCs-=KrEU{|&+<57$d(v$VaNQhJO3T8Cz@S%{4MpcX1Q0^ESh3mBUPDyMe~fi>)er= zHmqA@;j&{HYZfe7xMrEC7m3PZ1^0;JBGG-YUg1rmQ>O4LQLa~H!SaC*V7W3?ZWDE@ z6}?XstCi1u=Cim|^mDjR6xWG=8%24gDDD*fk8gbQoBug$*8ls~ zxBlzDzy0m+eD|RL`QGirXCXd^32a22+D%T)o)$ufm8p8piU-jkt0xt=D~#&B(j0n9mTh4GNv)$FaROH zEzyV)C?XsW-hVNUG2|C8?Yg`s32FHiwembz#bBPr@+Lh9)4+3}|0;Y1vbrf%eoW>) zBu^$~VZr}!DSudqfkg403It_Q+o8h2ct3;W(Y*h<{OYe4u)vJG$lpuzQhhuOXPkqP z!%L{-|VFc;rH{NSG!T{ZvWY5&C z$3`9CX61Kb)D&X|)La`-V}{6AIj=!RXe^;*tDb>h{GLlnNXR1e%Y0R(ge1ECBCyOk zc5zW~eTWS7(727+dam!A0%Rs8*j!^VVcRbo%mcQ@q{OoNQsP$1-Y)>&I$~n1Ns0HO z%I6!&b+`mYOvr+BIvRqUkPUsgpcigI6Dkzu33c!pyk`40@X_f7$)eHx7L6xro;4=A zp${+?)h3?`{YZZEPc`c2lc9gSj84NUbQ*var7UaGPvA+@mhVYNjg);HWg^#CLaK8O zN|>;PWcyH1hb$jJmj_Lyh9+o&`L}<|urb*Z_ zHAy&au|J(5VK(PU7~VziSi$0p(en~4vffCzPZwP9>58XuHP6AI)*xIf)O&5UdQVn| z@C~9|&aq?FXo{~TM$C}tuqQaAxY0!QVd&I+FR)f0TEZj>Nz0Yr>KKeLYb5E!{O%_> z7Uj2`B)uQrM97=%IMUfCwp@yw<+}BKLm#plhSv~n*XiTkp*%s(hqAlL?2cf|)4TAL zAZIDthc!kaW4ynZt?iAvAbRzoV7|?VLO&y9`8pbJB-*yh(X9QB0G1kcEtSJq&YL7Q ztIa0ddjy-FL;y|WJMqcQFRwl~@WHJktMqEh0+EsMyqcFb!CspgycTg`CV1^^LJH?y z;I)(s^B7jx9TkMvIx27?G9VdP1`i={N_?2ktLxRpNW6CJytGxx<~*;ZoEto_BD}WF zcx`emudOm(>s9v#z^muRJcUrxhnVqiw8SmOa!0bxE;V!wX$nunVf^83#&W0YL-0GC z!2+D=ORz)YH3V8ftO?7V$BJ|y)@3=lf||*#aO6+4i1b(0lx)I;GDDw^-e6{9F+OoSO^NvJM2)kUtq0ztQ*u{nL z3cE;4xc*ugf=5y|E5D}gr`rjOM9MZ;WL?7wbd?p=e!7m&IFTm9A0|V9i?L_ey!~`- zK#kc?Y|b-8W|=ij8KP=OW`@mvf|XKlm30H*ga56b{p6QfSF+Mp8R9BcWc|&-Qf}YO zS`2}77St^)P@kJq1*Cm@jS1k)f`Uf$i71x1AQy(o*!~iBmmq;OiylVTqGXKKuQdgU z<@&sfO|>)v6$Vtv)DqAVVBx85zlfpFE=`~Jgh?!RTnQ&r@MUcHGm(vI`r2e<0 z!M4{fi7DkqCCx~ItCX^qzp;%WS5VzXFRhEiuCckQQSV;CyzwxNQnT!Stsaj8a~ME5Jv}Yk1&6qE)RT$ z?Myr)9-2Fd+s%#VN3-J&%W*>^wFt8n0uX6rc;y;=AMtzpXUEZEPzIx>^vVmu%M4(}Y$eRIXRv6Ek!dbb*MqyeEb(6i`x2mPCK?9!t6XK}`D@cOzqdBSwGm z$LyH+D$XjzJ3!IWk%Q9(E>$D<6)9*zOStw4f3Uu3)r5__gbDPaDIK|GEn#2G;D{hR zN$H5#dK~3L!5lTRxxnDOgR=0Z7|Zk|%IRPnRoOecf`PSa6_AkmpJG?`i5#ysds15Mv#WJQadohNfM zs5NmqzPkmjw}D3x(I6s+kyA9(#Hyj+9#;P>{-J0ww;|Oj!0_qhxxiMs3qv_J3}qjQ z&>fF9#l%76$x;Y2h7O4d=oi=1RWx&SY#s^yC1)@#K-}Sg{+aUub{1Z!1q7>+Om4vw zLjRTnRV_(#8_EiUZNh*iT;79-QzC)~hBEO;l^79ytb$R}`6yzaZ(>=AU!5C~I7u#o z(&omJ0FUD14JmwZLxIAN!&7^&0Y21L9OUv5b^8nzJPq%ng6rKgl_DcCl(>C>lR;_n z*$KszacS~lfF{M;NaVxdS{jT(K2z}rIS4OXrFiYHCbFsO3n!84a;XZ889){VKu%LYV0?jC)yk*PL6A<)1`a{naO5u? zodiXXdWG>G8oD`4yU|Q+0Cl%QuJeQr>I1IXAhltl|9|X#37lO;mHxZ;^_Fx34US_J zM_xA|9Yp9TOAC(VUAK(m5?3-a>clGF{J-yTGrD6q1>fkz$f&LI=_vJxj%= zAb^edVPRdRa^i5R9RubpEZcCmn-t@fo} z^5m$1EGqz_$0wTsGFwB2fg*swS!r-~0MRUHsXpN#ba}cWD6Lg<3{!G)=y2g=qM!U- z*_5m*eg`u79m^_>Z8F$~+rLB={&puufpSkGz_+cy(CaCoSHm~CIOH4uHy0CsByW;o zkIsH0CHOqQj9DeyV2%o5^`sHm&&Kd5RCJ|;{!R=1*(l+W81pFeH{7{I1thG^-zb?+ z0oo$~3$B2G(*rYiH(OK85gp}2iGjJK%J9?6Igc53vtg>21 z>L<&E|C3;n;qXf0fJL^wp1IhKy6bg2mwfXQT7g%NBR!tt`u&ru-8(QO#U$-{9U{&`n8s#Z^0mwY0ym|7@V2KAl3!Mk8raA z01TC|i!X(z74`XYVz7rJFJ#<2p#Zf?kpOiz_Zx@t(n@K@O$B@)45yHBlO7=Ya%Bv; z`_N`&$Ix$Mz;1hL4E^@R4yj7K8SU~X7Cts#TU5~&<{|-u~e}KX$bfFu(Gk_%s>%o#Xc=Y z?R#JnXBXN8#r~|>V1qk8*=IccZ~y*=f$fh02;q&flfpp;%avO$7neIFk2qWxhC59U z3`+bh&I)SeE#hwf={5h16M}L?@QpYi_*MF(|=u6Rq z(Yol%(L>S0(Ie5L(PPn9qV>^NqsOBsq9>!TMPHA;5p9UR8GS4IcJ!U-yV3We??)S> zA4ETleiZ#U`bqTD=x5QU=;zTdqF+Y8ihdpaCi-o(Ir?4n`{)nRQ_&xzr=u-VBR)Ew zA1{a(#*5;`@sfBbJ|;dkJ}zDwA0M9(pBOKTPl`{DPl->BPm52F&xn`DXT~eyv*NSk zbK-O3^Wx$7{P=?S!uX>2;`oyI(s*TjS$uhXMSNwvD!wYdI$j-rR{mWRe-8hy#lP$1 z-}UkJ@#pbxO?*RqWBdjDyD7dI|89wIjYs0!;@jgp;ydHJ;=AK};EK&nDMvXf~JO?C-_+ZT?IeW1vON>2xlyy6j{iJ}7{71B4U&cN& zMd`!(`-S35l8odg8&TABy`|=F`lA;AnKv0@37=c zED@g?bOtl>L?k7@eA+oYsFCKKvBx(&rVbJ_iThh`@e1Khz8Y+XPVAy`mYyOnBa;T62%*FxpNvx3FL{7~EyIxTRM_-c zY=ib^G2$oJ`$r7no>ynaFShAQUVdfU`r_5a6gyd&B zcM=J_&^?H8ucS?%JXj#FB!9$crR#5V%I32eCDPML?CEH!SnHOO6Is$=NryXgB+a%& zDDpi^(bFvQeM-?ESwtwSh<_0FBE?U+;xJQ4LMPL6CtLiEExO5*k}y5w!18o6p9Vz!mOm#X4+rx94NC}goIE06 z+{KsvI?`49D;$jKNFLW!dpe(>ghlK04HD1%OBQ8#7}59(Elu&T<5~Q37CRnBBm>fW z`QlC1<$N;;J$I ze$+MioBSI5A^IA14UVQUNi^I>9Z}Gjeoxx`z8jH5U4J(A^5p2ZH-KeFU2Qqf504=j1iz0ZRx zO&@i|0aPh}#FaZxrSxG}>eMGGeaMwM{Ygr{>`G06x}Q+2V_`uaKFCrB|L<7uOH$9^ z|1C=%aIf?5b4u=arD+Z7i>}Z#s0Y~oK3k&qk~WiX=xj+;G)f3lN{v~;25YrA#RGoM z;(J(39sn_qdGG5|J>nrgyIY&&)Rw#ai=5i>16ICMUu0^F0mL!g!3R!n`97=Ou2s`| z%abg>&Bin$W7-rLBMNdu;)`$9($t8)&9~g5Z`U&`$xno)Kc)66oUCm;zrW`18 zN$Ow42M+TWv+Am`jbka?NxIl{T0pC|)Kb&KDtOQmk*x`RK|q^JDrwzuuz?`P+G7WJ zG_}fGiL}cVX>Dp9u~?2mT*hK&5nV{!tdxpo5uMMHOIhMxCao@Ei7NNbGM4g-U3qK< zsgz#iN~_610+5tm$kNtGImIId3>FEtQw+#qB$aD(JIulo-ytKIQ{4&4xjwfiOFur4 z*`KJ#`7%aF&KkC6By8TtQt9OA1Q&?Ht1!0tJ362<$38oE1TGi(?m#X%`3U1<`^)3S z8C1Gl-a?0(%Nri;vOUR`V((dw_h2A7E=mJ)oQg$9a)2y79KeHnW^7Y;;-8!@Puk8s zI;MXd3HJ1{jrz0zgUDjHN-{EetSq=Sf18q;=0Ao0DDf_TLjCbMsqy8=cq{Z{r;YrY zWPH-tCR8GSL>bwB`r|Lz|A}Mk|Je=$Nsa+-#rSdK)DeBS_f_0uj}wUF2?R<+t^65F zma?Ryriq7t!jj`yLW_-JUs@sA5PeMWtHP2~*S3^PE+LjX0WPJIMTn(NfJ>=n2rA=a zPN0Z^lo8-L3ZF23M&_3Ek2tVJ97gLkrq>t+^?I9@v?Iaq5&-5W8Up~wda0CW`?t=37VmZBRS% z`M(^xH){~VRcP~_(8gkWm~d(IHs1?vte;Oy8)q?<^|LXwv3}-B8&#&t2UUxYS>ga2&V=2xMO zjpsjFw)st=4KpT5^sOIH{vgKYLYp})`}uunV>pmJM&A2Fyyg3ODzvfjytidPPlqP7iIYpVvs6(RkJJ(8l_iQGm@1N6)WU6xzJ1Wj|+!HU`@( z3jO5Q+_|BR!InrHr-YR8x8cyn`k7wnCqJGGLL2MnWi7{ZQD|fRFsXNDJGmgUE(vX{ zpF>)XXJu$(G&a{5*sct1te*p<&1kf9RiVv`@~|cOIbB_7Gtd&YYeE|v z&wlxS3b?*Dw6XE*i#Fj%rN)-5q4hWw4_qV(PTN9}zK+HHa@@Yw&Uk}cSb&r?ei!3D z7BE+XYbcqeuo*wWZN@Wm1EWw@VOJlA){pG%ijqB&KB(rrL#>M*s4lqPH1g#RzK*#a z_+-oO3zDA23vmwrZWd$DJXI>?XVy3K4d%w2EZ_rRjYrQ`j5eMpLL2Lc=@&*bgFRoURGdUNVjhSf@XWJOzfv$R`$1Yt-UH;9`&?(GZ(SVcjv%l_Y;6&%LDvxyX ztOg2r$d4CbHV}gw<9O*?R$(`axm@BQCXr$86l6qU78f?)O_^+PT{mA8FNSsBe(7$E z#?|MzB9o7Q6610D9qu`<(j?DmOK!X1#xrh(w+2D2(<(K)rNcW7OM`=!zl3 zdKl7eI`c53W2hL2XJ8zN6QN}TDZa+r{=|oK3bcHU?;I_JVR-|!Xho3IBD@bcWJKQ+~Z#kKzX z=js`Gtdykjv!k~l(x^S@9l{A)?Cl;9Gs_3o8yB7Cvf&9sp8iDbpWbuR_jx2RY5eF^ zeF@f$WX16L3Q4DqHaWdI)%7VQI}`26^A^`S7m5lY=gy8=n0~cTOD*-f+!8QqDSNdZ z6TKN6>?k53p6>nu)g2Y`wwQ;@ny|5<9IiPn9>xAkvY_EBKB&0nJHzuu;rUv9j$@aC zeVGwxTxMexQ6r~Z*X{v&>HaIdEzBW&>pn3}Uu52X%#(^Bq@G~Xeo62%d8eIrMh3K= zUGS$#(2xaf3jTQK*mM7ZNzm}eG-!M7g-gfq$FoCv=NN7s8{m~=xN{7bj_Da9r11Br zh+fV7{kUz+-8IJB#(3EnP7_J?{UBhm1aq zWd3^4NKP7gVymyO6fl#PvdOAR8@&GI9n> zUe4;~DIdftR`FdHWT#27#9ed_L^q zm8YG67uPKsycBlg_e;Zzl!|gg*qrW!QtqfD1Yjo05qDp%DkcdT!(>lnDyq=CCt1S? zy{Hx}eV>$O6pLCLGr;k%1f6@iENQhi|HAh``2It0EGLTI738u+&b|vRnXU}l4&eli zh?tIb3RQqhfIapBOr|tMaVz4x@R|sjEq)HHeYUP)$euFtm89177ZV1Mpd@5%45aoKnpljLD@( zPszLldLI8mZtpDg%o-~R*HC@!5<0iv1(2CWLvXxH4&(`% z`~1}miYJ9k5RfP4K%OWx5I}x{Ak&qnNS4P;o89d}mJI5zEMj>=T@sqVoFGpSknMK? zWT>%5U(7egUCW=c*E-+Hpk2d2IsfR}GS!4%aH`Qq**SQjOme`so{ z4FM8Ot$Jr<;FO@(RHxv(v#zOTI#)K;Ot)o44c2M1G*I&H_f3tZPIfQu5qLxyQ0(BE_35srFSBY$cZlYX!3kUoHV5zBcB3BITLp)}AU|W3wDZHO-Ta^?0U95=` z!8d#n89CFg>FM_xpL%i}yQL>qK`zlx7PH14MUdMy!F?}zV7u@@NqFB|QqvE@@xUAS zPRly0geE+2RbQ1y#U%Cn^9WO-m*q-zagQ2Zy3-5t;JK*DG^w~Vkx9IimyrmJ&S?dS z*9M+wxPeI&vu)i9+cPW4wBh8`qnElRw@K56?I!RmbyWap$YHX8X`>>jDxzgcviIi* z+|lA>_o1Y*<*u8*MrF1x=M*&c;`P9YI@!R9jjfWI!aTL+WzQl6a($ z_&7ZtUbnR>;XwSN5`Gf;kc)1s3xHYyQ?6F!IFb1j?__!%Z#Q7r{yW(xN0OV8tHS7y zRW7Irdca}92{0qfXNpk@19bD$mK$Zej1ta08DYE3m?VIw|F~^Ck5GMT+si)cCUXUp zP;bPhkT7U?%W6E4Cv2McTS3-NifWT|OXfz-oqC@k!rVOxa&H1;%&<`22HsH(o6K)? zjs!eg-dEBQXJkV}HY?Mj0#Ds8dVQBhhsrU2&v7a6^1|%)@cI=xjhcr|p;;b@jvxmI z#RX0kgnbW3M}o-+fo^sMP)&FoMIU3_q({hA?})-cC((NB_BsrXG=U|ATbbw48->*e zg`b~up_1ccPVWTOFR0G5V3;0fzMZQRznAOpfU~>8pv)@q+gL_*c$}%r}-{PgOh!QpV3zio|=dvI!DN#DJ!svrA4!a zYG@fxVNtKsa?8* z7Rm2SR0s^xp+M(9lh5NPQ)7X}DYgdTc9leink!5WWjJUgs_lHA-IEu?Brd(@5P7{5 zRLl57X|-ucc=657X)f<|KgRXmWc6=M{f^yNOPky*I&W3dqBp~SX%L@WA_q@3Y)Lqv zIF&>vHzS0v+6kHr_S~>q^g1f;EM2H@921OzI#vYg$m|xnsWHNvonts>hh{6<#EcLo zl{n7bq}jQJX0k)!#Wneq4mm(L9NHLf3w&xtN0S|jz=N8919#dT+zGoF$P_F$R?u6E z8!PCoC4a<5};&c+;sl-b7uj?yjXkx;M|7cngK)1Fw-ar4>`|R8X~YdMRC`vdcZS zT2lcv02V;O#05{Ki;3jO6ojpDA)`R$P)!Xbc|dI@|3HeSEyggA+%LKR%+Gy~|4oAD$QTFryqTrJ z-xC%zM{_St!rQSRl98}B)oIsO=Z@dRrcb!RXEzivKQ=`^F6uZ^E>9ub29E|1O#eq( zZ8Mfl7T$sGhC_Gu)mQX=*!?FMUaR z$IopbdHw3#FnzXq!`j%wwK2Y&qgWBUx)qVyLkHzFSp>^-i+}`KubGX(Y?Cylm1^Z{ zm3!eLg_-}6G6iHR$r*)SQD=&ON-f%+_PeM3{wepHN#bZCa+WU{^iL%kL!ZuYFPY(= zf;3$r6a|&Oe34_eWL}Q{QM%?O>XL>Z_d&w@G|4f9uQNwEI;ztKzvTB+PLl8$2f8DPQk0U5Ou%olXp$f*-h^YN1nM7Gv)8xO}JTeawxtOFJbB2eebp z#z5#)ZaVWQNEZ+hr-dgv5Mu7O@RkF7dAG2bcpo$nMn zAh&j^;ue&0EbLmW8&I|4Zm90&F8j++qR-B)QBk4?{TiL=1yxFio-rOBdR9?~o|)I7 zp+{Hi3?flI+HS&|$&9Js2(5ML0nYXGobWoK;m4NKrKh{qEE=>}@gxAeV@4AVI={x3 zg?FEu)|ypI4q7vog4de+$E-CEWVPlE5CUF@ms27^YZgt^Y0arKysC*ht$DCWge2eM ziyeG*G50G?CqA08T-YLpZLq#|EOH!2eRHRdsC8U|R z3~qy>45xu#{vsb!`mWQVN>yBq599@k89f>A@b4Q5yro|Hj*ObDLO*B}=QjN071ZQ& z_Q0C>znPO7EBgOZ(9%UY7PP&BmKqX`WW?UeL;ts+C3rweHU<9{wB)XL z%Yq%SW^qa$sBy$8AqdqXcv6d{(mYNHVIY5@aY}yle^qfx+l%W>k5ihM ziBqzeVC?Uu;*{V9$iyi@-V95qMM<2J$Fq5NxVu0-eAGB4x48f(Fynd=))RaVw;%0a zdCvG^lS2G-Dj-RA9n|@(A=C&+!oh$lVcc<%NPYf!Xn}2Z4IrXO9XJ9^0M2{_4dDw)Fr&7eW_!il zuD5+B?r_0dM)dQm2x9#zV%Q7dR{Ks18Xm%LYH+CEc(M*$OeW`AuC(>z`~CQgcE<3(jJNev;s1L#NWqJ&`a5QlJ@q&M4C7j6k3K zYV^skJO`Ta1ZTh>8{G?K$P6`%TAy>Kuu ziNL>`Ng_m(h!kcJpT#20R6zl4S|aNGmL8-7zsun<`;N0?zRr|f@Qysm>DY@J9_-)i zL}+{xWV-4VHHj=?suPJ(lD?A~wue<%Q8|AeAoDq&qkw zOn86X^SbO=jz;6o9E}j!qeS~5k&PZ9X9R32Modl!Qfcmyh&(e2Y( zpXOC=*68O93ySn4g)_ye4j_UL{^$&<__ZEq% zw}iHb(8_pHCPWtoDQ84__{Be!X=U4Kl?mDwU;I<%H37-e;*|Ho3C=I9J@JjJbayeW z$4XU~D*jVd@$tu3^@iz3|8TuBYy^&kOc_;ePw?KfshV_(Rf~gAO`av(~(nS!?*m`>$XA zidVdnH(*QVn%BPW^>3K@M*O|$O}qyCt#8wdu>XyDYu<^Qu;ni7_q-PgYj7R5+=tCP zHTau5m$zbn?BjYb_NPAe>Cb%Th$D`4cVlO7$L9Um*&DL6cVuU8$<}+a&%s^UdRsQ{ z%hnsSd1rRGHM@9kcDOkki%jKcy{ni&XMK)s;l3lt(jk{YhsOeWSb-tAywiy5b(x%> z*WDi~7WGPf;Hhr-9My)VVIPzZsc+&@v=9{Vq#@IU?61dnx%Bpf9>+z^LlK{2KUFz@ ztjE51Fp0Ms=|Pm`k$7O4E$6cti10qXf)C{OA;2T2mFV5C^FSQ#7(z(p$k5IPk7!-~ z;G>@SH1IMW)Ds&XOJ7iJOWq_B&8u7D7YMEGrj~R;#*IK+K(;9s2_{}dJw^1yg%ogd z{}B*L0N-rqocRj&C|(VHg&dC4TEL+kajvyXW&<9NyHYUZnLkJDyc!e)`S`Sx!$^;x zC>qKY@`7oV{p3`)o8c)s!wznw7?fl3auuQ6O$6KmQ-;`AkO=?YueiZ^eb1XphQNvnIk++`?PEQbbRuLQ~4lF z3nmxGgalX2PIOA@Df*G*YxVE(g}B@UGzY-t8biJ6gGoZwTBm3ydO|E)VHY z$X4zq-qKfea7m!=T8FgeP0lB=81~9|8%VyeKSiSD|*q8qXj#6&qi%*vf0*<`Szt^V7?Fm3hg^&ztQmGkQfKUtF)+DvAp@-vZR3YbQjv#)V9 z3$rAEJ1Sc-1->^B43lP&U?j28e0!O(pCE0r)bkKgAa`##@_B-wG^}-wd^CNtv^grQ z22Va;=gW@VD(ZP8pw*~{@7Ynr^Hq-V2w5{EzOA91^&IPGh=ef^EsrPB?O-^8e_&TF}k+IsA{Ksw1062*<~?Z7J1A3#RVN zGab27c`gw-Zl3dlfKj6wzGp{K%|jgGf617)mTDw*)_)QSW2TxPhcOz}e1z?{jcOj` zP(GxSF+QqsbkU*m>;pD$gQlCxjo2U17h6?LE+v^?-j4?&3ol{+@5@v(U!*)?KEe!Z z>x^ohWNk~??mc`;cOTA~sk%gUuaiHN^17g0Ac?$)#|3P`i%3u)toDm6c$aqI2sI<^ zr3KR!+RLHDhzeF0(B8?ukqV_K99@1C3P=53_rh_}(RuBd@7Ym=dM}6g4vb*yMdLAi z#oLL5F%#-g7^4xYq*wHWYDY{nIxE)EAd~z1shgtnXr$AJd6Y@Jo8Va5MMtmnyN;?e z>x8`xXfTZwSr~0jX-LE*sB`(^x9Viui~DF+`Lx_;vI3);J%}~PcjQPCBjf@;l{}2z zQ%>{2#qgDx4`&24nOpiz@^agkMUX;>A*i3j_s>jq&aL6t&R|MbshMfeU>y-S)M+zQ zWSHjzox7DLfOC_VngHmU4aQ|QME><*j2WN?$2JV49|bz&l@B**`@XU><(1 zyO8*@t2RM6$>-Sc6=;Y8Axg~5><9l`#C%K(~GV|otbCMhQ3cX>*1rBi1N7J#_gfSW?kxZ7J zli0cO5>7(7xPMOJmg#g11=A^WCpom3t`ewo3}phq0xgJ>hV@f4k)F3fn>VS)q2!tU zZ2^3Xs?tkr99LkQyi?(h(8kuuK?KfcjbxiVDclv>SU(38+T<_)SzBl$2_HSjDueC5 z(8gesw2wa1Wf>0c4{Z!KUSiW}jQ9l{nlmQZTu~FK{L6*rFOZ>)hQfzK8v}D{p-tXs zeKfQ&F!z==qrtYm&}OefKl$l>JhU;`_9(Q;!}eroW3ctMgzX!JHj-v>)am_ZXk)NR zuEk87JZ#?%Z45Rh?ZR4;bz}YyUqJN?c7nM}#1DdOU8$wlhiJ3j3E+mZ9sN^s3`xS{ z6uK#3!&T$Dzu{A+;XwvyVYZ;DU$Bg+xm*KkfK^-Sa>eQ2X@8DQyOx%gIoY2XO~1pp z?Aoo0?Jjs*1_k+5{_6q?BnL{SO@77xw$Mg$pJY~&GRCkJeqU(AtUOuHkZz2D| znzph(t6&Y_r@3Xz&Pumwu%rfRFgqS|=}4jl(L!YfsAH6SeIO@Lt>&C!0uSW6X_H^v z7totl==x{28>q0U#=HrpySvWZddS&ylx92&SF=cZCJ4bkxS2)qWnMl;3GgZpc0jF^ z7i(3S{))-3@JJRjkBUl2fX0g4ux_fk{#uM1OBsmrx+Q8Gg^b}ud7k7>Z}@pDoG8Di z-S5H1)APHqVapEWGP&aDMX9AJk!;8j2@?)k6mzodX`jPxx%*m8Mt-saG0dd;WaP)V zKjpxZ=CFmr+G+E2m;IR^(gJMvOmI=m^Vb@QbtaM+i z$-1UpGQ>lof!KUXwoAR_`_g26wo7<5arcP4k+@G*yME$ijr&?nHZ<*$k;4*m!Y+HV zUG|V(Fv^YDF0p^stz|mO5!X+gtaV?j$)=`VlG24P*}N;;rLcN*xjEYh^@n1LT+|znY1At6?bklfzi{GLCEFN&4G-^ z`VHicT%Z|xcg!)hp$xKY!Y99zTLQ>k8`T?O!*nR0dv<=qH?cDvY{Go4z(zmWD1R*z zMu{ImJTA0`m)3he(OaokYL#6o71@>B9WRjmN~#}x0oK>_TFiSrV9gMpvseM@Co5pL zkYa0ge$T_(^)$vv-09921*pv!dtQLrvTKRQpDpJ#9mC?LV_^EHT6AFC^|CnA@siN- zY7IhtZfdlBaiVvQrAFtrO}R-;T}=$SS;EV?6qvWVs?ur}_7Z_>WXP?PVwwAe;KNKM zg68Nb<_RV=noF_bw}xlgBLPmJx2GKD?zk|Dn{>~ZoeAUTlmJ9ILSgeKiAQv* zV%_e9mqUgzLjj+|i(Bl7*Up9cl;Z>j zYTnUUMLNllmmewA>O)2(5V zn`qWRFblYMWQUr`ctkQ|i!V0NYOv{4p> zAgsoFR`RQJIP_hx1AfZ{e%nj_1vv>x`233537Tbd(quCeQj$l-v)+ZKq&Kjx6%#cO5Xds20#P#nzZjTr-i|Juad*aMRcO#zz!WN}qe_3uM0(Brr6 z<6<@1liK2>wgd*c)S!~rOP){C?Wj`$qrBwYkX?dBg5R@!U}BcXT={}B_ORlXH2fHU z*SSXpHv_8pg%CI(X7~-*fKdggQ$|4Ao8=fdGA!>7;{js=47_g>N^#{ayVc?ab|lR7 zVFvxsJ<*ob#E-WpeoHEGN)1{xwRW<*HV&(;&f3pGWwAtP_)yF#LrPwVdI_?^OEirz zZrrJ$?Hn@I@5|K-e?#)^lbRuu+?2AwkjYRi5duIGd8;84?Ni89*FZTkPb(l(nSKjo zB0(c@id3523EUs8kx4d1Dd3RVhu@N_HG@odOQ@?=LoG?l>S_rprPd^Qmnap_LoH#C zp0LSS1otW4t)e)P(K%t{#$0s5F!EC7A^~MixNfcl=CYwYX5Wc^z*30WKQHuc%taj_ zqqR9dv}xu5DfDw;p^Z8~M(gL|LYv?KNmAEPf?GuujsFtS2+dLM!I+m?MuoWVO83Dn zUorfK~ECjYdJy1qXHuKW87miZ9AM1ohmUw4W8f8q1#n!f{1ZdP9dlZX8JLi_1!6BzL zwRDQ|JP;Zyi$unZ@Ovj1tC)LO3|teAd^urGUk1G=>yNp|RinD4J|a<$$x%c`4xowC z&<0WGUhiEQ!CLT__^#!`a2g)Y1G!78!n#`$(6zcl*f$efId7^AR`Zi`03z09u{qGy z>nlLjHgb}Je8RLYYHo#g2aQ#XX8yb|?YL z+MVXUcKBtdj!ubpCC1R{;(Vv7n_^nhou-Z$VfDJ9*BIf+6JYQoL%WH^0;PVbn3365 zm^3wZ8YZ_W!a52t9UEYJvLcx9N-Kb}e&A}sS9E3v_o+x=Dw{c6wmb*aH2KeR@B#Gs zCeUXTS?E8H_k&L53R~QY;Pg}8i4cPSYrXjE+hY$L0bu;U3;*9=P5?|}_&P*Ea^A&dOMcXNd6!n6L)!1Lr5gYQ@6a6p;<$PMw%65E0ukHfiv= zEXK{8Q7^KG^mf;&ml6)#N*D89AJ}Yh?__@BbvyAh|GG82!Uqu^wHT>3+IqWdlK{qK zfUpzY0obcQvTsr{iC1|ZjCXT~R3eEOwEJQ%huS1HIlEt4c^iIBd}-xyd_X-Lj_?Ur zAhME7Wc)6373gLuHdRMpGUqtfaSe|l<5(}^>pQrXj9+ucX^Y#fu;%WMk4y;1q$u`tE~H%4&{n@HQ9 zV>~Hzd83YTe{`w0(HmRzULx>Ty9oDLm@Mu%i$yaVGszPIM2fJQJZTO`eG^~>-CjYf zeXY@IG@4d9ysu5HeX6tj@_o}PZ|iH9B6`xeD;+11M0@b}KGG#R+a!L=)U*rb+HX!h zem5NVqQt`QA@`dkfZxMuk&oYY`IM3Zey`N}fyL$|x~Nj|lTq>F z@B`pQ)k-5Fbgii_L|FEOc~(oglP@-4in<@}GnMyZa?s`Ba@eF4i+f|NxOq%Oi5}S5 z2PL`>k6{UA4D3M4aEt`Au4t6L0+n1A@V!Q*Z2bYI9T)>|)`kDx zk?0)yLj080dF(}e`p}o?>Tz?qEh7O7bPn2n1wPNKS`Oyw!e9ub8_X;>m|=(~7SEx( zD@B&rh|kO8Yr`9juh5mRoFX-A+f!CuAG*9*XG8)7HkNrh^Wd%tZ4F$xYfc#44g&Ya z(B-WPF8xf<>53|E(_(K5P`AOvm{1Gs=H}3exk$vtWV(#^=oi}ET4+b7Q|F~MT&LIt zjZA}C@Cp45TAmWQ+#muK9@mx2x|OTU>4~3U_v)^rh^N8RjwTc!ox&`jJz9kaSb>fo z$Q!9JQ7W)!N|;ILnV*vh3DcnFH|$5)UiY#A=mxAWYI8&U#QJXV6Ow2>KaqrP9X~OE zwfuypw=(KkoZjN!AUr^~``6ngoPbp@y%x`U?E5-Ck#us4ZuOG$o_vMj{h<6BSCL+rywn=%&g`O!v_m9 zs*W$`3MB>Q+kCmuCOE#%c^(X~zm}8dFxd{T1eb!pT2n8tOWSF3NLwv5J)u1?ZJL;8 z2kF^toXqB_Y(10xnt#TDY#_dgb7Eo6W@9Khj62Dw$2nF}(TGGzdz5qh29Q1;K*sT@ ztN_)&M0yT`PO-+d{==;Qde-N(&-TrrAaZ53$-==UZ?a%IOnvJl#ggad7Y+lYUMDXz z!30S=h*v`p(}|8nGb6h;W|AxFQkcyy$OiQ1jIc0f=@VHOvvpYv>av)n*6B=L3^N!s zjMnI_3lJ+;!za2`BQ+v}F%5!r4-JCE+Fxf()@#i7PnpD~15_Mna?+LYPvXjG7yI$m zsF=dwmx)2fumh+EKtOA$D2N3BoF-L++ohLfY7&&ZT7100QdEmy1(@8{4sIMZwb;&j&`HC+dO!-~gQs2!oY2I7MR%PSpuL>? z1wmQ@kBkYEF!XH%1&V4j$(ncoQit(wE|Anw~^>9jbWAlSUeUA{Hh3og}2FaDq_f z+yo<~iTD&rn_sTHa`z?d$wgRzkf!4ogc_GCc=`-{U^xwDS1s12TeY?}-KxcUcH)dT zf`J&*t2Tuh%%z1~;Or1*b~-2>A2U=noXH%tfEpm+_>eii@d?PVE2hg>sjj{k260f9 zw73Vx(EAkAGYr|XqLr!3tW!QK@SC7FT3vY@_2OLzrg3Dv3_~Ml8vr4YiAh@iIp~pjHVT^ft9p0?A(( zmY?Z+beaJG!GCH#WPUR9;kZD3Um$KjPw70aPG3%%((fV%cp-6HWP)i*zk~I}aZ{vp zokd)RDonE}rE`m!ex8UFMcO7&;{!r$7Cr*q=j0QnY)4W0Or`W0y%Xz%4qhI`BY{kd zADXRj_Xrz(F}}mOlSZN(_kX@3u^@g{hj}#dL)VaJqkmHIb4^n=%1DawiJun$4|{ai z55z|wNUT)+&{N!Nc%$nIu?%UVx`#w14xJLQeM13njD+xb6Z|`#yQ9U=7ngr!xrKE`i9+6)l_)7a@XyFJE4o{>l}z*Y zKs3fQ<@`%aW_xF$ox~)n`ih0&jPg8_zPr%w8N%UOG558FcEv+4p!G(+zxxX9^x#XY z{_Zcdn=Eir+H&DH8{d}-?dSw(Exgth+Gz|(tNtD;w9|tyz=ikXH-q(&LR&S9(N-fA zM;Yg1g|@*w{>n}})I5ekyKl;%wQWal&OR$_JeolZ{5P>uhjLabcP*M)sdT2>7REgC z)fPr-KdSF7bHANzRFRilm=yk?3#tOp0ZcJyt^?$3)ReZ{(ng)3YOZ9G8JCSJ#wm7F z#;1L8qZ9k6W@m6y2(mDvI8aHh5vijqUo})SG3g|pvogl0d(l>Wp3Gj>t_U)LHU|~5 zt&j=ZYGsHei%o}e-HY}ugrewPJT3L?ED9+{pRFh?s9q;G{E9Hu3ypzmvtaW(Vqyb1 zbI&1Im0H+E;%sre5||Rc$sI^B1i)Lk`v?L?IeW-k{-+u&MazH6xK#*7VE%o#81(Rq zm#bckNyK4IK^sk6oS93jUQ~B?ZGyJ53TWejJC8OE`r>wvdPNLvW!CRjp$(c{u!7EM ziZ&iB9iPU^c+#D_B}SLQMP{<8NGc7t!lbtntmg+@nZhwP!Fpk#-Pi={#f5fb6RejO z+KpYXURG#3cENf@p=}VXH#`%9wfoNy_ydu9Xi?-M$>%ddn$PEkM4!*!dvC`1NS06J z_gT zD1|X^a9S~Sp&sk$6QA4FzVvHh&uy8+Dk&Y+;;gid3vuF)Ai|Rc3(l4B7gxO-u^eH{hA#Y+#9k&Rk zlMFcFbnils5+*+d-}lVU{Y#{XV6-hJyCw-36u6rkCGx{&p0>J$maNIU&`)c4!Ztw) zWeCVwqpn~aSr!t(p(vpXK{3dzqtrJn+Mc&M9D}7KbyAg*lv^9x1tcjbFNlOQ449%M z9WAs(r{0|CAPOpTz#yH$weC7MP4u8e%b9@OkUHkwE1fN%W}XZI1jR6B6C?5!@wqg3OSPR-J+anVo4}BTiB^falDY(d z-2u=N*6cjV=99+naAC3$4xv0Cu1&Cs=4ThyQYX@bVgrCg&MBK~l;B*uSV>$IT9c@C(5>RB!pbB#vY@WpwDME-6im=@j5CN+--OyI1j}4;RCBvQb$i6YWYj#zh4Q*R1svbEhPr)* zBVFB;PF2s;P&e%Akxm&fD>~wKp;KD%65Y<>l1_n>**c(^S;-0c*hF$drn)_mwB)p~ z2cy$Dpi_2+J)u%Ml?Zc*cm*JyyQ8W_Fa`R$HcYe8q^hu7hR(h!Yj=I2ovN^IzRWLF z=x``n$2vE~u_&OoHkC%9kWB8#1(K=LgdII0MEziIK3fy4-f{Tijo)EZ~8ja4g%Yx ze@BUv#E@I_3mbk^w&sZgR^+lS97kGGR$blYP>EE(5jR4on#GW`w9gSX)JAd3rH*CX zAQKS*Df_JR@Cy&oFSWe6z+xu+2GDrlBY6UTuT;ORKhC|{{bt0mqsM-H$7&Rs9>90? z4d|H&ogRD0NK3wzfk>zwR?6{Vv|rG;GU%esk+UpRH(a8+AqRufKuyX(#c!9hfaAr_hI=fbmqL=Q#(Y{BgpC|^GE`c0bxoLv zKU`9RQ%XA_-4_1nz~D(G*)fodN`TKMj*3%rvV`0Z!HGVgZAOm1<~Mu`qpx0M$O3u6 zcE_?88)Oi3W8Q42%6KG}fp`s|nYdbXNSHIbkiBN8(2MT*O7;&xA;2beD4!skf&Ct=-xuULB5!S103$SH&@V$m`2z zG{vjtt;yh(P7<-iO7MDS0k6nCfI&6E>%87r(srn=)ek2Cgh9X&qddesA{zDdjbISy za+s#CM|XIE#(@m}vUZ3xl*t$z18F)IJ1S`c(mrGKO2o%x`P|Iwm*sQgUt?6oXghPPwSA5QelWK$3B#yLC%i<3uRW_9?-y zE;Lh5y2ELcX4e#&sTG1AoPclA^4da6?@D*NK$DiAFSPWIbf-2nX?a7TWw1rQ(E*V& z_Vcq4DbKD{BL2yBSMB(7=EqK))+Q2Tc}`-GOhWDzF|&cYAzB~aE?`WrKc!Hka3^EX z31wZZvUmv$51&bF5XMO@{uB-tA%BTDE!)go0moAHzTI0XVz&2?Cg!QJGFSb$2*B@> zh+$ga0I@_Hz;TD2=!cu2hY$EE$00gs2p~KkIacvae7PJ0Eo|9lg8?C9pnftjnY_3* zaS=Xu8Pd;o{au@|pchG4ZM5Q^f#XbG=57IpGyO=O4~3shL?@3~lKzlZnN~`txlY}g z2{`nm8uveWCIWsv;VSBl3uh_RE4LF*b-+JeaB6j-xwo0Y{W)eT#6SgD6$1-r-~$HI zbbP=R8pwJOQUO9UAS|F$I^R3ir1K!8H-l>`vMf;Ck~-L2^{Xd3HD#R0=`_(8fhsQe z0d>L8(u2!0dv}t(J2@Yr&KPxisW1wRj6Y3vIu zo*pwL!{5sy(qneCTBCIHGw#$)%7^5{$uO1Ltah40S(4 z_}N_i0(YB}M1mfK5| z3=DIPkwMPz_QMkKBqOO%f{<4!-wJbjN|@6Oe{*zD*5mIW+lf13`A2{Cb zm5Qc%aqdjorjiKS@@HVYO_Yn_9N*&+AK&Z^ayz+(0-PL*(G^Pi5XNNtw zS#Fs?ft1zL#c3MjYjG|DG8cMEA1|K3)KZ+cO|LVcgho{t?!)VwXh$U(oWp&nu3Ep1(h>jHCK#ma?B(Uj%EUKUL*2rVNmURM%kT@V-0|!g-jbO zw?jwHY4+6^5#O(T7g~Ybw5ef8<7+!WH4FL_#%&mO+1ffe4bY_UOs1ienLgY!P$5&z z6$78GvoXDZ|78XIBT=Wrzv8)SyG$Pc=u3RkvusZlDjzu!H6G8^^Aq8;9ZrPklZA;m zx#>hurO!X?Y0d%6I)R1jF2~p*J@JiWAunvrS`y1mxoEr>_<6~ zT-Ihqp^fU*ZpD*Iz@X zBMHG};(_uhhENv+4r-Y!7PWv7u_KWlV9j9HJVdG?kzEq^0d|5-BjLJ?r{XTRM9RRb zp>{NZ9Fwd8cVM%ZYWK7ayGrbe4%$V(d@FUF8n6CHMeG8#vLD>ZCcwV5SXbg`wG zvU9glJ9K18Uf^78!vz=H2?j`!F>5Me?;o;*ra8fyo+A#Fj5sFek`M(*E6Lo$#YjHl zut<4GP9W%`WYah^b=vX*D8(anMX{(&AUP$G_0pLEFsED_d45APMO{3Y2C`->I`SJZ zM(Tnf12Q4lzp!CQ49%_Bu`!|9EveXH2-v|XLH>f&;m0hsV`pdrfSEY|PvB)|W;9N5 zTA-o~M7&?a!CnKpc9gKSQ5!Q$=D8V4f;XwB6!A)jzPOl+vsZWfxIl2jH?Rcjx-Z(Z z!u*>2VH+FCqQ*+cxE4fvRFGdcfPYmC@Z%Ejg;91Gqr~f)u*56fn=OMOl*Xt&MS9K; zx^_gfLDy1)=Ehe5+Tmr{1fAJrf#g#D@oBT0qrrO33 z8Oa}t{Z4Fm>TV~tJ7HI9Vn*5Rto7;%spmi6@-k|~Hqw5)=*9dy;J||pK6r5OC5IgP z(trHNmm&KH|LVv9@`_i!@>Q>%@lUUL%|9ax$m?GJhM8}C6aL=(<~P6Pt#5nV;fK%q zmw)}Yx4-=z?|A1s|9$qm@b~Wby!UJb zE{#@3mqnLHSK!~3(W>aG=;~;7^jZA7Ci+ETp_ z67arAIsAr*3H5AU4`CCjUa7CGJk>2yj=wE^>Z*i4$O$*Nh!R(@5d{#r*&48$Ljh~x zT3uZ3B)Sge!^^;Z8H-1Y9K(Wvj(gMGwcoT4*P;-~5xrhC)p}L3(h%fd zpSdqUaVb0I3MRw??y!g@#rWmaZ;-=jP$fHQoCN_HhICc%FAqHQQ?-WUjp3N*cN^KQo??PuFYK*y3tFOTG9i{?@kV zv+XMWo`~*!*H^NnO3zs*y6$AxJh*U$yvW9RE}LG?lJ=V3NZs27E5XJoBe;xDv5ZI| zifnhQBF{{$Og%+sN0Dsm$MUV003CAi_Roo3{K8vkku{Kt+#>TOGup-W23tYkE*&@y zLG~x9WiGPEZdsypGkotPelO%>l*p_tX1^C?8lWq|rj1D2oNqOR<~cWnSztMjR7_KG zUV$CC9Wjz}-phPC?g$K>cv7q~iymJH* zW9C8khG7~HI$K^KJV+T`iZcMR27JsyJEgn{GbyunG>3Dh&52O~9F47b6KOKgjFU*; z;<(PRmj#kF8Aqcz5YSgy_jJ~E1hj>udYZLXpgjTU%91vxrrs}$n*{V-zU}0#BcLY& zW{rU4MLUXs{>WjTqyyht0{RAryG#%iSmMNB%t4OI7@9#(gd`hn77Kh zQY_4bTR8#!mg73sUe-r0T9*=#v{{mRzbByI^KFZ^j(|1=%o+j7 zi*^(N$%VKJb>Le|K)>Q}7YHK8OhCU3!!!b#FE7|e0+Q=`kD`F`EJYYlo_=&fopO|- zC@4W9<&H4%F~^kVr#Z$W^uXf$jxYO>ZU+-173`D`Y?|&X+I=5AJI8+{0>Uv=*oOu zChWsNgXyau5}dnt$8whMa=!UPnK!4*y-WG@gZk9b7Azyv=FaESIe3Z!0rM^vd>~yN z0c)y_sW6om@7D@KTRgf;St?+>7x0m;8}RGpY(v%T%Wtx}Fd*JoAzxHZTn%Snt`zf! z8VkB-ZKBm%6K!R)(@2acZ(_xNV?|2WiE=o*02sLU&EPt}u>_a%HG48v|6dyC-P z`5%Z5d%I`ZH-|PW+VM6&->70*O<3ZjF0MeIduVP1DX~4>$^-R&cfh}JtU|_g& zL9m@KtsIt`bZ&k*Hs6IUFzlU*g#HQ}z5)$VAS)IUf>~=*goNYY!bM@za}7!hWUh5D zhxx8t^d7ckB3cXf$}v&5-9>8G?}5_48qi}*l$84)oqZ_bDK(NRyr(a+RAh~W`^mMx%)PuIz*?&aoY*N5@bn7aqu@aq{%EV~`=O1k6y}{34bJzICxst`HrCGpg*Lj; z9?0j%g*Gp03ENLY8-r~?+PF=8uHrlnHib3@+kR-%X$sB@I5g+CDPsb^E;L7S60{i& zg})7L49uy8HhKTh??M{`b8l%g8f;G$+U!;6C(k^e4s8s!Jqm5|ur=m;UEE;nZ3)|g zLK``yHY(m0g*FD8oB+$T$-}lJv@zJ2w*zcQ){S`^eL>baDfXDe#d!AIhh1`>Hkcr) z?#XmJ$!RIahNplHSB>kQ&8N76m5~_gj_squ2t}Cfo|9CI&K=XK=L%r<;nc40v%hY=q!u|w#Ow#yDUw@@m<(WlZX~p! z2E&=OMtvfF;sCv+*Mon*?eJB0Wf?d9ND=-e^zNH)fl+3RgxAZ>Sd(AI)grKk6k%Zs@{u2_yom)W&zRmV01pn&oNeKCu8X?G? z9a}*N`nnxS2p-@9AskwM6*|~i^2hu4O)(nfY^iX~O7{z!x3wIJA-J>B-J~aQ%H-m! z_OYH2EuCnf{aAWpTg&g4?&-EF#9di@Yfjkl&T9#FwS(17RigDdnx@3EJFoE#Y(6J5 z7BqYdBRh&vFA!4VU{R>KPNktHl>z=m8Ya;K2t+77l!sJMaA+HsktUnBY^g3_xr(#Q z+toFlm%Brur~9-g-5v+Vp; z5MI>qHEmvbz#wQjnR(>_ChR^eOwaE+z+Bo&4-ljoO7T0U?H_d7812lzR7wu!b)v1@WFo(l zn@Bk$wbo^FnpTb%2B;$GJPKHvu-KY&R}&vCJ5> z-;|?><#0LI}IB{q3{cc*Si z%&Z6Pad^!x`5q9t%IIQsKyf^>bjqpxlmM|&x!SWSPU~!0c<%ScECVFb65x}q&BrCOb!?Ozwg8{m9 zd`k}tZc5VyhskfU);8wW8f7nnEX{{Ctui~c){KZ|71o-6iLEsr$iq>w%vz%i)78;t zYmH(SwQ_G;+{nL86En@quQgd=Zn+@~Hr_^QI3u&x26e6JHIMnOmKM4qfeTPMIy)iM zw6&J@#E`v%Ho3Myu#6g4cZ`<`Eb=rwOWuw8$x(~Y1ZoTfgrs25)rs{f;zHIZUp#Om zYVhbGg41a}gLi<1m|~Ly^rQf&EiuZpj3D6>lT;JB#K-`6dfH2^8M#-U8eVBiiYdMu zvAPIfe_jr)D_v^2)ledc&Immf1ktzRrdlp2zpH{j@!evyO(^}xIZ7vsF#j7zL1!%r zyfbTl!#6Oh7JZ8~a|l`(YJN#`wNQ9ZtLTZ+PT*GE*(FUEho+BdQ%xADiiHLuz;e?q z6HH@2Fb*28a7tlSI2UNCCrllzl~CK_D9Ze1n(6Vx*juU9>1mNZMhtHnFNS@CQVfd; z;7lt&FAE#K)w(pcdqkAAz_xGdu`NVU)SI>sLVh(~g!l%dAjJ6#j72948@|=}5#pPU z4Ix{i)GAa80c}*d_L?ue%{eS!2P3Kv8u-FFjYdKB{HY8``5S&ZjRIN%pDO#*^g+K> z>P|0O-`S%|92%B`b;C6TzAEd+uO|wBzo3Ml*F1WI2iXI;Cok6`mZb-mmyqI~g=?=#$if7( zf&Z#aZAZJdq)O}Xt5 zUJYf2(%SU&uHz4z-cp8HHlXvufWE8)BK2y1U*o5m-nS)lJ&%U2v!onz#p0PHI;~zZK2;4ij@9c5dO>nh z`HM&~kOF%2TOtfF?k4K$P>yIQDExXSw-FoQS>CnmoRLQKoFvxjl4X=z(hC~??M7ic zIgYMg)3A=0gsR5TNsLapB{hM_JTvFc@I)oKK~Hi_Bi)?j*aVx*Ig)eCoRckCfkWIN*jz}5%LI6xP4KrjKu8BNv{RlKeb86cjCjQ3NfJR5({dCqRTxkM1X zy?uRsd+f32Ud#p2KXt0y-nZZW`wt)+1h4Qr;J^cs4T4_9CLCp%BU#fR4&kgfTrvYP zi+QBf!%{4TvBG>H^vr0!!Vlpug{=1r8oo0lqRL?#(nO5Q9 z-z)`E(-1_=DGRY{Ve0$hg$SvIUJmglF!qan%PbAkOg5)LXJU9n(>4K}SJ3R21HI0| z7kZSa7L1YXjpBV(otO6yO1Hcs^#yo8O$PBeE!R{KEZ@hK_r`McowxXDI!Sz??4MER zJ@3!QFHOymAqB4-Xvn7}ut<{<(FHbE;Ch#ZDK}Ety9w93!fF<|9)SWSm$AJPSTlh0 zhcM`|z`Cjc>t0P@y}Bu^dyWg%GQ2h!DRWFS{l8M0r5T}eG_(FNk1^`K6SGwJpH9Vp zYIQc%A17;{U@cy$44dlCdn$|{d>Kj*|0{;t2p=;io`(r5*hle0c~2T&y<2%jP# z%OhC0$qIUq)t{MPLQ;wi9eu@@SVwc}sevkwckNC#1zXg?`QW2i5YiI-ydrIV3O z-eX{2WtNO*d2$st<&?>B^Q`ZNk+#s(zTb4BL{ls0Sz(@k5IRb$YGuu~URP5Ym($hM z-wI7)YPANQjTOnM>?uw1Hma`X-~NyabkWr`1c?+aJew))1pXz@hOYLPn9B@0+(#?= zm$u@>k*BfZ?$)ARcG*?3ctL}M3iljnaQ@omJ@?#muf0TlqxQyBUiAnI$Qakkg!cycoXKQFZsDG1}8A7h zYS53m2g@KggSLa>^S~2K^pf^S8f;{8ZQyJv>vp0pPWM3S z>Q%-OPjxPj>W}cn`^tn5*@Vy2`5wl6gFx*3KGQiti6>#qMiIoSq_lzl&Z4=z+_FRD zxN7io_3{@y+7MBt`zE{D8O#4f%LDBYlgZ6hXhlcCgN>^W7T{OGr zWtX3o;_fol{v?-`YP{6`?D1~p+8;!?)18@HjrWzAmLdub^XT)41X2s)>6C6sz^1o( z%_bEvi-a&+q>Y}ypAFotfSycOr1B=2(Sbo~UwU#(x5eD)FzSh*y9yi8QACMq8*9m< zO&2BOsl)+BCD3$4++2jRpd?aF6?Z^ZR~$wsVjWOfJP^Z@_$$w3#-JsBr9dQ%rE)|< zE%70u>lxj0tuXZNbwQ)Euh8h&g6zYe8x{8E6uR;Ay2k@l#_JFXR?6$1Y>HL}YBk|j zErEp^K6b|Z^#ZVn+9?HgLsMX7GjTM=JPKyV1?;y9z`{f+1@=2lffe6(Ik09<1+xEM z=x^aLhdlRxCB5=e2uU>EW_C%{KFf+Uw9)~tqV}*0`hwlc$3$ss14n5 zWBOdc?xt0kb+^)a!m#R;7uxfFwA`}E#rb0aCcD^^LDY0ap5BJ>i+*E(^=eJWs6q1F z1GCkx`;~6o?rmJTx&aaf{)6zcuXPD3HJHfIhJj~edJMGif**z#SU?Xgx$I$YWo4nw zk3$S#yAHFsF2M?D47>|!$VfC2Uvp%h>=0Jux6Qd4Rna|Ntc;##yR5=Y0RPBVmLDa#mN!R>rW=-KF~*=E~H zt64N|p#L>Pf1tw4Lq}=OQ#NZ`&v}%#a-3(oZMXTik7c{<_uV^ayAAv)spwytKiM7{ zc@xMzEN^*-sD${=iSLoSwg_SvDRB=(u#+Mq8678>|}wO+$_ z8fF=;L z*=Xh|m1Z|@CRhB{C{UJBXiedj+cWtBn5t+Vc;vN)%OZ)I!UShR>9I7p*VEN4G8$sb?`F`Q0%2mC8M91W zkyZHZhh|itidd0dWos-wFSmz|(z2_p+1AT0WhXmIcKNrD zMRq;VF-F-1S+rF_U8{2>Q+W#jo7MOj^L;D2-E zX<%EYHaz0isosobuOfiDvN#6Pe9G7u_!Rs>n90KEMBd0yor@(+3C&d5(*hVR*ufcA zv&d)1q{^NdI!d#HviaD0cA)dOqu7Ce`&ih)W$DPb>h#$E!}4#dFra@cuKtQeItZOm zvj~|ZAS9ETQJCKqO>^S~jWv#aEXZf8IqOdVs@vLY0^Chafji2M6$KOmfmI?<)C##k zkorOorJdx;B$D95vBkt^UC?EP(e?0)JMkR0kFBcTfAm0NWBJ}{0e~=<;TwROEVJrQ zDmMd)+NC6sbve`(@6?GzWAr&7vPxC-VMCRKZT#g6(X)#t4;Aw zMV(Px)!fsXe<}&u_!JQ``V?RMQ?b?+X4va|^MUbze`-+`g!usX^Z@_VjBvhr(7k!k zKb3%N?e`__=}Y|6>{Rjs&u^vfh2IChMAZ$$J_lk0P5l>2iHZmr|x(ZgBm?$wv3J znrvv=Wf!{C4Wi~u;pUWZl z6$kv;d+A(qz57IuO%OX|u&3uz$_%j~wrr#OT1}QU?UMO9&+0mS?-{ zC;3R3c9{xi+Z?(aZrUZ4I6dW$E^FB?MQowVmDw(9>{804OKcZ_mPN;bewAE#mfPW= z9Mql8pj(~X@ayfkUBo8|^>XCL=f>bp6+I%Ic1lXD7+nnB+8fA%C}&Ur;^xOQi;B)f zEps5cO&NkXe`Oj(mu$&xu%1=`5$70MfJk?y@L6`(1jNP@MG&RTftWJ8ljBDPad`p6 z_Ld;hW)_A$3W!4`AWE5m2)-x+nCeSf65|Br(&hd4bx#9&c%%U5trqH z!~!ABZ}=8#RBP%$i}dat7d3=sHtlxO7;(fZ4j}s#-n$^Y*HUlim4A4wVUVz)C8!!M2*12Yy9{k}zqn~vw;MXzuGt5b&@knms zCDYPSI`Xgq@8+uH9!!9bJk0pY-4Cpc;1Gr`td~gm(XO$fqZ&!Y$4Z-hE)K;sX!8ST z^HpkipB?5N#HbllseOqqob@9*pkyZ9k8%k8vLl3KdZ<<(Dvfi4R;;c7@oqF4>jiln zs#yANE*pFi3Q@~wNw8=B30I3!2`6GR9Bxq<^bd87D2Ky(BEe&g5ZXC>dB0yNgn0&w zV0N;WIZxBRRjdXQxkQf-Xsr$ufx2fW!&j`W^mZmANFn?wguh{SG8^;`T!7$xp6JN0 znOcgX0h6zTZY+7cx^q^p&YvAUCJgp^9jvllP8Uf;eKg@V(U~$e;WwOLp3GQ(h9O(# z5x-|!{S4`HZj^qqE8(~RObgG;@m8~m=cSx-!jd~Nbd>hIlr9nyi8Od>d=vLlM>tEKIIBy@!@^fChoe0kdo}guK|+2D&{-SFec0<_SwK zKA?&8a-8k|k55e6#gWXK%p9jq{)AcU;d9yi?7<&1tNk4=k$x7>4>I~ZgrD!lbA$a; z_u-#JpG)xh0eW!oApB*+&tIW8NaOzK*T3NnxIp@iZ+sJOkACZ0aecJiAN_XRAI%G- zd3&_n9sQvXdy1+LM@6~uWKM2;1l8-qu~Vp_DJ>U?{$N^ejNmRRFA&@h;mYoZEa>&= zYVLPT-< zL23@NQDvQB=^qp7Kcq*E|3h9cD~r*k3^e<?t9!K8-L7jger|q1=?;4~+)f@u9j6 z1=S5U$_hvy$_j4%L42%ZP<#PiBztsSKGL;E1ve0VP`X6WI(1go$Hh>2B%U5xS3HK=OZy7-pO#-l3FJ( zWKfi@4@+24o7xm7Rb^J+)dB2Hiq5wQI)Or$-RC!q-F_=E;WbO4zXm4oEx?pK*K5o$ zp)(zd71J0XQcEJ62Z2J-`jjum&p+oJ&n(s;%=NVe;NF~qB4Mgq0;RA5QwZ+|s<}M$ zyy>qAIWJ2?c2G%+gQJ_cAQ3RjlQ(h-v}2iovp4}WvAEG*3eIG~8&Ck05j^zBb0C}( zj-*yi;sv~f99AdtAD+nCuR~|dTiA{iu3Tn3d+}QKLv-Sba1`B6sQwvc?MWau3FHutql{SC&9%(R-v*2aN4u?!F%y*4Fhb&)zC3A|gd!MqA<;!6SG zU+IEP1mM(yl_RKe})Y42gVIqQ7ZMVok_pOOKLR zi?_X{!B62namyXxB^w@_lH)#)gu&dTNk#rq24naW)*WWTBT+!xNa^poBAkLYtTf(L zBYa^43k5KMpR_GThFjq?bXMgZc5*cRP~wd5Y~&>NS{a76Zio$J61x#o1JVbq)K!fR5dgSK4-^c- zr~fs}6_!`yo(#1OTpk&e)gkj>^CNTRmI&Pp4rVTVS?oL@f);_4ziw|X8qhpq=>0gh z2IsKI2m`O-2-l3V1c559Ok0BD@c4h+y$PIMM|CFt-s^64ORc4C3<%8fx@B7}uPrao z5CQ!zTLT8fHi!%)$|RG~B$NC#nN69I;aaVwC2ztQTgJu+FtH{<{FTIEJQEl?U_c}c zQ5XzLFr+b?00%@uKmmj2`_4JF+`9MnBDI8P+CS@Ux2jH^I(7Csh3&+zYzrPZ=`Hxx zfDzk*&v5WMnfVRwlB<#}cmcBUKsrl7DhjFVeq8U76~7nLlOr1 zg?HL`=l40oi)4oGDCWEu(5{sTyXbg;-4^h|IWOQ5E|24(oR95V3RhK@d6+ZisfVi; z6qD&o8R|c9uETCMk0+}cn?T38nl7Sp9IGk9T(l@KRxTCh6X`qWg^yz8tV%u)$!9gJ z*jeTcK9RIhL?y7(fX)*EonKT_a3~J1iFNm5&TUY4cNm9=+}9kKh~xg^&35pR9L3)t zs+++6H2lVP8wv0;x^SaP53x>q32uf zgLLXXh%<`{kAKX4@MH5Ad5nYm$J_^b%zco@h;GjZZhw7Dy^v4gl0GW8BOwn=rP z{h^H=#Fex`&o0oWC{imfWqeQQ!>(XM6bP~|K=!`yL>vvP!sp57Ax}Fmc3i=7!Kxzp z-XBoC0a__0SQZ`v|GRr@>hib7X8#YtqYD}hCMz?rk7yB(^J4Y;QLqRn=6GaIj>{or z1Q=>EJ-+6UVY!b_BDmqA+mWm#J}{OKhQJ~Tj+nEE$t{v~xCS>YX!Ly*zT%b5U}~@j z`S41zJtf(JG7hvmb$>BAiRYp+5CnP@FGCyONy=ZbKi6?H>)W{<_kVRw%rZi^c(-^N z4zl^08SF+k0zLF{`AK1fu59Jbco6r#vE99EWdl36bL>YST`}9}nmf$-A+xxd!SHmW zGiOXP?+T;$W}|-eMcIgd-;)jd_uX0Bzb6_TTnU8kYffl8|7Ji`7PAb3m~figb5ARF z7dS|bifZwSyPHZ^+~F!5M`TtjKysNgWr6DVsu=HGp_z>*>2=<}VH`09^F5_z5|;Mr z4;htFq_3^;zEYcTSqza?THQ8-@sq9DK}w3>eubEV-5kf%OtgJSfZms z?xUG1lFZ}e6FG9N_bR_%F_7LD`WN%)~Cssz)>f2Klb<3QOG`nS4BSX z{E6q}h*zQ;jyn4K`s>Fu$!sr?_WF0CLCskD_mR; zAJGvVl8X4+lFWdMDk z6a3AHmE&$sMkRt3e>)nY7Ks(NE%zi7EGm17Ju2*sWm!4iJ=APYSt~v)$ z5zw~N+LnzY;$24+?CD!ee8W~FQpGc3jyQNm;+^PGOB>wr1CsHl{O#d%X*$Je7*9D@ z$q3%3O3JPOvU#)pgEES>B`Z@=o)EEpOF*VY0q?oPT3X0Jo$xnu3SE1n1Z0 zKS*#+fOtH^9DVwh=vN~22multEFsTUDQs!9=ZXx;?ZAb7#eROFBVJ^uNR@l28@)WA z4}C*V=UahmW~an;5m6LzH4;-Ux)>!9FB`$!YZ$@_hbANa%kikcNe1o+#=e^tRp+gA zYgHE+L(VuTJ^TFhjw4+nf#HR=kN3ukdxgXoM#bvTY<6(*T z7E9Ej2)_g-W47)7zq+koI_CAHmtZ(LDT>2gtPrNd-BcQmK1P6rG1}@K;alYN%W!bw zwX#3{AG2DJs@huLwrh2$rOT(@4!;OUDZ~{e!TP;71*$$X56R?b z-QsrZRY*IQWAoGuQT9N5RY+Uu4B|5i9pEhxCQnFwRmvL>&f#qT&s_Ofz#k^XVu7fP z?0)X!)a6%`sitM~Hd>|`dvi?NI)sgXtb$LM51 zs;bE%uAVy%NJ<%xg;6h72Mftn!2ey62iwa~LB(MJuqHE@Myp$K?#)_xG{X7K5{E%ra&=r`vFl~0dG2!tyhfe>d z%Hq)eM>$>SbJWX3`GG!X%A&v<*l%{zgKGi+nbZG*f+WU_>4kwS-x9!>(3B3Us(wt- z^leNT-&MSEw$;3rLU)c_1XfRtpv7fEi!>N{zZ9*&8XDZ5&>#;x*jXqMPopsn_9^S| zG{~!}af{k4G)PTJOyj~eXNX$FG#Kl|6-SM*mY@KKG9wpfjvBdW9)4Ju>vKQ3e+ssn zH@jqE+7V$Gk%$#R+tgF10P1*z0IIZ6b>EFH&~;7kZflM4KP<^CR~$|z3qd0C{;|aO zair|~*p~Ya%=giP4@mU*30jJdS`-`ss27YD1TvHPe0>6x7>Y;T@hn}>ur;&k53UZ| ziF*KOOg1fU-f?}tt+}d!++H>8aKHsioJ~Xfin?(2n60q$x^qi{99-l9i|B1VETVsp zU03qJ>oPXS2$X6gi01+x(|y` zbxO`HNc}5l2kIUEWH;*#knW5XT(N!PiWOh1IAb+|pYfxbEx*?-fQcOmg-yFfm5h;K z15xb2)9SZ8S-?3nZFx!3m1}Usp~~)xlHB zj8L{14H==73ZlI=^!lK(2CA09S;c^B8*)}t8a*#B$`4WQx4fDvAa7@e$2Z&S3Jv$T zx5z-2>P{<&LMgS5fe8ILUcgfzo=7|E@d78q7+w%W*?^yXl`(pbp8q!g#j6&}({Op}fJj7lkx1>H|>=P0QoiLDSG|H&y@#qs+7%)*{m=5$P!K zkL<>;#u8nUGRsrfNt_t{iX8G`*LtlaOW*_8r6{uxyY_VHM?^Wo3U!wO~K zX$}54)gJf9@K4kL^^k%W)kyyR$;uVWD#MEwEBloENGK^t{(;#gKgHDwao%B_oHxs) zv|4aJoTQ5yafc;3$75i}9tm+(sO2R7LPOkJ_kE z9;58l119v!Qg(Km+~a4sazs^tTOi+q+pHm~obk^KX1rL8mLhvwt)c5g4#lDhudqC* z@$BfQN-UNPT^hE23yS*edKdNC1X@+;HzG#NVyD`$weO0p?L$rFYHjTs%xi2FreBS1 zrn;Spy@;@^nb=grYd7BA4soV(Qv>r+hfGs#e9%?BAOY{&a^L(?(chGEunWwUy$I_J zl?+NN2x$BoVh_3?$cjgg_@n4s{Lxv=wjak$RWhwv2Uh(E52tYK2ypyZMJLrXw>?R| zemfQwWqf}W3+Q$B$kw-_|JWo-@~2C_vo;3 zh$Y_>-o}y>=F5XXBL@^TmtyK>98`HH0%?>CtsMb~$f4(%t@=!dxysr<-h>&Tz_j3? z9JZx$Ae4=oOE_LT)z~hEel1ok@{t^y+7p1AjD2h-354{(vQ7#oy5WDq4PQ+QpoAs5 z&1rkn6sVzt_a}59$rq!Nd;zT0ZNGrUZMpB^6S~1jbhQn=94+kIt6CcpbyBDm-MfWtSXE7F;x8&9>2X8!2vl^7xxDM3%r}e+*JYf1tUtn1$}U@D zbNdgQX;3$lFOg|A_gQvA@2!3k>mt_dv3nDgBg?*t+p%nuNx>*#mQ;-x^>mkc4uMDD zR|deyM^VU~imgb;mHsIogmeBQlaq0MDU)Jh5qIPsCJQw)nktMF@>vfHVN?P{N7@mq zl&9d(c|`v>BA@P;lLBIQ35dd#SZ)}&l-8m@eT!3*lwrAbJ*$OgPgZI96#nhNX0cQ$Nt3p)RV910;}gY z29_>sBzooc+{1jWuG^68F_9T*G>P^4(4(<%Jp*Z*P|cxH znUL(?0vEc`8kf0HJf=vqq+}?TuhB-843reea#lg$ODL={PCRi}85{Ones2KRN{R9? zp|{=u9hrX@=H4xSG3J03_568|l3yf}64@6h4y0No5#VOS#j`4Lx8Ma2Z^R2U%?)?~ zP$ELR+TE-z1Bl2ETT)iDN3Otig$y}o7fc}=NqtlM!u)@zrW2!@7@eIeBSAR^ezQ@I znJ^nq4v=sz@{mz2LrS39LHusnXdBxtsbIuRKxCsyA6Bpey=i?HIz27i2_?nd+p-aQ z)zk3{bJW<(2}Mp)nZ7sSHU=@{-9Z4`Q%4~6yTVNE{58Axo)_VkqY<|p(f3#c;`J?C zxsfGzi^%EPfVr~f@rr(_&_sVLCPkSDaG@XbH{4I>v}g^5TbDg;9O0Ejy$j?i&JxqI zQ08XWNcCAaU(VevWECO5H%!m8={Q;`5ky|dEhj=qT#^h0vhI)<)2Un3!N04+}zsydQORdJ7d!Yqt?0J6#xp#RmLEVByn zB317ynWRl45L2L$KM2FuouRYI76kFZQnU2f+@bJ9d~B`?N|C&$Ttrf(!x=9k>4%+L z5y^Yv(qw)t5|#B>Je*)rj>mexfXh4+4Mxtu!58^yuX%_o1h`gv4hN+h$|@XJJ|ds5YHdb) z=BBa-9PO7^A~e=!cjO96c|((t*-8*;?PzhZAjJPL#XZ8AycwI?if}nq#42tV+hrqR zcNnWIr2nE1(v0~2K}IA1O_cWWA*yD2)U8|t;>OTnc!C~S~f5)1503@3FEu4)2_SG9N|hwjflh*rL`&@*y>^1ORusK<_d z($NX^NWN}O#9uCwFQ*!XFMIJNj;apf`GM^yfz)%)xqRQp_lxv>H{Y{dc~=u;YzZ)? zeVJULaPCSp{z=<2n9$+)P@AgR%3@U6QWitDf;Gqf&~vA%1a#^gjK}MJ@WvC)@i>>W z$d+PVkN+bHSCB*&^~hu1h=;`iZ>F{}nhIWt|GPT#&TcJvp&d`H@s5urPLJzz53gwr z6dQn&Jf>u!+*t867t-t}sga{oJ3y|kbx!tQ2c%a6yaLnFJY9%X4&i-(B7QbMTmiYW5m#*|bS z^@z0=WpeZT7cB82Sum!XGZt>A^>CA}U5m7GrPh;1IcZ#{Tfb+IIwV-EoR++gm18ql zRRAt2t@-9)OXM6aYyK(+aPYp36Dq6WD%*eElM=Gtk^3P`v@wVf`v$p(AY!upKORil zqQ1BT&)TY;jm;)|RJPohx>b1qW)us^*Jt6C@L~InN8V<&P&UX>EErP~xgZ}lap&%P zOy97=3mbq$`^M@nY{=BmV|opP7;wmUmf<~v3~L*(7hQ%5J?CNwYK zqEFDMqE9@26`rIUT_Je3n+@$+N`&Y}o-QbAvP|dUH@$`j#FA(=Sd@m~8Vdoap}W9z z44MrZv^#6iUKS^7KDTvcm?5Po20U8`uOyPQ>4^dR1wuF5SGwHb_X9q5wN^DOzuwX; zxaLaG6%t9A!e8;w@2UDq!3?Zmh^9`s^fcuOa=|ul*X9vkOx%2;xbLUr6n)TbHsb{n z?VEB=Q5MC8u8u%3c&Q6 z0Rvd?lBtYuFp7P1z`QPo(r}B0$GP*%_)^V!j|P{}n_GZI?JWWY)W!zaUc*q?;L>vi zNINl;iVQ_KQLRaJbHKKlRO(#A%2-&Ej$^CiLR114SMiLL^Cqw5% zWVeOEb5$3lWQ#4Q@OD`kQ|vqfNkSlEk6|(fN6;Y9l3H?m7{}BSZkbxO1jXtd1saDH zMhSRIk<2?Q9*vo&PeMRr7&P6oY3U)=5GE{2`iQ|E$MJ$4vbh-06#uD8v(3Q#N@J_z zYT9mAVY-FxK4giYvz46HF%lrU6x1EZ2T%Pc!iUaOrT4lbxcu%gMN7{h$^k(bkS|E-0qQ z6s|nL2ADP$huJ8okx@uR8%<-tgV2B!eI8?izR2Px1`W5B7*vt+b*9-ZuDCo3Vq&1- z{$NKVk~Wj0OgT|7rbX93rl}uhP4gTJHRiTi)5A=o#pe+oWx;FTU@wq>`a^Jin~~iY z+tYpebgf6Blmy!x|K0K+|HXP;i zto0&Ya>2)n`sf(p^=hWmN15$_>4IMU86H&q1QoI~qbU%a^E}F1*)xFjIC!gB&vwZb zej(dGR*`t1WOno7d1@{ozm=dq5FVWg&T3hPKV&2UOw&t-%WBEj978m;*dzO;%^K9Hwl7p1<4O;Hp^i&9 zz*Lgb6NVLyCFzb_CsvlEL7UU^_) zJ7rhknH!a%j^PDTa6?gf5ILtjY6H4(%EOo{4;#3Ulzv6!fyg)f8uGm!9hRjM^U9N^ z>Cx<|7JcGD2J>P52uQsqI;0$72BAk`rvhf!gq~aqLH%cgAbO=MN?(#YiYKrDH8b6+ zL+W@YMQSMLeR!Z2O6t(n`hTa?*-oi*@=i3!pdpGN(g81IqrJ=mo56u5hH^c9Je-Ik zDXUpL%q=S5ATVt1olWUYVY2+TScH1&aVT zAVJNPG5M1uQE&?($ztZp=xPy%@ox&_TV-@PckZrlmJ#S%vb+m!YE3o3U?W8qOMeVd zNTr9$GJ$#x1nZ2S%UVcJX@4W`~u{IBK^R|(doBE1=+VZ?VdwoKx#C$^}VpQVSO*Yn`vmhez;@&pol3P*Q~4|rF8npsfV0E#|Shzkx9diB_b&@ zQ6rLJr)A5R^F)b7ohT1$2>S<)@XU&n>lcowKcU$V2@$ZT3>wJXm>_dk?tA%!THu;l zX|ljf{9$fx!!K}3q#-cmttr~vBAY#GxsndE=qjto{@4>nHi@9(*(8E_yCuhwX&-<@ ztZ?iFh%uGV^oOz%w%q@z1yH!AUiqUD?$m;+W4d!g(Y^raCly8NQ!S!sq>Q35K~TH( zYQTFB=0iuJxLz3%Tb5 z@Q|eF)UMlJoXAcn=Dj6I3RydpAqpDHu3GaDPs&b!)PM-Uy^b}7K9Yv1UI7U;?WKJYZhMTl=T$xOkH?gh^WV2cm zn10sW>9w+PF6QJ4_|7A>_O*TnRi&oJzB}#}KLc$R_ z$d7W1(OFU8#$SVPsAdoJcUpMiwh?DBUiofI1Ry@v9suL??9n#h_aB3byC+QHFO*NH z$7saMB~AfKqK{NSn|lq-jSSatVn@=^iXTV4yrO0Z8`$$%9);JCO4u_EHX(Ln>$ig4 z?hVix11aPs14;CW_4jvpj21guktez4{*0DqtQ-#*h_p=O_5mAj3**@pVXAl6NojEp zIttlKw}s<~bOQR3=^}J2{dk2dwUUFpJ-|{C^B@Q5GY)e1#D!dBWdo#z5(}ZjMr%?4 z*o{S1Uua3&f?tTLzcH{7{OVW;G#tl5@Sv~|&fm|H^YOcDf{hK+CG z0NGG>=Z7y<`ep#oG?$YBFmqMa{C>KJ;bKZaxT@7=j3nO@1<|ECwgW{=z$R70f3;Bg z5PWl{*>A5H+PftCkRI8#h=(kbpWhARpdYeCe8wjVk>E)kHZ+=IqM%To)z3NQZ6_HG#lhFhLcI;KHy-f?K4R#fs zw}_YV5|dXS1Tm}r$q0ak$Gg@wURmS?n~Quzm;p|EP$7GzonFO0iJqDyw~089@(RN9 z+*aG_=k#Jgx=1G7DQB>4erI{s!YLv`h&aW;>_E&@4uubu5h<|Igqj3W+c*GRSRFos zU}m^g6%TrW3Nc7DbDEG@ff-GPRkEuH7SC|I>hAEg?RJP2amS~^Q?uZ?&^Vaor6W0_ zL?=tPt6pb4mxD)fl^C(iO~;Vzsd)dWd`~?DHI_FDEuKJ{P|%2rvwsXRBw|#%}iD*MwdQ8|v+j8H2 ze|&xvsw#E>iPlSC?g;UP82uqHp9cnMoa!Y27Kl=pZ}!m#Tm?#O9lMDrjJrLI`+b!u zddgJ$=D6l@W^$2Sh3WRoklyfqnVi4luTu4&Yq=Ra0P4-S+X&z?+_k3hc#C0I7}}<+ znXEcxJq5{rkuN9PVJtgw*Wpkto@r-t5ha6Wnhg3xW}#84Iv8DxkOwO62=5B%=`cb7 zuReGTxe#q%4oQ!`w&5pcY^9}PZVkX28-r2PleiZ5RXxPI3ZsxCJ@SfB1x`hJ9E#P0 zAI9Woz0rdpSi)D%-GUwJc)94@_^kRNZVe4m;b0c+K+s`X=o3xDDoI7TW9MFIl(bpD zW7)0SvDMuM>UwuTz+bCHr9lJek&ytG><%oP(u>$vM%v`1VnQhiIavS#A91c3tQegF zkf2I+b2X>l8$dI2iaiKrSb6~QE@@%9UO=;*=Y*-sMHms9!Ny#KlDXW0m!ScZb>YIq z|J|Ld@R{5_oBl?c0seioN+BJ{jEa zL=4EwZy$UdlaB$<6S;3_47+T9DDzfX6*jSFG;+lLa3dlkrVe`L?kGPv(i2y|l3vvj z60uoM7KeA9G7fzY^TnZW_->W+KX)8{hjyPkUf4C}DDh-oLA}GE-X`oqWD@XjTsS$) zoHid5p*B@d;ro--q1IKPaHULdD5vg`ZMpB^{-D%=z7zR85uP(49xFez^@@yRR5(Vd zSQEW^dP_J+ceuzV#D-VS%MhGn6T^0-1U)Lb12~cFd}t&6Ox%umKM4n|Xg~arlqy!eSjWgTzxh)Z1qj1cOXZduma|{gu19?+$ z!Yl+H8p1bi(W@9&u_%0^Sa`(1l~#0d+bK+LS(cRLH80C4IDg7f_z03!aVQn9KU*1%6=mqnFFl z3=m}~#+}R-l`q|N;T~p3dZdayIX%Z{(D2j82DT!C@IHrc3r4L%Qwd?025Y5F2a=`? zG5OfEuC$HXoi^=GnyyAu5zFbQIzwR=Wp!7D?*Ci_X6L-4)yxh|Y!Fp3d-~Y5A@>)pS;N7hpjBT!%ud z>8uVBvrL2s!}CO~4PzEg&uSqqZ?e>-22^GP2=MF`v+N$jnt8Jn^?DsZhDys99RmPV z^$=9l$;axFQ(AyJ(~v`t*M}bOQkkzgI#hkcLN&EZv>)<3`^*XX*+tRD$_YVtt+dDNIdj^naEXMR3(7~~*%gucTSNDT!}x3w z<7|-2VwT!w4>o0LJ2B?y!)&8P@h_;>rcU(3BLW~r{NPs?W`p+Bwr}yEAhd2%SjF`y z%*OKtZZB3{a;wWeR$O)gP1Qc)PN^Vl<#z-G*;ZC}lR!oHl=a5lDr9D#qeK=vYN1bp zqU$8p8QW>^ciU#}JIyya{X5MMb^n>(X@2C>v(tR{H9O5YfZh{3fIyF>fcF2ZJIy2L zbnmoBc|34lGVKW}(9xbmIXNRgb*_4Y81O~G$_fNh@eOW5S8ZM>@Ymgd? z)Qz?SP!~sP0#qfhGT8S^v&X?d&T3AmqX%;`yYI*v^OB1v#)%y9#F&#FN8yK>=RqDu zv3-iOi?_nG1XsmDKE~d=U_wGG>IU=9mY7ZI^xRgqBxl|=OwJ{5z6PSGD?5kRK~R@m z+%Gvk&^Gxcz3xo#5vf!fLj#%FIqfcX0vMocI#9AkyH%>vn8q1y3MjQimNb0l#dJ$F z1bPp>7mAwgIl{%mBE2p2c&lF2q7GPx$*MMQFSQ9N8%NIq0WMs4i>eqDuPZ>LFk2x(lewp0`gBXx5bjN=coiP+oN&hu;jIwT?7~{|#%jpV$(HIM zIj)kCm2da+tZDX7n&_vi$@D)VHJ1snEB6CgP%18_s#E~IOl<-!yg;gAF&2u6s}E!Tyy?^b19E2d&&skLB%I8*E-5NEcE1>(*HC>jd` z3unn(Iy3H*(GN9Q?updv!N+@38xcm(xjX?KND+xO0zOYqO4&@rCFl%lWg2tiV_K#K zeL&$bRYSH1TiR!g#EJXkb{NeQHzwgOh4c2$Edc>mM_Ln#ZIS}LA_Ggx113x;)Q;nzYh*Horo#h~ph^7L{YAP*sIl zkwQFU$D2Vv<^xVaK7a?DhRlaWMc&_vgunrQh_vEE_{?Fs;Z9T?*hDml*a6K>0uzDh zy*nV_J-RV86B9IPTv_*HDe+_~p~QXeGbvFa5eDq35|l=Y^#?*p2;92bET2tU8Nkg<@yBV_BDj+9bb--elAb zhOcz*XBy0^^@T4g=>7enW25&fm(+1!wM6;zqJV7g7ky#`fcAAm=1K$y1Dr+#>cete zK#0>Q0z|L|`%S2>v?&?A)pAN$x?{0S@cz0$efY{ zdcZrwUfFKV%IUTm#9f~Zv!gVOMnSL-sW_r+W8;WB0g?^rN&*b5Eq)NMEZzrT zcGUu-{@E}{=p9|LGdPw-yCOfpN61(CSiNvz#64j;SFUQHHi71G&=JgT+Dh0JRSsp5 z-#J&86PA4$7F|M-TGg~(_I)l{cWT4_d;um36iP4zljPeWgtH{{tgazpPkcsl5BS7@ z|J4G@!z>pqIO7}tt0|Xk($-(`#{X)eW&SEF$svaQuXf6ize>EHzmE7{Ew;>GjcM|C zSaC`$e%%~T=b|~@>6{6ZxyQ>hWTCwG$0^91zlJKf{w_@FT?8ZH8}tuLTbI_W;Cs>m zH2VyETnu)pkJtqfO$!dhP1%PciGaO6HSF)^N*=h;AWr@ z20X2j1hZ}Ja4J{Br~q$dt@x{)Ya?ml%#5QEr2_tH6r{_?y-rkfEp596X{_=gT}714 zb+GFyLPr5I70Hsf%TbKhIEo!!;ur(Ul?84g9ql|;8+1^|kR9plN(c2P;2i02(1=Kf z^@bOYKTO4o8W(H|uDw*NC1vPFL{QG5KqQ41|3t)0I_Txlsk2C%GM)y?8?q zL_%_?niun=8C~BGx`m75OD>DE%$6dedNRqB(oy8q zt&+~PMClwfqV$nK=_90cZUjf^G&cgJy949^Z**Ra`-T8hHKlW$c~bh9SPpCE^dHj& z_3CBERO?ylw8NWGH%Y{^RN3MYhvVj#k3o;vmir#QsW~`w;H+&72vZ{iiNx!8!1}oC z0sbD5!g|ME*85+*fL+_zpuggc|JASPS}n*u0-5y&|Est|$fwuxl3Q*@m zsWG0Vk3|!XX)ZOkP&?A$PH8S-WE9KuT;AtJM?axCHLc_zHY~yKBOlC5s{sT_Qp!OPI#(51kmW-XZP*sr3dIXDvm-Z^ z%5dz+{m^ztrZ@ouXP68ROf*Gv4bF%U^6Wr0A5)8=fj`V0cEe2fg&(h)yx#njPQJah zYVxw_aY59e3rmx(fPw04G?5Y#T>#G7+=Rj^!j$*q9->)qkOJb>!Q^Dzh?j9yS4gQp z@+&jq4T`k<&5pPqoGRi-HSNSg-j@4r%@8Ls8m5?y$y_x#>&LB9k7a6rf@M3HB3#bt zwAY0}P7jJ7;GT4(X~Hz}Ql)g&S5H@EU)BkS_Oef{l*hRvuXvgmiSjr>zOlI>_Jnr| ziucu@_|Id?v1x(9*k7}MZu8=DrqjAMe`Frh+FtdvEOZG2JL?`jISd>m2AptIdjPzq z3w(x#E#^Pm8YpE9YxD#_im1e(HTpuOw#lNUT z&#bg}y@NE~tn)(kRQ(XJ1|bq)#jh6#EuF48S!(A18iZb&37A78<0qClUi!C z;AtZRwC!BjzqR<>nfv}v4?cz3T*Q2?Qg&YzDu+eoOF7%f44kd(oA4dmrRK`JASVQy z+_L53@R`v_bVABI(J3io!7nADZ_96~yP)yUNo^(U%*xpAJazoQ zVlOc^-)%%{+_7|tG=!|;jp(0#jNtO5^tt_2nAH0$Q%XCX`kV*j$FWR(Eb4Q2F95=- z^f}*eLVF9K&-t#;9CB}(OTY`(#tMwnFWAkHE|G$a`1 z&SKPSWbb$In8qO_F{OtvQtpLJq-tvv%UBWwzGK^r>=@5EDM^)Mw1S#aJ9TI7JF2E8 zy2L#-txu?lKZ>`XV<$?Z(u?{!@T(5&m7Elg-2skyQx|@c%Vd1CuJ`lO2|cg7xOcRDwd*B-weA32Y}qLKZ#{q*vXQSeCBU`Y!&zRm9*i^RH$Tas#E}I+Sd|g$`%NVM0vNHr>obSk zlTtE2SB2WsuVngRfAm;aGLN1*f~tZNzT1TKPDaV}eVsXEo)oP;c@(HvH`HKohmjNtttC5Dh+7w%Sb(A+j9@b=?U1Jd;sj& zsp3bFQ*uW6ZX;@2$N-q{|McMVqyk_MSD|tt0${%5$4JoTBm-c_PaQv10WjZfL~10; z>HwI3`Z0pblL~`-gfX{oVggyN!ku4764&YwuA3Cp}hsL9emek4!Nfx0QN|N z_|p^s^TSk!EY4T}%)>G7kj3c>fO(jzBNjL2{((}&;aO#W9G7jm zZ(%iK%ooZNYNDZM(?34n;@k*mxm4?l;trC=_^l@(+h@7mBv(A%p;I`W|03I941r~& zuxS}+-0|zG)=C}wbIy7E6L2|@ubeit>b&zWSUtSv!iz4xv4o5U9N+=IIxN+8 zB~mt8S(B%p2JrC;J<$U&*ES9{db6_G~VZS^_Z5i2%e3>2n zC}F}FYcrQy3ZMesLZCn@c3lH_l607NGtrZPK(dxk@sNyTw4I@Z#L?vggQ)JP7#&b>$@=dygkhQXeo5K=vK2yy>6f(giK!ANh%G^cS{%@u7>c0onSJX6| zfq(r1Fd?U<$%pPs=B)fn=gbm$eS`@*f`}x(j~{@0+DRy6-L*}cu^B1{1`f>g)|`%~ zwNwrGaF|M=1aW*_d%D#=Qfd?OE%S;~n>bD-2k5biiE?>ue!Wv&O}UJc9#pvSu>HKM zo6Q%3y|oaW?7h|Vh2WN22t@b6{O5~<`4%PHR|`Rk0|ln7XEVsKK*)|^QK-s$>h?}Y zDV~1)Xdf)G-czu|U`-8zn)s)8gSlcwycO&$cP|*I9(lM`=Sc5#GqseBC*#r15m!GQ zcV=ac*F%o6QlVW6x*?(2iQM;LG|Rfi5D#Rv6^S|(PgCNOrujOc>e)uSYKxtK@ViY) zvswzJv?$wcya2^0P?Jqf$_DMunmal6M#_CrZczNHT#rcCD5wvUVG4h$qC=}6L+I%6 zemd#>K)XXrn><>ICW~o^7OQ&i2r4_Glabf(PB2VIYD6-(TQ1Nd(Tpp+o-sKahBT#g z6yUu+jCzA;e9Im$C?6+p#4y8ZN405{U{JGMHo)>)E`}G2!rQ%C{Bp@XSYdvLTT-); z!9{X;>x%xYJ%}rVdfMGmtCBTswE||3eCADCEKSt~Jqc62M#{y@d zM$hZOyu=w*0van8iXP>zHJzL5Z<2?1%L1E7r;~q20of| zpMsUG;Vt_U-oi@&!_CdqGZR*V`vqMSTTnLPgP_trAzfOIVh_l-tPlc9;g?z&9uH5d z`QeYgs+IsQz@3EOOZLsqFzSC_x~hSagS;=<^-unxd_b;AFkqGlFyx9_DIU}?=G(xu zQo`C$y54wq7|Uh|hD$y{wx|3;_AG9MrMp8pNpBnX3vR$X=`hi&|3E9KN!0EwX)-!Z z$2{l^!Av{~s5u*}jEX$o7=SX(nU~Xf&AFHFO>T8>95%Et67&*v zD!(>$@gj6$I9S|Z#{sxo0&rhaL-=w1omCi-cW9M5NQKO;rPgd_WagbZ8%qwyeW9I^ z4BDxrREgO)Bn}OdOb=Z`6j_VFx4TF(EQv3r-pCDYiM)()94E*apYAaW$-FZFWhBFr zhn{3&GQnQ(C6i7xtRgugfFa-Hj zOEMcx21K2bWbm=_dgk(yZYnM5?*)*9;F|N2UJQU$ge~Zj{y_lBmXrzUKbIvv7(lTl z)jC<53QMY=s+ROJU&_EJ{@m+(}8*wDnx2 zs&DsLlByo4pTAV~p#0w>RXxa$C8_FxI$5b|s!^gZ&0kSE7&!7{MylSyx+CuDg|4wy z;Xl};y=sm2@b2OoEAxO8GbaD2+jsO>BkR4QbhOxN-Ovf7?kf3fJ1F|uM8);WL5xl0 zzW={foqtikRPprX7Nf4V>y?sFnjqUU)viNVJ4#*2W!v>d6@NOgK!$x0t*7=0i}Jb# z{xp3fO5LEh@$APv4(S_@m#gnqKIutMrhnimPkq|c+k-=^R-IRo$MMY3XFdBD);;IB z&l~Gx^-KKzWQkwEB|aKCDNB9?-@-TnThN&~ERI1M2WuOPg)Ug>_xW^B@k>y~AfnOj zE(!cG#V!*U*J4}-lid$T7yVMa#ij#K+5Lzl%Y8A=Lu;Bdv}2%>j|6`tC?UkBW79lP z#boYbHQytRbl);*}#Pp%7}2?;=eFM>Wr+E;)JZZ4hiQkgNc zF@8a3ya~5oeyl+|k&e}8vz`VnouMm`DKl)g$u9YDj;Nagxc{hX9iNnGN>zTgvC7oQ zm}s}u1-X8(CA~gF27ptM9!F*=Tm?9~G31qae}!JVgWGYsB}n+c8}cQLUHB31$yQ5Q zVL+6%cV_KfdUsGm7K&kdB$D6;o}LbM{}GIkJ=&0)duRZU;5WoH+Yo-c z6u$vV`R!s%g#+YAwr;h1LGh@#JDJpQaWuq*(#@k?($9tX5$OzBm-T~e1B?O8%CDE= z*J1q1c@nw{1W;ZL)N{>H4`a!6@9?tDzv7I~=hCQI%qQp*r8}wBUIb5TSK(Gp(iYZN z?D+~CK3%&%3~Tq_bnVWQ36E!Q-l}zq#{}_zNibF^g{*HQ%I|SMo?TOT@_+G3yOL6$ zY}+b%8o*sg>d^-cD0<;wX0RPe1aO372EEve4K}k|PZwp~lkhxe1MNkEm1pDOr;$#0 zMN)V6{cm3gRIHfTirg9?i1l8cfhV5Y-}wtd1Ak=vAlzv36w&)B{oRebs5oxtIcN=U zoB)-L1b{%Z#t@!|C+L6U0C2j<*o^3}?C&6-f>{Fk6K-)5M1EYqWS_X*HM@v?b`#m| zfsgS4h5+<|2LuhaS(gKHI7HSpF4OIs;YUR6QRc#KJ+Gt|IOl|(W)J87Zm~os>m)c1EcpvX0Y*@L}XZV>?Gc6^f-a+rA zPMaMmHB;S1!_~1=2`l;8&}PnYh0ldHwn`y%{rRUt{aAbovB^_YG#=Znp$6@4IxT2X z9CSS!0TPXkIL&7kz32Hac;Sm)JpPiGzU=Ckzv7kaU-jzOy!Lhf?DZSo@QeTajc@v; zU*7mD|KeAF?O*=-zuNS#f8#g*&2Rno|F`+y{?5Pq_y6HP{--U!`=9^I)@$DUmb`gw zb6azwxxKlgxwDDQQlljwN>r#xKI<>9!qo+)CU=1$?P_w@!QGxUUV{qc9jeYdniSpO z;HpitAp3Sa26n>-uYo2)wP+iAWr7fM%di;|y=*e~V3=NJ4aTULi5GiJB0XT%%t*i1 z0O6OatuX?U`)?8ckzuH}ZOssO?4gp@LnV!|)wcjXC}};Ce|ildYU6&O)p!A~8paD) zQCU}0KBl@_%F}KP@SCp2UcIh{39N0bR+Y`&Lt~@=7llNz;%CG7(SKH4^K?ynXptmM zF|_)-_`1t~+TtEU1Xm;5>lzp6)J-e^+2}!&J&E~Xm6(Rm@$tu7!Ys_;@}CSY!heBs z{F<_4TnUXKGm!cp0$375=6C--e5VmRe);d*mjrPUXb3CB9O2(_->+@-yYK#O_->i# zt3=0Ue7T77e^G}Yf1AWen-H$Dtk3ImzokvrXL|ou8&CcleAP49+u7d4hu?55 zr11R>`~7G9u*rU3BEK`LxXFG#!JmKKe%AZDr1`Jwh?_LecjI6m23y=&jfZ~?x&Zao z_7b4X)EnqExQJl@kr}EZ)Ea*k?Yp4N3@vH*ipua09Oz$gRL-^svG65Zk)+krUQ9)Y zTIjFzcfQYuHln39`ksD{8c7VEjX2QX@#kMgp9)Zy0o0*l`X=8wbBeY2g0)vNwJ{r_!>S(jm<&v zbw2#+iZRyXL2xn|@0Eqco???%f}ac+%D>7lUXk|v6@L42*K@lMkPJ}iD@^fk`Owww zA;Gu~`O;|km&kj-aAoU_&J_8}hS23F*nS-CsV~D?QpA0U-@aISrM2`uBRNqv^@%U? zi5C^db?jU;;}^ItkuocE^Ve)Z+Zc8ny1ayIafIJ>{QCFH4*j%#X%M;QU*NZ6zB#pD zZT?)}TsOGb8_!Kge}K)O-NK&c};m zi;Ho;D%+SA)yB1|iCvZ2QmV5C4*J=^K}~0VmQ9Hq^!yn(XhB^>3NXZH==O7=TT|ek zDe%X-V%p~Op^YhUG^ru!A_0)LIa+FS#jI`qrqpJw;&z5{9xS!FOxidROO-i=?aQS$ zm&`iObg7LTKk%k;)i@88+UUuGfoMLOT@lvjYo#`;XNBz>r8eHa_oh>dgJY#OVvNr? zpKq7i49*JM!=*M)pLKn{TWTZOI0e{Jyd4j1Zqwu?X6K6nvFI^e**3y+hKMW16I^W~b(4-|&U&zAyD7u%J=>9Qz6Eo;cN_S;Ta>#z< zvSmx&Oy<%9F#&1$BR+Rlf9EHB9S|Nt9idkf=%F=;62R06v!9hGr4xH3z-P#yjjQnW z8GKz?muMG&Lik@!g$H>J0mR-3swWEAPYFP1QhlL*tpbxh{ZVVLcues@?_h79ec&`#IVkTBOkk(7S9AhE7mO8U)M) zP6=@^9?5kKq+Sq~&QD1wm7)Sg-yER)CoSa7&OAjs!sXmcgdJ^D?pup)C z#>xDi+LrtNzp9>XPSRr!{Jh;cZd;oW-Q=B560{@kLvQ_1STfVesyqPklW z@8P!GwGM{2J!F8n-viQvmla02^n={@HnoJFrqm+YwL&>U`UEj%E8QHB{9 znT0d*#drZhA#kjKs>h5@&UJ23dd!f^YYrLyWU*ULOuTOVP7Pi567fJZQ+XLU%8dbs z=KG`Ny0-D+RGaW##TUVe5bpa1S{307NNY8}NqlwGV)MA<9g69r!% zYKoIVTo2E{YbDOq0 z=l$(r5|)>9C8q2dLNDJNL%<|_&O2Cc1+w_%i+FMc^M*5P>(JtRG=RAHo;Dy>r#McD z_Ho`gB`(Kj^QIoYJYa_}_crzPC5i^fY0@o&%c0V(=j$rJWbt@2uw6 zOL!XkdErU-50p$tc4yiCIZMgTxhd(eri%iH;{|IHUuSB-()J25H3kPdbXg+@V1@ZG zCBn|LK}-B2{q2G5(dGoQ4EQp57Cx?+7#wJyWosec>?fm1fBUSh@-rX9?^u%tKihLI z8^9PBx-}U5sxkLOPb*>*an-PRFPtNh&&z zQv2n7L8#$4BEJM%l_5ohkWnc|Wf=!1C=hP4Qyi@khQ;q`b@NF*^u=#9EkVzLs}w?u zRMvhtOx75#9K@++xS)-QcjI(FjdHKbPKB<_)T7PaY@anln~#>-&~TCJ0_aEx~&6%~R+!J5c@6Wb+E zR~vbfijgX_G(^eyfF*qEtz;+>qL4y~P>0YeJjWxNRE;fYBE5uEK=s9f-EeQ=Ie+qt zE|*k^xITdPef6>Mz_>)q!5kUFCC?LAE%u@xkl}rSOUBlq5tTvsXECO?sW751^8#jy z;JwkeS$G~a9;kN=5-cwpqI3lqYw#Y0xa9qX>`dMV`ne^5|6K*2#|yotCnn)kLwP9R z^=coyMT+TYzq#?LcRC}UaHhecTf>+>!AgSIk6ZY;>wFJpRdatwfWzia598^b`<-D- zo4a^0LH!jvCr~UmR|Xtse|lt%eIhwHy|0QIK)9RiQ4&OGIN}=yGI&=2>jR5cHE`mW zt|Y(ODH+VT^yzZ%4}Hg;rOFvEnvZLVvH!@mG>nhVwX_A~33A+A+)AD*NujB0>7D>) zt!rts%Fmdm5EWYpwf6zjt{Vg_v2%$h6zAn!`apoDjQ}QDMw>p-pK{VRovm& z95m3y-3Qp?JR!%#NG`FLE0qB^g&}QIv$rZQm!6!wuV;n@q!5O5mrAJV&x-U4C_;PM)je&m04lSX@QuL*P>$KQl@!U8{rHQ^0~W zd;MVcRI($JP*21AR6^~_J+R-?^(?r2g*Abt$r^HPZ9Ppu#mhNY`LsKXXv^8#FBx+^ zr#@3BkE&*RLm1a)TAjDh&EF_fKw6sQp$bjYEbU7$C!h*UTr=3U$6uBAe$9i zP>Kj)1LAKkNv&)6cj1Ms&3eftm*Vd-`5PJ0I;~edBX$MPJ<-+geQF9X?;gYc_O?)- zA4&HAZ*%|WEjywDg*dI*x-B#@4!|aS(CgETZT^<&(>#ff@Txe5e^VYj(9$523RyN3 zjW*>3PC)?&O?20bP{{RJ8hEAdima~vkOIQ)v4g!Xi=9ol_N6R$cbLFYq&-yL3Q=9I_IyUY0FCg?Ia|>iZ3MJ(E8^?%x-kZm#j~I z`783ExXBPDw#jT~7ff7~Dd4cfry2yB-ojtPx82!i{O31Cody>ha~B2ICZ5s7Lk&p` zqytX!7`YM}!$U0Zn|flWjUSoL*qwb+1{lI;<}!BU0Rq6!8?^Mt>-p^u{kN}|r%q_1 z9&N9G1}7h!#%rjY;h*d+uR0fTL8g|z7G6=wVWpmi%8?>ePzzFmg@|Baxjv8O${Hf^ z-G}EiyP-AoqG_loyJ%3B8&9LGtmFZ{I$(G?SH9i7uJI;AIz`TM#VGMd{cR1vc{NdG zTVfdvIez)7=u25Dez_iBR?!FAYY#zz_i~atg%e0r-&1w;_XB|&Ykq|ThmNH;X-Zw* zsxli4Xn~I&!m9zFBf`I7p3BSdg%P2w{pb1ROQWf2M)T+R^-H3!CAuQtGTYK2NBu?e z^^5T}IKDMYl9NxJJc73<59DS|BPcYpVJc)iENr>)}0GSLQ?V3$T?rln1{B$Z)j34t>KC2NXK&u#$E z;&!jN^NB?;Z@2KW#pF{&`be5hJ%S$(C^L^B&w4sCAbcc|qxd%=h);%wMi6LNC>Wy& zEjbV;AxIPgLcioD^rG<)9Ny$j^6_42NUE_CK|cL9U>(j;+LRy$DNm~I$a1(Xwh~-O zu9{dr6DDB9g79b{5X4tJ;l#v(l@iyq5Y1sE5ApMsK^CU56%hhIfO)n7ZCGumR>5eRs>}R>v5PmIsq+=RIYo*b+Z+(Dj zOBGAw=)Mv>Y>YYc(FekejE_DOqs}^tuyZ&J_3R)vh)R5}ij0o!(425sO?kQ6jRC7) zD8X=5Jq+H`#W?mp^z_%ECv$sCqVkMwzF2C*MCD$_Ero25K)MleCiU+BJr@rrfI&W> zjlCov&aO;(t%xKqZ}&3+PtH{!;)p4M#mI(%BmX#O>dGy1rCmsa zYwSugQ(imSUA?=H1)SUNJ`V$V_8*s9mhVSY3zZtw2!D$R-Kf#<<5E6a>Os>V4R|&x zh*JV;dx@h$LhB0o28s-{^X&kW?QMoPrRFs_j1&?UuA=gQZttO9LbA5;M#kyaHhxJ3 z1Kj4qbv9AS!ZCUUa|*$FU1mfHmu1Jpa<+lvWjK9uu-&&E9r4f-#Bv|J35&D=>NCw} z;f|AL#M6Ho7VdiiNw#o|W1P~$B`XFZ;yR-A_gok5`vE3fI4#F`#H9OuV#|O(T9xvX zT{u>$CG8)>Ca1nDIoga|wCwoU4~cn(Z^in^Mr5DMmrN_y(`bAeoCOsM%w+i|Hqvk< zILUqzt&@_ZShtTzu`Y21`^&qwtM}K5fD&7#bK+$Zi8<;lJ1n2=FWFc7jed=AkAZM8 zBVq6u_fqIFI&+jw^52e7yRiv^$1D=X_EFA^5zJ)9k_*p#^uRk$ea1g4%@|SJK$tVm z*zMS8#vK6?69;#cllx?e+nSgVvN-`bmL*S@Dt3oPOXVxlS1;AI*Lv@SEfojwJE{(F zVMTe773xwIGM0FVz;-rr#du^DJnft2Eq+J z?g%}aXcqtWjG}p0sf|W`ot;rN&hAp15b^yYBLl5k_Z*yBXE)%{lE1Dlsc8$R7G_ox z9r#@0S0au&ZCCkZ`WtrVNI=52+&6i!U*bsWti?p2@eQ?jE0b`ID32V=BfljY{`Sz7 zY4`w?*SoB1{1NC=-u$t9b1%-cJbYK{o~v37BtCY56y&6^%kdR@URhK~S5hTbn`tEg zfTLJ6TckR07;b~({^LJ$ib8x!laD>YZg;ednaQYy?k+y5tLi(Ve^ z_tr4!y-mSiSlsvYU~%gzL$$`@|FF;l4g3{OXVfqA(PWt!`}50;lK{!eY|DKETN%we z9|jr+5W~rHSbD-Cc>i9DEoQLEVFxU0J-uh3gje*y!}3 zogUb+G5RxENp^Brlh8>Ah*JbOrob*7OowCI5whvW<9+UNyx$y)k zoiaaPcDGIs?o`)j;TEEZEIEN;;!LTOA4gzsMbl`9Sx8AE9eOx?I}+Y<%9-D?V#XB7 zQ65d`@uslUU)239k*x|s*Z4p_&&wSibd+a=#O!drKwty$!?$Z2lF6^m7`K^GV5dgXTQzW1buw+O5lL)cEeDvnbD`Q~ z&B2yzFe)3m8hW}!%Ob1CK3W2KC}9_SN`tW+v9GJlF<+i8rOr$}@N}|Eq87$ay1ud0 zwIYRmzD(v}$4_J)bmdbV={#O30gM^uF`xkfCcHD0FSs5du92Fn}zr&41kz2KOm9;+}Ydcln4 z=X?v>=&Eh8z8oY55yrQDdNssmR6Y^@%I@rL3 z4{*429O|PUtRVaM1VBtBW%!qv;lJZ1JoOW_m6H4h42j*{g*ouZQPNUcSX+ki0x>KX3B#fShUaI?*VS7s<_&S43+w zkk=1m?iIvli>We8sOa(!vJ=EzW6K;*h>A&3p=4&*hTC%gq+Nlk+tBNy*yHL1_Ip@0 z1AKI6ji{dBWA5xYSjPP9FMAl)&z8Lz#-0dc+f}9-wi!?4-uCdE5xhRPF?nuh-E&~9 zazqAvMR+XK8-3fSVH18kz_1X%cYKR%%sDd1!yL=yY=sqrKZdzX+SvDW2L9tsas$^k10PfjF05?j;>-SsKm%}8}WsG_>V?nqz2*0$U~Sxt2iDW2*a+crV6!RBOC zx6wWt(Ye(#n%gYDhJh!-zy*>^Gyk@S=L#e@CiEjBoNxQMgnn<6Vw^B0uu45)@SUMk zyJOdDGm!x()PULWD^Woflef}K&7%XT}2E2NuvcdZ#@UXUhuTwd5jT*=P^bNg$!|^%r5&;zXd+? zLO|?@fWwL0k8T8^y4w1Lw`>p36@>13p#mX@&5XMUYvGr?W>!9Ikql5;7-nQ|BBx;( zbCKwH-;+ zOuu}JqBQ>`SyiVoU`D4<)l?Px^iNh(mBT=(GqX; z&lQMjRM?>KM!ub|u=JhIAS@vneXcur6q(YnG7??CFqvJs@2{}l(+x$93de()tCKUV zf?}$Iamf0fI^Wn{wZh)55Fp={`zNbc_>}mD@B8MN`9^q7tAEs~;5E;k5x${gpKiY4 zXIP-4h2k3zl5f;Gt~Anta}xM-HXs>8jS)DRP#B#d{-8w6)J}>$Y|DNBA6X`*j=GXY zT=eVdk~-)2Cwxd=_2_A0uV&|n=a%&=*C%u8j$v9tG zmGW_8==Xmr+@xjUf~vL!FhxT$U7U8Ym4R}qjqnOLl$3!oMW^;e!RHqCN)OP(^Bedx zil8?ge>|(YcnSXCN5*MYy46>#7{DK{=&&1spSV)~aDgX^R6mU;Qk8_@+%BctU!PDB z6Ja`&;r!|W)L$8FL3x$H&oi(d%z=TlL1C6+Uh9tB_hl=J>=}6w?7=*vd*ya>CRHG= z>3*X!jT6?A;m*jC)+uz$km|@zDTadVW7yRS@^t|qQ;>OknpcWt`G>tJ7AeRI81>qc zW0IApeNDt1b0A@ED*7qaj8R9WOt@kG&fJn*HdzKMepE9O6;DMC$7Ko*W&8m-tk_3V zVd8n>2xrz}mUmBt1vv-spqfE;_|u2Qq>_`sT^%Of^O{fM*jq`)2h2+HjvgjL7ObXQ z1Ku9eEyS+;7K*nG)b%u*_4d%($N8Sx*jt_ZVb32@Q~JB%t*fu*RRfd3ASy$P6*o zZxbZSXhxPKLwpNgOHA$tk?d9Z89VeKcd9Ugi-Aq8lK`-2Fyaiti|4ovHqhW?p`AeN z7+!V_`ndoc1y_Q?dsBNc4N$XC>n!}?4+DB^!8DjR z>gml(w0OZ}iHNf*{%{2#*Q_JZ6?_|nZc7m_TL@qUci3X?g$OMqKEGnpy5J`{jgT zqk-@RbFt)zp{OfRRfh=&^k_0*`nvJqrMYW7W(L=r=OT`y?jy8*= zS@22=Ib8*~H2s$#Ap;nKiF(!ZIT{f58@1JW2X)1Se3s79iVm6vJ9ZMPYM#;6~MBB1nk%wfkI6N zmWWJKuQe5ls|&*LD-9ZtxhQoD#W&U#ss;|j31ek-G%1+K#(Ih)uB}LZzb`pNrYdh~ z;VBkXtr=HYi)3PeOnRW5t@J=?g=A+Tg|!$Or+MMW{sNVqoxmgn z{4%fSpr0$9Rnyg>)^Rxx)OO*2&{9`oc}@k?8YjLS52?ukTx0QtOGZ3JPUm2`$lg!g==fBax>40- zG6AEc-iX3tsuH8a(h|++IDn%BXc|c#DpP<^xcxk=j=u;X8Lz*@6OwWq&jIkUg4Y}0 z1-#_DvDG2he&8IIf|--x%XUW%*Oz>F^cf5fESG1AW_ZZ0CKqA=vpm4$yE<~U$}k57 zK-xPfmz==u{xbKR#q>BDaAeEI{!fh=$Z2SvB@<0}3tj-;;e;6+u44v=%{Q?n;RWbU z`65U*GC!VE-~q~1h5XyxDB8wY<4i2`hkE`!Y|JkO#Ozj=^?CiBTbtNNLkLK~N(AwA){8EvJ1ek__7_+PIS&K5e(i2?^!>;5$3s%zrAq%(TH6QM{*rEFe}oIsYkTT<7H>+KKEK6y&A^G1PPWf6qv=HfV@4*(guvB zX(GC?D)Yd|d!!Br4~%>hnTT&C+TMQXnbQnu`l&Z-CHtr8>ffqn&8G zauyd1)MQZ?00*^)dAVS24p7)eBrBTZMijO27UBlphN8c%QXhzWmIvGyiM1X=6}Au| zRB;zalXGz%?bUK)F4n;vVe+;FRK`wCA$TVN^wBfAyupR05`|!@P9c~wg<4n7y9?N%FSEr8KP;5PEG}73WWgjB#`fIzZX%mbN>V4zMm6HZDCn1M znSNjZJ454Xy{ckSza)pz>XJSpO$k=}d5O_I8QT9?+r!Psxs_eNiqQ|p7;TO5KVY$^ zfxjkA@frl~OAtsOi4Q0vM<&6^w%j)`oTyWUCH1Z*i*4gb%`-W_G3eQA8|&9KuEv-A zoZ_sIyW;Bv)20Ub2yc-L_K z`rVnV-x{vph~EHLTOq7g_Ejx}MQ7HqY=8&!3m!@l1LDfo)nT{bVoGcdUg*lQ6s_z5 z-7S~li}Oi`(8m+X*qM7!j55y0bMj<)<;P?h!_rNL#$VB;g9X4c;WPjWfE^XU7y%s; zz#fv%JdHajpT8OawU~7Z=nY{k1C$}_IRbi9XnafoeYyfloxF^cw}!`UEJmYe97|$a z{;CUX2X3SBXh%Hc%7@LqBiVkEx>Ag~KowsTD&V~u)V%qyFn5wGD?3!I%$;E{n=8xh z&ta~8wR06pwbE|0ugzTn0GsU-bhgy8%apV~JZ|u!B>!CC)xrUyj--_IwRml2=B@7u z!yB~cD6|YN7nb7tvJ|{NgvU9(oMjm|JItAq-S36IZEAX$a}+XVy|`pqzkqcrxD#-z zIXDwT(ORK`xUwaoCWep7Ty!64Vb;KCem{)$i04wW7U;?oTs=t z7(g+U;`T=JJm@ej)CwX4rY~B~eG5qOG=cL(V>lH0GmW87`%^b}iuFGVj~mvVb~9SX zuN9>;Z1xj#C#ZYF@HTtsN1VNSrBi4>7#=rh>8PG@p~9ly7aD&{7hQF!kvd)K6Md(o z3_#eo8?ms5dE$>kJ3$ZdYgDrRiAbkwqBHD8`nVVAN0lY=w7;^wPXv)JZ12hzYg)64 zH7ZwV;VR}@(Rt9yKA}94$AcwB28Z)YBHe?M@SKs9L@w$YwPL8WLZeMceeN4ES-=|( z+35E!TWds~#sw=Po zSV#7C_}k=BHnk!TDF$u|z!?T;zH@%_!T?$1cqAE89K1CQV>no*I3Ujp6Tl*BwNg%j zC(4Dpnw|z4Q?~I!e8DMMy@+&5w}!E7O0=0yc}j0dmUUkk#-;>r#ATIu0})u{W{RFb z7Vik{jhlf#u)Xq!bXIqU#}ocAuZ04Bqh(6xbXOR}=A?XNxQ>t9+7CWbm-*WooBcm< zk_(iR^suM`|Cm~V3{a$iGPeR(_`z`C4Sra}8h&zj!cTa=M>w{1WoxqOIm$!2d00Bx zlq~%Cr*b!}@{vpqviIS4adApx&tY^!@<(!?mhCrwhH9g!cqC_Zc}HcJ!iI`nY8_s7 zaZXI%?9A#%Y)Y8c?%dDUC_%5?-6T1L>P==!hR<=^#99mD1*D%=b^@QJ`^_b&vVwyY zrznJk;r|dbHTAnWM9eWYtLk|jeNvWxwxQ?`lY<}{ z8<)vhL|(G;c;Tw%L5$ZEj_&;bxMZiJ(sfaa2me-L_GkmjCAx^^W^UNA8C<{^$(J@l>e``^c0!U8umzc7?va>2){WYNIK~>Cn5w;|10%12et7>Ejn> z%DH`97++oM4cp?}O71zHhSpnK8)V}vQ**cJmB5>UJU;%Cm%i-km%ri_uf*T_SH1c*uYK+7 zJO}R_smLFGf5OFacSN&u#N`iP**XzaYh&ZA=Y<<2$YAiJ=P=60c^%Q~M9)=+CiTwO z%4g&2A7e(#YuKDo{)Ff3%sn_pg0Ha$$z7bbc9?7y$^$MAiMKB+_}gb=wiXZ%+ND34f>^Q%oUQf z+c{{pM3OIUU#;2R5#Tn>_9Yl(ZkjF9cWH@Gzn-#X7096DO7?3}yCpDrOlkqRKyL30 z;Fym4VuwbV3|3sy744P)mLMtVx%5RK2fe80#)0+9O9J!(z%-2`mdI$M8bM$73v|U` z8ngB^rpdJBwxpj^<}m#n=LGrn6wuLOdbG=;Z*#9RLR7QEg}!%6EGaqvu4T+X(_NPN@d~v%j42z|*|} z2&4N^k4sE7p9|gdH1IP|mhK@N%f2#VSr*>%q2#^#XJiGGD0ou9&I?bGMIu#P>B+00 zDpd4Lpj)Wf>Hfn3Cr0;I$ikco-9HcTUGC_9ic1Dc-J8&TC9hD5)BH3rKGiiH-Iua( z?1v}|=ZmF1AU9Q9YQAA`8@Vd!QUMNlpO(#M5*nYq@S~K*XA^#bb>1J)_2s@*4P3O! zMDL&kV6s}gESvhNyUalftYAgJQ}s7cIZhAYU?~tIEbyO#Q40|5h;+PB7pJkvBP^s+C61}3zb_ss`YFC%?8dWE9o^^;T8 zRc5wtz8Ih~U1haRgLxYj)A({|VAHt3qquCodcrb7@`QyQ$?i*pH66PDx>}!-Xi~#5 z0{)`ab*o6kMFHA4pGdVZTU~PMfF!PU>LU1R0Lr42Oi1AcMtW!oZ#Rh}8I;TKk7>DX zxl%&XPe^e%M&^|7Ls)50xKL@kOG=DCMADb)2c8QGUk_Yxk-sYg?z?RdAaj5 z&O}qY9jRfz)-jb?^sS$iP|XCCxy1p90&t9yzV%ZANJpUP@9xl1s&E~sQ@C&%NT@hJ z3BmIv3LZ7t==@XM*6htRDdXB}z2Ry}8R|cbcG>2NU3L?-JBjgf2~ewVhFyj!xr7l$ zd7`C{HXE*sgk^+F_#9#IN;Paay8HLA1NGN|qQn5{i>Bwc9=Tn--5g)9Rtk5AiQ9H7 z8un$gU!8^Te+rz1kImWwa0dQPL;vUy zM9|wjfsA&ujsWA`@B~V(>=S0KAON=@O9=2TV_ah_RRh!$nA~BE<<&3^(yL!yEO3

;^IxFZNIRWQVW~)e`lo;TXMW~qcJ6%XOJDl4Q9ja_y&QkP#J^vD z#qL+W@|C~xE5G`yzxr!TOZpqgNcx|dlhjg@{+HkSEy+r{k9kS|@BjM$Xj0Pu_uA_! z(vlvkAF9twTGBWvDU*@jQcu&6-W8=H)pVpTA*rS#{avIZWkOP>BTW;Mx}>CUuk(NJ zkpD3?sY^~8(v!LbrA$o9w4|Dtl&MKSfd4Tusir2yF0(Y5^Nl=B=IMm~;#?XC@O;xK zFuc_1g?IbAzK+pP)DbSXp!b)H(rv#*>z3axL!Ja%lDP3i+knsq($p8X!LYBcy#)V& zUhrmS5QIQ4Zw#Fp)yL^Il8;Cq>+;}@9#*@m_7XW3Al%doCXM1Nnoo#~|ATds{i|v( z7WFIo@Bx0{ficJqf5~(rIN-(?dI*wK5NFk->QWOP5tJfP#zD1?BsIc8G&Z|LDFJdD z2D8`{*^N?y97dB@>=m(nsQu6EL(Zf%i>C?Ckvsoz*bFi{o0rEwls-8#?&t$4>M0D6 z??A%$s^le+#O~cS)X&J178y!sQjRdE;%Q1`eT3iZ!UUVdBd6Lb7vt_w)^uYWG-Jsn z0cWv+^Nz{dJj_A9TgE^z==~Bns5Li>i#ZRHl#J)jz++9Y;&pq!=Laq_l#I2kW#AS0 ztEvxtaKn!jh{|!iHH_mQ)cyG`MJmM@&ixc1z{xZjopkLIdrA&iJ$6>v_S-_+Hb?hm z2rHRl-yyC0$!HWW6i4(`=$Pl$uxd6L&%hfTN^_w2QRb6@3GOo)3>U@!p;SPgIKg$1 z185$N0!o!s|NE#nqNMbHLcFyi*UPNz;c;|pfmhNqg9LB@SAJZFM5(p*&~@;j!a&d- zE?#nImif96h%F~f-^OOcVKq7(e5?i*Rbn@Qz{D)}a0+7+NdZe#yfDGx2f~~i4!>FP zQe7D*>VlWzU`A7XF|U(x z3}}OH=h#P2_*d%1@zuLEWE?{-R+n)g(GS)QoE5vG3#_xz|@tikuBgE=qBL*lZkk&jbv!wUW-xM>F8;#97xB#qhzG#NvvgqG)oJn z)5~=t)d+GxEg*^06dxa9aXY^zUrVxFdjJ9)5l;b7j^y`=?2RTnfxev1? zIqpUY?ils~$?Or6G++p2INA_cSrcJsl8B54#|%DL-n=PIl{CpQ_J4YLS8t*V);0=b z%3f6{Qo&2DZ7QP#w)>h_dzIC!ZNDXmW-=Hp>(bkQk=p@vgA2rSLrAP8F@(qTRziyn{UDe8KMUBH z|5YwEmYzmzu1%N!x^=-+`SqfhhH@o=^^IYQ-@REZqQB|Z2;vox<6-=5lT>?7?gCWJ z;`)x=y%doxOY~thbjot zAB7fewO^Kui$gf=lE5?YF3SS{J}&4lrb*y6MLV{P%1VkQ`f{Tf^8t3SD?JMP*hyzj z8erTtutE=fdd;1(ol8YnCEH<9oUTjSB}7Ep34G;4VHGTZ;OE@_kp5UNrE`BA>e$hj zpOrdsUrIAWKOYNqte>5%YaIRR-UVN4> ze-bYn1;STon4BCg21%Br_)p+VRIreOE|^8rfl3Ps?*QA!3H6IdJ9jql?~4dL0Ut8+8NB9v3tBm3=Cd#I&DDfaBo6y0 zjaU%9fGw>lyVHC|i;XJc&v)(m*cp?wz&v0M6XqkSFrM!rVED|i2V>s^Xfy3(jdqLw zw7`{G*G-JzM8QydL`5wa0IaDuanRFT3Gyn`6E4=mgHP3pdBp(|`jq{8I95#hrJ_?< zo3DlmH+zvDY;wj3B~i=3G|zn@8<0ZL)W~70;h!@Ry<8PpZ`L9KjPMq9&z$jZ2SnR#+}bu(oV}!R{*?r2<|e4n5sB>!Z1(|5#+etvJC-Is_A0X1!Hb0GJyy8z{?TB#LA<{(gng8yR!vI$b zl@!9>`Nsg9o!fk>bgoE9QSxZvSbfrC@z-9$K%ZX107`gR&||h+|0(P7V(HQKqPz8U zl|aE;cq#;n?}ZjkpkUmva2P|>l0YFAl{B*TUpc80sX$?;0LlV|zTBulAsP4(cw7!X zcrqd5_##N z>^7~%yoplhNxFlv5232aN87;k!l+_?7u%MQV`Y6HQhU*nKa81Teky+4vEQrDU)B3i zEY1#j(QS_TaL3;vi>i~R6PWgMB&(y> z+B>pW)z3S!IvNDjZ#?hJ>V&}B-yK5q&ial}Xi%m*9N{Bu5l@DQ!FIjJ`G@Z$5e*2i-O7g~%8xpm57uFeBb_AiE+w#3S;&NWbJHYxFfA`nrBpuv^25!I32Z zjePX+7`EV)I|ZxpseCPgY3@L*UVF;df=!;+3ExxD;X7gY!=Ol1gdBmV5LQGg*d<;r zoNq-gQ71KZ9X_0?eaEohkWa~4V>+ICeL>L1KafvY}Y?XyXK(kb<6l8ZI@v# zSSFxk?oZGFw>wAHy+s-``af)yr_}V1(N~CK*7!@FB$6m*93<+!WzHm9=JDJzt2G}3 zv^NQ%+~4&zEClHB$_Mw#6bc*EpA!GWpOUj$kalmf`woT1EDD2B(Fo}D$B!%;dN1~w zNwfS}ica8J2n&qnH#?ZXpOGXB=J~wlG~*D&?gu5ED+FM?VPEwA{j+0-z2DnX?t@wwHcN2nf=W%Y_4*3>u!5|@GYlnI(@H{_`QUbQH$wJMe*cv#4d^~ z+~4(8%+fR=AdM@ez`J9nX3ef!pzk_zo1^kx=d1!$^&4 zKT*pGLhq1GiSQ?XGk045uB<-Q0Q4h>tPyAUEpM3EP}-s|NCXA40J6QQoa)NZ632imAz>fwghRbCYf{w*f|C^e-B8r9 zDb5FADD`YWQ%VQ`@0Q^e&!tk-l;eUKUhylAHQ=imY89{enhHZ1ulSZH7aU&knc|!s zCgh`@3KP8Iqn-+rOE~#hIu-Uzys%SYVU5e7hwH=xBW;zlzt;MweDqLj!}3vMru;vU zo+k_Gac8~cq?bQy4OHo&U35QBvAt6pduT+&X68rftOQYM504ye!enWZ6QGDNEM=)g zE>%9fc{7!UX1l%zbA#&PWAKqaZcuSm>;U<3-cTMCqsBjAcaHE`$b#b?x*1ohS>OEM z>IoP@Zc`-_$J(I)=l9j{s>g!C9x41#e_)XJ695C}KrIszqfF^c1b-aZ>hQF;ZcOFX z{lHoe=+rF42r@&33~btWMMvPSafz)+c3f?N;NWj#gXEC zD#E`mK%R*^|GWuQX80_MJB=Aooy$mdL_I^c2R&vgq(=_OxKs}~8uMew@jyYO2N{}6 z$PmrHoo?OBIV7af?!``+PyH(H85mg1uX@V_gw)J3vA^s4Gp$37!=_=_cGwpwB4!QQ z%{{op@DcpGh|m!z{X=q!l?g1$pZL5_H}7sZ#+q<83^Q00J_p&hG%zsf1fFHvZpX8x z)q=@uFLpERqr=#*aQ5y&vhrGcn9hdw5W>w{c-=w@h`Rm@c|nPq^9xg^cg6-xhe^m` z^WGT7Kd;sjCfah2FmP|Vg^9;NM3Cc1cAGJF4^Hl4OYs|pI(*sNZcyD6Dz!(1$xHE3 z*aehYd?W$IJT#dQ4dwL0E^d64`z9sarHN-V>BjTRX%kZmMKi?0#YT-|;Q^?Ui(yzB zYHO5b$;2o#k$k)Pekz_dVN;mzrVvF;`yh&0Z2vI54&LR?UFS3#nP#Q%UR=97OzjJV zp(;1PDnM0oGy4>D?Ti4JAb5HNcLWVC#y6+=TS(gkURh!WP5=up0wzp7z-_1t$~Fh* z#FoBtPBuJ=kD!7;7H!s)b=(`K$cU6$huyStie)~ejexap4)qq*f-OY7WFc0oTB!5Z zP{;aG3$fcB)|Uz~q1us9&5Y%0B#w>IX;*I#bu!xf`T@}1wa)K@nvT{$P5pWOp44(a zp_Y<%q3z9EQ^Yk+A$1@PKBNREvy4RlcnJccUt6;I_*D)C>sQ!`-S=_-UFKT9Pr0vC z{;L>J^(!LM-S;sPO21t=*Usu0C{&pAgIzza=gQX6TvOOOP68vGb}*fzXe)K)DBId8 z-%d%V@d7)QtD=#7zO99Xdw*_=TfN0@^tRvN}#xtSF%h zz&n_nqaS(zHAVtz0G1wX^ri$cC<%1}VsNJ9_=m0(k9dPF%OWyJK3d{&w}grS{Ax=q zIK_!)3Bj~ztGij}OsCs^uIr)evApahTHdj+yoOWkZhS+_dob-ZUfzjDr-d$?V#W6h zZ078qi}m64>}8RSHisqan=@b`Sv5-1>svK$2#U|P6v?V3o1RSAwmo7iuz+s0(v6v~ zoQF_XP6g~_V;c4lKWyc=T-nOG&B#t20970FU^nShW$>g^q2`K*Q-Nv)x)h<4kqD(0 z8=*_rr;sE#MD=2WIP}rAHaxZa_49)}5(G;4L7#0;oi^eN5duMC8o)=e18#>AxEFQ>sHP&0$Q$ zmEs{P$q7Qo^;pl7#9XF<(mXf8=*2GRDnQBKM-8+J$Grgh3ygBVO z6R+55L@;MUr)GWPvhCbZr?;k^CYz3G;08C{x5$5c2V7u-{dg_Gqy zma4E#)2%r~@Ysfh_lxvskRZ+Bc2n0wVF;;Qo~ha%8)QlQUlUoh!bXvWThycc3Lgwv z`s5Vz>Z+7C)=^PjwYYPMDsTRwKot+g4+vG#{?|kmt? zyW1eo|HMY9Fy_wvt%nNVmrSJa{8P>YDm=ea>*%#Ju;?euZhzO;FER9eI(v?ed&+Y* z89MuTY-n^k#x*ydR@msqlfX#F(4)Y}&Z$bjZdD|u5$UQ5=blO*t3sv6oS}Oten3<@ z?SD;V(Fz+ymLF|~e*X^zs(2`VK&X=Tzb2|^g&#gtd4IhJLkBY-5MDkCl@opn#GFIF zS2l{UPq0|TJxKiLQLt1s<+kjcUqciv(GOcn>dCD66KWWn2;5g}GR9;&E%8KjYI0J* ztDdvn;|}L$>lfE1>RZAgh8udxBLII0$~2u)y+x4+T)P%S#E=LtiWJ=k-AVM8>M#%@ zg6=ol^|k-9CQw1OjIN-9{1GXAdVeiN81cwZgdZ=5(~eUx!M#qW{!%l3iQX(1kd5j) zC-(QW?_W``zlwm+ZinI5Yd+bJDPz(6)<&PdR%wBL12s(>7fFk;3o3P$`g~#UKJR@v zkHs$4eG?_A{(0ar=xtbYS#|M6!cN(H@mG??CkmHxhU2nwDE(qcV04t2(u$=MlOjO| zL^#;>Em`C?JB^ipqBpFEUX%hlaX-vRL%JF8=njo=9#8xoudHxW>9>bDN{d6G%RA2( z+@la(tbSLJC_>WfLqUU0ZD)W$tR;t$<>Cu64-x9hi0K;;d77Q?C5)K@V$ts+_3oHAQ|-9&PRtotULh%n!`gfZC}vOo^LMQY~!k=zHe z6Pm<`-iV+RfJnlxX(S;+U0mkti;)aR30Sf8&l-w1(R4pEle8rV&&iv!+=Oi*#xlP} z+`8_!#Q-dK>$(!`PDKLd+GwXf+8ypeyLII5zt|SA+$$~Q)ixIG)O$isCObpidMBM? zL8#@t)ib!s#f9tw0u5zppkgUt1Pp|k-r<`!-p%IKkSNw-KJ2xYNO-&VZMG+Hjbin0 z-XM}P$ZJ4}xvsXEvsXPtp~k^t`S4Tx9q!cS#DC<1hbHvE_6WT=zyQ6~n)zwP2ub3L zu+C&G*IU0>uONpYql1JTapS-%kZs-@L#5Aa43q9jp7_Fc{IX0w35dvvm<&DPfZM!e zFG-?qn-H#m#@wlkVkQ{AajuJPa48G|d%!?sr^c(tmW3W9l!jieJR?Bxk zAG(-=;9MsKi|1A$@$M7x3J62!SFl>Eph5h*|k zApr+TM*80B2%?v58yynKA#r|VJ~6iz>QbK@gfZ}mL9&ihZ3yk2Jts(fSeb{Z$F{#ZepQ% ziRrc&lXJZ>J(}(M#sagfB)|u(WWEU`rlLZG03Kki9CInjq=B9s3IN=q5=j<9L+7i6 z&;*oFbZlqncztNih67OH)}GmzO3M{7}?WnI{?HHA^dWjxi{*6%k^l0if!Lr zA_F2xYAAGs5jwJ5LOX4n8xA_^8H;<7us7TFy?jZ>nOENzjq*pEBPuVNaR zj_*!%Che~pw~X3>GZ++3%hJtURY_6rUY^%->QNJ@x1RrD?Z<2Qi{g9jKCbi5V~ltY zDtJ0U1*Rkk=d;KSc5)V;;u)+ehsGx0b5B?qZo6R|4h(R7TYFcp?x4 zI>2{iq=qDdleW;R5|HoP3r?RhMix`73}|?L=*7maw}kg9|XYJXO8gxHD@5_C-v1=w&gKh*g>@_#e4SqX>JhR2tv%Tf z0I6O)-Mz!e5jOx>m)?G-lkC}@{tlqu8oGL|lGg1GbdmGquFgxXBe7yzZ#-`QG#L?^ z+($qb>(PGRTd|*!&B39U?dPYW;iCK93w5)3IsJ}M(2Vhy2vE8nFf@bn&wW7<2D8iq zafDSE^l^JY+EEcjvlPP2jCHYtdk>%lQ`}v4FzpVQ=#g%ZGT7acpjJ5Pm?0}s9D&e& zCEJ{fG=}80VMKE6Yz zl8sN;cM;w2FZaI^dOqz<0DFA^%*Z+qx`JlqXSJ~Tiql_Ht2jUhHWl^cTsV?pxM4o1 z;uW(c6szA!QS?orprI%;B}${RZ*-(PF)rY0S8-LxNPNk#k|$MhR<`UtGP)oM0w8UB z3{XT2xy$r2@|==;}e3+%QC@xvKF|FUHKLQ z(g!fRZ5|oW_IB!>1RVd2oNjkHCb-|67mP+GWknj+pern9T7M3E3T5OpE}9Oj^+yIz zP6fr%ODIwj@xCwwBN3vQRFMc)7qP+nS}Meb_xA)r?JLTr$S^oYsCAx9(pG|@f?aAy zvb0L?(QzgRd>{aRlNv{8gK=|@v*yWKeK3@_)sD-{Sx{LkVG&-HMT3evk~_q$M7mml z&l#Cfn&2zl&^2?KCD%;W8(oAo`%upb6V0J|Au36VT4(N~J9n_J^bKiwYYl&9jHW3X zQ>PXfNcEZEt0X$;WkmAMk_x`ww{6R}Gjnh5HxeJb2dGc4lOB)8?Cg=pahINDmprO$ z3LM!hhbP+HIjW@NN0`1jYrP8Pxe&V&G&qn!qq|)MLZYOm7T5*&yzC)+rX+44U5>D= zyjRYoiI=_o+2M<@D>@n}H$%@mS~y{3(TQ-88GBPc*Z zGxdZyoDXwyK(Db=<$@W*#Ev62Rxm+Kir@Qt2t^5#Z|FHGRa<{|zV#Qd^ErDv;{n3G zD~|!(8w0q}&c{+``xk5G_b-pUqHU#rD&WKf7oSA5)e0=R;1&SWXIxefC&_*;jr^vb zBbPWW?3G;L(%t%dbRW6h+L&?w!w!X|96OY`KS>9Am`7F64?B}2&1L$uovBz1%9RHm zAP{_ozBS5) z&KNlg%Y=OJHmk%VbhTLSuV~M9eNU!ns~ua}@TA;;a#igq6O9hdBO2)g(Tr#Bj*3tw zc@%jTRzYc@l!WDY7$kd{(&lNXPCzW>&5kT`xpXmMMv+etYdN^+9H3=NE{-3QbAYt# zi^IB!SRX7|8rE}H7?dF#$Y8&7fQwckM+lWvumLD*#{!BFI5FqDfrt-C<&-K9P6p-O z8I;(agmPSDG>70Na(7QpK)I#jogE8z7K*e^K$Sf1kKKt8aa`LBdsBkCB24L71X<`r zEZE=m6>PCs0lV8xx&G|s(F^1VX+B)fiz=4toR~x@i)Rug7SFS25;r$9DC+qQiWVPy zmkVkoBOgt;;epVhCG#Tr@Qy+0a7SbW>WM8CArV4v7B+8)-ndoj^)KkrC7?%jN0BU{ z_1Jljdt5nR8b)Cv>2xlVF1SfH%0w$q=XkKit~kTrBzCFfd)?k#PHm&JUEho?x~4H( zWo5+eg8zV&J&$;>EcQFB7*}SO{!@$P&;y|@Q@fuc2((N)>ke%Vm+A;dJBj~ZReRpy z3u)Zi-dvTJEB+NtZZsj9Fkr@|t%Y6bGij?|Vx%7>h^V+X}R1Io+_dIyjG z7I>zqd+Re~EoZEgPk4qHN`r^MhBNkV7_Oyh2Lr$Y*XG;^z8Y+6I8u>K#4VjU6E74W zU7#D{G-cqh5<0TLg$qW-VEY7%gg08s5jY-> zU0C+F*`5roE`(Oi#b_xpW%5Kg)_AW@4RYA`Mu8*!Z5VL6CmZ^<(8agZhVi)3&XX}t zhOrS^6-EL~cZ3S2!b^nQ@d}|+YnIuF!&Q1n^%K1d$*K2;3GktRqmIrbKoo zGGeT1umFty+9zYIz&QCl6$x=burP>410iRAbT+f)e5PI(!2Y(*lsKGq0kFKz+GS}q z)4jsn0Ad#r6n3f&202}}0TOn%2}rP~s+Zvn0h-8?a#igFqrZO&8+ro$nIvo9>`e24j43ccT|d`H~CpozKa0i0Yu6rV~t_LeL@{!O91EI$6;A#j9V zK|a-V-$|jo%m9B30AdjNx>CU0;RuG&dfGF64sao^SZGf0g_vNoYR(vaU_xz}GzEdk zSEJ2tk05v=^5M}?CKCA=!~mJriF^zX+e!-5L*!fNdRT2A0eO@CQ^NY&tU`|U6mmt9 zqEm~5V-^a@_EIb@Oe7@Zj?k|e+|>?=jVfc3aZ`^=qv~DFVa{{fdI_D+sCMCc;Rx00>sw%Az{9j|J(Re2qWhajND8pz4(33C6DE7`qrI z!7x@M`O2uioL9U%t0-Y#Nskq0NbbohhBG9~8`&e+9T(M1M?*+7|Aw(O@JBVRZ*cTt zvN?qGhgi93+XvhlmW62g@N*ht#qr2G&gg?uxo_Af8gfEa9aE}cOOG_UN8Sj^xxYfc|c?(Uu-Q|voCnw%SAasAh} zn-oALwXo#P6*0wT$mR}miH>5fg5A=p;ZHOOfN5I7j$BK)C)pfaht9E}B^*yR0^}!h zRcy^!Wqb2DrFi4l^1Bzm4h(rNG-ZmQYVnHD&H-{nkU1!XR4+upmR`g{ZoR8{Tx^fJ zFj@BN1EI%z;&9P&k4qIj!VP1+n6FBDpAv(7za9@}J@!*}#Z-Mb2*!r_o*3wNf@01d zJ2{~muZ64riC2b&WuP$mnqw)fEMYZ#K|jB@d((ZWR9LChx{gKi7PN>CS{7Vzw0a5Zc)Dh z-J3Xtz{QvmcES@1Ci(K4nxx%?LrC%F4$LEKL3Y5BhUq&HI$B4tcG#-ytk+Hz8Z02% z8k%IC_I)VyeGY=K)j$bhijWZ8DMbJ=Tj_HtB6-A<9ld?0BmW(%nx^PF{S;Q=g_GcD<4A%?Z*moU3!fofC!oM<-`DCx(G9 z;7myNCIUah4W3RpLCNL-C7a2?;>ZoR-#jeY#3?jyM}fiOdrJrYk+}vsm*drxy!ym< zS3fo+_({3`Qb-0oa@-z}S8SRgTnHGp!v-`-JXJaaNu&-Hwxy7wbp#zD&@?$m|cX`*{6dJN!H>q-ogkCGgcN%C5#w?o)KO$JdiWB8Q zGV&-4l16PcI&Expw*{bVbed8hn<|RRV>*4zl&xsx=n zP=Si@mEM=s3vq9N#O4zk0*4JfP1?E?fKW5wyF9sc8L!p<9wGHxLhCk8JsJ?kc_o@R zO`^2y6)UQacm^!_(8jMv&qN*wXJ6LQdeOy! zJIpq)Z3hO`8tsrq=&5UI4W=OxL`3e;2hg!9^Gh$P&t^QP2}s8FtC}f}+*(?FJ0-a> zP|}E|-_NFt8^1cntf-*lz zkhUJ5C>Yol(;U`3fq5ihOhj#;*9Dx~L66CipCOw(S%o1zKZyvU6|!s(wxv`WvDNmm ze6w8-gC!vL;cU(<#IDTMNq|i3Vy~Lfj^D+?qfmc|*N8(nMjvmR+3tM~@v=lkhaWTGWMxg^iO&0%0X_Bu z0~Csr*T$y&@1B6(-xJVZg47&RFJO)9NO%N`g5WQOOd@%!GJ%4Aad1R^*GA{!b!yDG z)43aH8dM|UWUuZ%;6`DbOm#@=o*6=kPWT&VYivERwl=zOPR99>HOAQkH)YIkiy=Bk z+c#vH0->=Rf1~9u?~xO3Fxh5)l*_}uoyZZkLj=dUTAmd*q7oVg5XxDJME+qiHd&q< zd9E((H`^M6HT>0y&OPGXzTmnv!vqD0&X^=TO84q`kG%@%HrY_fljNGUk+4~mY$wmv1ZPyx+sCmq~pcRGBt z*>upATGm35EXe_pm8QI-af1w@5J{pmg9okd8Z!utG9k0)48E;$2G>NVFFVlV`5Ui9 zr*=A6jvde*4^m*LaOj84)^jJ(|e+Fde_9nhpHxbsuB}-^u$EQ zX~z_5f7dr#np|oHKD&@Q-~_*jm}>U)Mp20|DQ((0YqZxqf*n6^{wvIBUOb1A}hVt z1Ru1z8=c?{a_=L=OQ)73S|el48EVj5JNcd)o}s6N87LD+>`V8Haj2ckDn_kce+SKC zw(DDZpC*y@<}6{Y#gT)*gEP~tRvZgIL%L{jiZP%^(?i3I)-IpHRc!_?ZPrGc5-ua! z&Zxd~0(S*>PzCPWbTe)&_K!;5#{LH_=*qH{R#JJCU7o(E^#fZ2H>G`^hjvsK}La(HzK~vm|eASRrExe*bQA)|3?ZbFOf1#srB^bS+r;CD&X?T7xh)UCza^y~Id zUhPgA2%vhOc6Ekjb~_|f!Vv5UHvxmHAOF45 zyxOUjek<|i_4h$Q$7B*G0jNbc&J-Hk$S`bi&KM-0+b|?wS$_>eavmp<{$BIL%oLB~ z8wMgs0y36)Jl|Y~H*lcTVKi|%fEb?-7lwA;F?6KssoFO-UtGgw2I_|dR}oG@^fiSH zQ4`)w2!BfP@rBC-ht;P0c>9gQUfZP{XEe%p`1a7DoiZYmJ3FV0{9gOl_0OxV-QRDx z#;NtzP$#j z?sVrbSfJgIuRh!5tCCatcDf?mzT zrw@gS*-3%V@vQ24qyxnrW~%&OfQ zs@Y};k^M*dMOr#J7x;W0@L7&I;@(xBbYZ^do)qGy1fl8Ye*_K=MOLD;#RSloQNvDn z6_O*v6mL7iE+TORM3k_0Q?>)W^um=A64O|dzQj)ZbRBQ(`T^Q}N;qhF@rnxKa&xE{ zuV28ng-{@Ku=TlS5bFcIt{g$0g~Ki+i$Xl^Y}`$ti$dD1nK^-bq9`k|_5>KGQC)w3 z7$>wbvLPhI@LovBlqcevr_ttoyh@l2^M!M&u9s}SzPa99<_VT3DHnTV`5mrnBil^; z8=d6ZE8CL)(O)mSP;3d3iCOYeA#SSOcp2Cvbq>3B8z)>W^)3%<*%_BzMz*QJnfSNY zUJ=1X{Ntu?D_?XWq%fU_x_(R#=%Q(ajs$OUp>>ff)M-*@mNMb2 z$Ehc1=-^1gJ6u7JFgJw0?^2E}8@D9wY5f52O<5h?i2eGxC96{<8LYf3J41-$aBjgf z$zbJtNCuB>l2C`W=jLBfltXnRDI&ihHX47Mkz<2tNO`*b@sEGP6V68}QUpok@4^c& zM4&Vxr6nCHVx=!;wDi+1MNZP~$Vhtm6<07L=~d5s*0Y}doaa7o`uWd)!3(c`(TiUE zl9^8N6F>2jKlRf;v-71d{n>x_b3gy@|HFUS^$WlFvX}qTFTY~gbevkbpaHwNwS*OLzag~>>Njge;D%zLg29kV0(`m5{d z==!vyUr9Rp2X^#IHU)|`!Mn#BNoP`Gx0XOU8$dJHZp?un56@2cYr#ImW?rF%_7%-} z2|WODnyw=efaKP0H?OW;iU?h52((lEG6y#?fd3DQcK&h!VV_aBzh`?dM|*&XYx#G4 zei_>@)Zn3BC*{|HG~oPLd0u}p8SejJJHO!Ob$2pU`MOI-ffOsuaBwN(02t86#il8f z!F-IIhbd|&q!AepHS~Wk;~BzuhD9y@xzc#P#eRP-jOUwt{&#DR=dI~@el{7;->{vR zy78oVB42lA5q46R+q!=T`wmhoWvCz>5*xBbb|c)rele=>~c zYkd9*_QaHa3^s@1ZDx(tdQUpKA{pH(TkW{f?M+rozRu|AqVZsKJ9J2ro)G+2m8HE% zwu9ActHtjx*z}808JQ}?%JL;WnOvr+ZvnuN4gC@9VYf}<*LtSQ+?~KWOb0j8QZUU5R)k|w}%NZWO0QYKMs(NHV8Swh8pbw z?$pl`@@KF+WDo?6fZGL^P2t^@?%g%B8dbYb=Ka6(+ZFZ=#K&k*@sdN*!fbKPtghy6 z^sXCm4}T$@7iBE`YIgpZZCtj_$s$|{{r~eY_Iq@`#ANQ{cF8urDK6X6H!IXzM-Qt zp^`x&l6olc&!NCS>av)OzQ@?rzp_=4$U~*?hf3Be6xw*P9}WeqRWq*cwpM2;b-Dw1v}a4;0G7J^;iy}TC1omXzoG}iGy$c#^_;SXklx)~AI zl@a3}$EZz+lZ+T=f)LlOIM?i|m`_UQm#|vs?5Ifq=aO zr0q>xHcmL6blLC_y1lLEvgxS}5M`SKwuyXJe*QE9OotiTyFCoUJkx4k#7ac%>|;AO zo676e)H_1mirZtk4uoN^B?##f2dmPQz;;qj%cH}__#t|OgUbB#oy$eCJLDpn2?>3TZ^$ z4DT9Rr=7gPd%nUwtVk1L1Ov#@!}+k}cD@k{rdBK^aZG~;eFY;Gte_{>Jf*;dVsc`P zo9k+|oKSGrVQToF)-OV!Az2V|k2WQNBq>7+FNMTwM=hd7vHYpN*E8T`wi}vdjU>4b zN@kMtk;;@=ifAAuZ%BihZwxKk*n#Hs!;}Y(K1>--EJaxV8X+(O1q@7P>E@oZq&9L; zGTTqywI;Ml;wE)d9xWvCfm!=1vS%n!Z~=t|s4SSy4Hv?}ZGbws(LKKk+z~aoHB8I< zW6NYrNeN+b`k(xT(*mTCkxC#F+wbZ7GV{@ELbsXu=r>EZ-(gSSwp6*Pyz1P{n;n|i zqJmt6sc2!w$7J2o@cfmn*pyrPX3}oVJlg*ObeyOM?8u2_NwLiPwPov8F&xS5HSX$~ zHiKT)ig-EV#%nwNa*P)S7P}vs3?qx@@>Oh#ScL^SIo=8OENq+0xW~3PkAY~vT6Qls zFI8R<`pK{LE43M($=)vRY?h}k!>uopJ_QFBJR%`9d@b=Ze61?uvAVb{v`o7Rl4I@zD901D`BZA^Yok;~hVxSA-WZtg+2Mw*dK8M z`7+q=Y*)%aTJq}JG=4kcM9*I4#=EQQ@#}p`Kr}g~!!ORsE*Z|H7>+1Vwo)}v>@t5^ z3~d>%{&>LE7R5Krmn^o2&uHL21D&#(1Gkz0x{@5QE6D*9Og2)IweB{6a?ZyT2w@Y2 zK{7s!N+5U~gbEq=#dvk0V(uQ|PZMa>yl!&95K9av5RtA^guSLcKy_Z~?60By09rNxJBjd*)G?u}vMO_Wug zvs;mp2F<#8v&m0+%DtgAGaH=G;iuL1%9;g1^vzi{iA+kX$tp!0?5&}i85~40S*zNS zteWVqenW6TLMZPmsG#05YpmN29yyCH} zVwFR-n^*k(tYV@f-yaIRN$o*FMgCG8{@t8uB>w|1+*HG#slu3n9wP0134@b(8gTL7DTa#CKtGP-qHmPbo2VJ+DU(#%G5nm-m4FQgyS{7N zG|*$fjVryh$$B5lXaD-pTqY8oOC91^GU03L5Wa#<_&Rk6t(H^LN3KJxuBAhGNY9!M z;ajw^pLHFg*DU>T>kxig`s)xU9=Q&&oNt)dbbYtkhS`t~alhLEwy5jWA^w1OVUC_- z9U`Tp?iuvdZpF-X3%aD?j^@pn<4<~$U5puN7rYV^?&oLH`RoZXG^8v@=D3>}Q#Pha z-sXd{0SjSSfZN~oRctOYoR3thMxq#XRWx>u%@Ls$-6wF!ic%9nD zi}3n6rfndvBMKkJTj~npzX_@dBW?NmS=u&)f03?^i^d_I5hyoqBL@#QLfkJS5*eG)elp^RoA7#wLBLkMaIyU%emF_TFh<BwrMQ z4wHTVhA>gK?~wqHsij&Nen=Ofem_M4Jr$rR>J(LKY$87o6HZK=>Zr(ClOB+B_%5O&)iI?rE_jQt|g%yJ+^MSvcHt z7F4wsEH+z;{5D&P{MIy5m?rP4vCS(6^k8Q@BF-f|o67Br+wOJ6ZTI@(TsXG@xfz{a zS!rlE5~k8Nqw3%S>9pI1n9>>DH1a+s!IEXy$gx~GXTPU(Yoa^>XzO+sLr3OKcskZx zT)ec%aEkzX*&A3KZWXM{HRby`l#r=6LFY7hF|G+-35QySn zL$~AZH@cp7zX8>Z`wduj^rpxTYq+3l4+=ZyzA)3KQ8WEw*_xpBL!EbqI;Qi>`6iE@ z>_;&;)HxRFSU+kf0K%z~@0o=nP^kI)p{Dhwrhx!E#nHF%*0_6gX#w zf(H`ebWKBnuV5_dF*FqTuFsC4z&DraJ)e2}Inha=ZTwu#*>0R$5v&R?#)@xJHCbRMUH-vZ3&Uu*)feyG>4>KXq&?5{ckdP$GO4b{d;hC{SC=D zkhxoWj)oVB7v1aI3D~!0V8aaV!M1C#$RJYJKMm(%#wK(-%K-*Xf!G=13-HQ?7eL!U z3SIFDfJY0b-G$J^VHGU+b4Z1E{v1>;&7T94L&Z4b0?EPf+?*UP+6Ps<;B#ZLRZJZ; z6#&om$&q5mL3JbXdu?)4F?~=SQheS-YA=b%tp9FaXq%9mQRU)e@zZzX$jmyNkb}P17^q7PrnfF%an@m? z^`#g%cyb zv+cn-JPs7~Lm&}@Mg3s0X%@r*zYZ0HEICj#53$^k)}4coP(HB^3+oO<4Q*#kPWAl> z`=+Sa0ItBaG$0U*jtTNpp9K><3X+4L^XQE4YxF&m?4a3s{O;P{ZycbJ3C1QkA*jPNMdPHfMk2JjD{>n;Qv+`G}L9jDD@tkiDTkPOR0(xJ-T;aP#fQ zK`8cKK$^*+x{C{JyWN6O%u2U^$1idrDCtmgUxF(&_Qe?^mvWh z!cXAT0~i+(elPyZLM!!G&~VAfJQ^xd384GnW_xo8kLatP7Z)N*`XiA^l(sg}v=zc|m zj;K7?UdYYUZwbY18%D+5)|rwaJL!tph6a}$B!JW_Hn4K~-v*%{(Ny$phx=XHiiZuD zd@E9~iKZtoq9XzRPwQ~Ut!O&43lY3*N@P+XycuSl#A;BVcBKI|OP_JifSk`=$5m;Z z#j}kv0QR;3*k=^5CkhTR1%?;Q-Gkuu85yA-ae5}OQ;x2%?ea*%m9Sz6_tRZ5^?t}b z2I0nRW0-ei63qo2FSr+yCK4|e-3!U&hZlwfVc72o!~U!en~DqPkN>?!2*wT!4rgqN zF}|9w!`~;=W&vlC_-3D$zfQsnr7GNg5GS=XXt@S-Vd*e^;`gIJLam%798G4*X*@o( z>zx5sGd@{zrzNC)U~h|V(T~^*r|%!L=dKn2qpMJ&WW*kCY}Y8(h57ou07J=)D&sa; z&8q5Zg{tokRby*v5>8VQKJ^EoqFKqroXQcOa3f})rYHINIv(m7tP*zRS&zYKmm&v1 z-y7-~pjF1y)jW*h{h^`(DiUKd!j-(@2eXPnY<%kz&xswdF|*eHAcXC%;m=~88Sl)S zPAPohu2ZoT(pHEg^Ae&UXXc;CFoh>OQ4F#e!l3yl$^UR%{)#ItTmhS`w{W(S2xkm! zSVK7TRg5dJiZPLraP~zi9|%D3U&kjK#b!n(e1Tsq2m!la5?D}FumFS}qTHcw+VitQ z+m0Wptd)y$*IVVBe>@Y7B%+)W9h2Q4A|jZYgHY*?o?-?#$P0K}_4w(Ty3j8mC>l2RI-Eybur4+!?WQ> zDp=eSx;Mc>gClw@K4Mu%?7@slfr!$ZOqv+Nh=iQ5R4SWMpAOGF!^%>*P z^71;WG!)9)u=^mngV3z4GJ6wu{_K3yuYX2aPL#fBjm zu|k6hgX3f5Fi0USy>z@p>I+{{X=8VpF;IT zOj~jS!l?2%4CI>pQ4CU0jo8Eh6=(*rKnJper=y(@lQLh#=SGJiG8c{(3$v1V4{zL0 zZc)q=MIkS)QVjABl!5%iaSB9EI9%p~E>xvtN zR=jDQPbZdMJV&}o&$7aO{}>O!sniliF^^qAY$&M(ZV}d7ZN10@lN3z zo?X!%v?e2r9}GLn6dU*g3{%)%CNw)O!wJpvPR1nCcnl)a*h3}KunUk|908#>2<%#a z9Dws@faxR#==quBMj2>tqWrN;Ea!QL(c^wM z5JXv{*8vee5eB}fA^sBakVvBy^7ezFqKUB@_JGOq^oz2yZ5dCyJ{{`CVGmZ$n+!5} zdnME}d0XXlw?9ozH`OEz@bjUb^;adQpU%bYKMfT(Ca3>dRx!xwpJ7_IP3tg=Lasi) z=A>$5(L^3i^TT6Bd$`iSkVwRgw2xAgww3SUG?5X_LHs+^X#%5gkX`YO|2D+M!3@;m zWk{Ub2fDr+6M=w@G)1=PZ7AxJQU3JJ~~_sz^wunha1CXo*Eb`6}Uk(gC^lWnn$sr;%fMHUEeKm zLDZ)^WQgB~*eLC-G?C)8I`(KBVWgpw0fp}f!^$#Peraf(2-TQr@Vxnj4ygw84;fl{ z>YN(e7UD|})H<1<7A~HRv;A2(o?Uy3d!0!$kqLqS>@*zHb06cyKCu^XZ?+*|3{WU5 z#$XDOqGS9h-t^EQTu>I)!PAsSx{;ie_7^2(26xg9*HKIT%Sqo(A zA!HofQEgrbk3k2^viCA#exKjBKl_g)+7m;+BuD{-AP zeDCh8PN3GmLu%dcDq3u)5!q0Z6}I>G`Es&-m^~J}+=85Bmy~B?mpz)~vs)e!&Q$CZ z?S(6XAW*gQIu2+?UKM@9MB*+p*ZU`Ru{02F54)WfA(G@;j>>6HVCPPqQsG4ed@T)= z0X*Q6#}0?1v5C;cUTMc0HuuZ|Ms9JG#8C>GH38=oWE|;=v03U>mABET)i9@V&?&+l z2xEvN>eiY#_G>*PhU82RIuv@aSrWR8Maqq!n&;!2bs&e!5oFX=jy%@nuZ|_IN?@?+ z7Q;xB`kh+XiQAMv^XFDo-uQD1B)qYMN>TZ|8D97CgOfZT(!{1k3c|TLh>BPkl>;Z6 z#W*BEd>kVqLYaA_3l`bB1?%V42x=!>;Hy{HHgd)v6Wwhg%1l2QAs9zQ*b zv2Mhhi;eMPx-pE+sA14Nv&^FDH%rw)q=(!jnd4QG%ld;z75*t)ljf>K!7LO?fPUO9 zU6}zKUJ+G(*&?ppVT`3DYXA?sbeQE=&pPfRUm6Cw4_~K_IqXBAI9?3!$i;{MGa3(of_C;{sEiTxY;74Lmw-;pSgvwjvMuQ-tM zIQ{??PJd&v0#&=o0LhJCTQDP>6KgC~xjDdY#xIBkQq+0P$Wu^LsjX5XJUUuz)|h=p zQA*@i2q)|Av9C_?bZX(W8wJQ7Jy96}x+Oqo#~qwANwNYovDlkNI~U>~kng66M6^YT z8dQM-uL%tr3Mk#rP~i3+1$&^to&AbGmMHLA10+WQN*$Fbuoz%B6yO;P7X4vBf!77- z3wT4z-H53&5f||zGP`L4b2(Q7E^-vQ|IU;Oy zo7AZj?q}MKOK4n%D5{5;_nishn(g{F3~MPXp&b9SOGF4pVyo`Y_mKp_681Ox~BRfjP?q2e>*(2=TF z@C&gQ_=zA}aNL(41)^A42*ow1_!qVtx~Iej3&gOuC`A_-S`1sR$5;YvxSG^WgI9@Z zslb$9BYHd!lnd30;6;b{-mSy_KKnMrnE4fhSo`d78qL z>@9g}<4J}uPvdx!9VSm>c#=&fPc1yjKI0SinYPFbT@64!AYiK!FVk$30-#{DXc|QF zQ^Ap+3XA+yK;)-FAwLxa`KkT$r)+W>{}XPo5N6dVlw<8q3Nz;C*tcP^g|K)mcBKuo zTxpPbT>#qyLU$t{#F|3eZ2>;x*pw%*7jvbt4Q#M(2(xOt0e|icE%h{A5SOHhP;D`* z7MT2dc)3kK>xCEup|Vt|v_tNgvA6vpttsvn4JY8m)U}k$^QHLSaLh=40wuj? zElh`s+^NT4w(EQUa_!<8E=Z#UB5Mnymt-CH1`KUqOi}D}%mX4e2mLzEHRsoH|5fBH zzMg_bI9eqZ3~zv3MK?7~9174qSAbI%4w?qwCK{5svMFv!0U9X9y@svaY3E3y?Bjfk z0Y@3Hhu21LM4a=h*n?vyU?0eoSf>G@2ctNXtQt-*1cyN4;_1F4%Sg4q>l-i+NCW2A z+GwZ#NPzj?qXot{kOH&#Bp~`&Uuo9O*`xm#v;K0-dau9a{+#nle`y%H&;Q7nr{2rh z{USMIxb<{LSjGaz8c4lDsy|2HpyeZJyHw6Qfrd@xBm8MsIPj;1U-Kv2Kx~FThZ)$c zKZhXM+0Q{Wd$7O&3?BA&6!vTTxk+;(vcQPuMdZ&GawFOaxlJ%yq2^ZpV{#NNUIIRg zZk>Qx11wn2yA8v?!e8S5lwZT`ZS67n<$>ZEI6DD{0gmWFH&ofeUpUP&sE6NLJlA4i z^7tFV8SsY??IzF4A)0{QAcrF>;MmL@rCV{PuW&vsTmSgs=QNOz;{Z5gosG3+#y`yx zSEwSx5(7NY(kz4*YYB<2xIC0-wFhzJr4atCB_!tIvQPqfBc+3)K>-^MBlSA{H*<`% zbui;}VN8tR|43RnLGrS>7?{}7X#=3`xN`9AHzP?PWOVToH{kXn_$^Go{XS4E|2~Q! zx}sDBuiuN;qmbw0ng=Gf7Rw*T2Y8p^b+$IJctecv7{csrqsw{=9cEh)ZZgp3C>mJr z0j$vo1hY*zJq2lJNL*&jnaE(7E$v~MMv3jX6fat6!Zkk9b{0(xQN{xlDnZ3#L-gUP z-IE>Zpx}xqm18OI7T?TL93u`?rloX@gQYQU1xRqjZ-d8fD;wHoFw6NQoMceY;0G!- zhLLP@BeAL8oIwSgbFdF$Wdy3h3@V#>Ohz>G4NerH+6oyK)9ax62odtB4k}>#T2NvC zl!_PvY|6mctdoP;j=*RF3`mPxk--#OqX}q+>DA9!Wg!BV z1T6@YVMa4iECWiDgdIN;fH!K>0CGfWmNnKqxw)Rmm zHnG)xwn>RU!v?=iKU3RHJ3(z%mvb(?xxwiNKhyEYF`lwDpf;s#PK>#lJ({HUomK+v zo8x|SBL-$+i^#n9hMr4|6Dn8_#i+Rr2!2~iG~O|09}TZ7Ws=vX~!7Q zLU%eVc@nTp#JxBn0fV~tu*XR?*@Dswo}H2~GoY3u7c7e%ft@ZC)|X{`)P%HKE(^2; zKrB1x%f0|*8GY8k_VuMn@`X!H3$2<)8J^H_WQQlfNvMag7UD;SC4^@(bqa9a8(--m zz*p`B+DZJjpX3Gw!6a$mCgRu4p6pF-D0AkbF7zS2<-v#iOeea{A9cOpV=9pxZ7PLIs7e*|q4#BV zBolAnI`7ZwX!@HtBqQzTgIOI-f3qc09@07=%IawPo2`B7{Bc%CkA%cim-h3~td1tg z?N{gHSshJ$({DVV$m&Q0SP?}I*zd4D4`y{FwxMtiBIttlJJk79R!8h8@nv@QJJk71 zR!5`0oK=kd=A2Y0^0v?nu%yE>(fmB zMD&YHFpV{n&xv@R38sIJ*9>P6k;myV)J*;gAIkD^Su@!L*+4WCY9a#=Bs5>8730XB-EQ? znLt+PgoLV6CnQv5osjCcX(p1~A=gaU`5KxD!C?GK3?HB)7`bKw?T}!U)i#QQqM0Bv zk0RdMn#s3%YbN|up_vp*TBlM7N1t8>hp9o!Qb?>6*!}lP`I>qOyUK;@Z9%m`psSXt zY(hkES0a<~scGm~Dl1dC=jU8QL4+$mPzKJF9)+gIfQLAt_=8S13f8R9DhJa?U4p2jZouLtVcsh>#RpZN$adfLrLqbM?*>LtVcsh>#RpZ zN$adfLrLqbM?*>LtVcsh>#S2lNvj17<=8g(PS$fErO_jZ;gP?GC*`MVH98*|`d~L@ z$-!}+93R79p17yvG4WTb_jaAkCkhH~9}XTcnDJ?4Zxjs;5MW#hjQkq24EqKMI!*nc z)g-RqL-=P3)*bva&Tvq~h&EvkdJfNmj=-BTg%lOe!Mji?wgc5g-r9vE-IR5c0n zlpKHjFwI>&GY&SO5u~t<<0qp4z!4GXi4&19>%%`GRww4kXVUsncuHV?L|Q-mK;l3C zQ>V#Ke$`+}p`PKL~KyQQp$Wt2hZ{XwDotx;uRHwnf z;i7f;w~zV*Y?x6oAr9xl1Q_fvtzZy0Xh0rzNpR2GrSoJ z3=UkRqLH(vBCfki8Z=pj1BE**FM-upX+}$=)@~T`V2#93WX9$00U3}>6AxJjkb3nA z3E&i4MgcX9_B>Y0Y^`tsT8!z%@ZpJiPCWDNQTQgA_LjWqYKAsKtP^b_uGIZ^B`BZE@|j*jS3IyuOb2D`P{t zG15zBjwhZvCg&t{U(SSBF4hD2|2Ws+63`4kPx6{%QVH|?U!xN;S1 z?8?F8#4!%xa2n!q0PYmP)f77Jg0~Po5lm9Yx}NTtT%vqDwrC>SoIwcwT;}g*b(D{{ zBI{&Y=l-mY@^L+5qlVqI&L3uVl#fSsve@Y3Ssmfy0r>ZZ0+xSTn6^dPR0HxrsAH3) zL8bi${DG{FGVRFZX{T)iY#++%2-7Z^q|<1ikAyl|?CvMxi? z9^|Hk8#3I}!gFEK=hluwON;bov$?LX|BcNO>cXxhX2+uMBqoQy!8rXHXqs9degiVQ z0^Ou=@niOzaevP6%gC%W@aJIY@Tg{U(*%c8K4Y1Sk!6QR3rXnY8kA&C*5Y*Tevl}Z zuQNi*9pPza0uCm1R0I^<=E)f7-V?i!Oe_PGqPXXs#Taj@;eiqta$JnNH-bSRw?$jH z#|R1`94TK9p~+zug%HbQK(#|%56G9|c;a}%FzL2Je)1sS_}mc^B*{oWe*kcm54wx( zzFIfMr}@QDw_=JFqjn}R-Vk8?ax20jpozyK_V4kB{rd-AMO!R?#V7q05EP!?;ke)6 zGBB7-a^-!2pA$EC}k%6;X^FR<g$2aj*|!IMN#bizX#vyTKcN zNff-^QaaN1^W|Hzy4`yc^pW#yCmi}9tP`gyK_GZBjc`z&^prO|k}xLJ0EYlLq5DWS zD9a1i#7h;)_7&TJM!=J{W_4i+I~#^GWjsKzO){)7oL6`!q_`y3_T~Vk#o98i9Oa;6 z@GyX)B$KT3%(ZZfT>-<0j*c!cPSRl*5t02zh=@mrwZKJwby#chw=PzB!Hb0)u`p5tU|5ZLQ95Ps>qk`;9Sk`x4t7(wCF??49XQ(@``t5 z6;-7#S6t33E@lw1RZL8h)4>bX-W)Tl7yR*@17&9Jb;@{fC>$AaFMET}Ns(<;nh zEsho+p)lx#Jq|8=Kn!;%_5{Us$L2|J^{WYNcFLrf>-wI*rqqx}L%q%k(-hHQkAQ%k zVbe=daxaTbMQ~i6{}zy}j6vj25gAC9Od{;-`3xdXTYw0lK-SUgsF~_Vl)o79@Kue> zd&Q)t37IIP4Iw7M_G)z9LFaUpNP~z++1n8Q^oQQ205ddfZ4%HVbRuAf{Nk$9Y}EY_7PO9FxOslAu= z{$yE&I_$7LteTi34P;;VEj!PCcH6D?(b*LPsj96QijrenxT!eNt<4`1^e zfqV#Wi7T@Eq~?Lp=eM*b$4{PA*7FXAat7Oo`k`mwV*)C4Xk!QKhhZOi`-B}M0$KjW zNe>C%MMe<|?$w3n3U3udHJ2E6q2fYbl?pEmk7@D-nTu!^ChiT63Ysam&sa)vkquI8 zEBb&dFDC1kK-7tpV$7vlbi`K+7F-2;#nc}3$o?m_Cf2dU#8q)s=k;~u1rdyqQrVVvTQU5mwQe4MTfvsjuBzQjG_49N}@%%#K@5WhYMfVx+yfJiUbd`5B#LUt2QE|hbt}Ba_ zv|{6gtKx>Sh0v&3-FR_=pfbb(-f0EQha>WEam#JaB0V2+bRI1h_z+(zhG!ElJF8Xs z@Nwf2_8||VT_oG|B47}mEo91Yg@Ry<_l<5Q+z!wlvR&_3HBS!cp&3@B#|1B>2D9BE zbAR_yb|Zz0Gc%-`2gy z4!1W?rAOj%EwU?UOoj!uXt@&rk!c8B zU`0X;v=<73$I z@^maR4m;15N6JH42guHh4#r#uU1}y74tDFZ zh^D)q_OH*{*ZXMw3>}g7WrpZ(fP~3ru{bB>1K#k~LJS$d?4nT}?a@Xp+~A^UmoCV#kqiB zZGrxH6Yb-pV4A#H0&+rPVEN;?$5X~_PtmxEEk}HL84fE(KyV^gdVIX!Ht7c_Bd2_5@ouoZHL(m%;fBrExiDM50gBqd^m;_ptbJOa@tuaG+%r zaled>nIy5RM5h-cuAPaEpU#$zx_X3UJNe{sY=%!|D&4pF&t%OrwQ_`RJG3**FNM-+ z-@K>MeVbp&n%9)bUM6jqnxFE`dkWpR`Ojv}Yo6k=&rtUo!`y4C5cil-?|nv$_hopy zH<03`K}GXDhPHccn6fwbM#Ci1F4D&X5O*0F-V;;dJ+82Ahy_>JuzFWCPDg_02OSLt z!t^7-U(1$G$Tz7HgrPj0PbnO#}IN%s&T zE}J;b0DGMa{?|w_XPpmo@t1@IABzO#lLLxvOM`~U$3V(KEWqW^MoxoQe0d|nODL8Q z;YGG@IClbPD%jcr+Lxg%qWvH!FAhfICblfg(#+$~rzgV;DB~I_li}kyxgmdw6e|(7 zWpwzv+1jZW$K&fU>Dgo25qT_A;=UdHW7dJ1@I0wplombKErkv|E$-XFnXChiDfJ!9 zmpfPp9e8Tow}XGmI$)$kDq)~mptQ8DLzq{T=KDaA`4lZJ&`D}6YFSrN@Y_8^_-%yQ z)sbTEAtG7??ucvy!Pt}dnULodr~jQCaH7RP60TAvsQMEZ17x6Lxz z7qmXXibPp^ipEZ~J_Uu3&>ly5*`doQFDPzLuDorVRbSpv|2V+*b`3|YPtu^_Hb6gO zedDXWQO}HH3`vQ|>7k;2 zfatzeUSC&m1;)7j$O`}(A!^AtTzP>*et0>8JaL3$#9AWytLg6~chjcX_7-Q&LtSYR z0#j3eNN2;=8I%ur@c`JsEKc^p0(f2VYV?mAHF(%7q+Y-d6QM&YYq!_wE@B<9D0t{* zG11&ufMhFS;Ndz97{36N*dJSb0NcX@O^qP_4;I1YB+35 zpZH`>kE6vI=UE4#)7qB=Jjs4LiC_ZVa%|!-3$RBNkZ244 zl6}cbIIZ+0DAl<52lB`OIWhCWbKrb=k2qgSt{0vLF8}=qdR~?{?s@T5N}d;Sig<^L zIsxRJC$tMf9^{>JdRTOh$%dDA<6amecTq#4h~#aRqJvR!uIoYAfD^@l0SO`=9qT8B z9mqOZj}t{Y@Iq4G4i07=Bu*6QVgS;!lihrZW^Szk9Lm~HoG44uzAR1IiLxvodOJ}d zm6NYKCko_nP}Asf!%h^2A2>Hk>_CC6GXe@%vI$BYDDyzpHARiv zvQ`oY$|*r_zXMkB$jO@TCu-cDHJUh3R-{pn8z-w8tr9iv$QrJ4px9m%PK~CWUZ^8k zQA0A{gTH_uaWs4?i5;%&EWf&kMC@2a!-7Yg=s^l~gZ0mN`%sA?BI@eXQg_Io6EEO>8+LOT+RqcK(RQ z%>j#t&+%l%hU1ZyAX5n6lr7qN94KX4*SCW=XC17^fl{V*eLHwd*1>ulC}m>Tw}ZE4 z9sI~TP(XcU<1PQ20|f@T;&`^QkHmrUM_DUp!GZGLtkJXNKzU!*aFqikrqXncm?>gO z*~__dpe)A@6jE4FQ1zyOD1&6HCM5*@e?kXJ9QKgW=?AlATibzBrqX?z|76zu+76U5 zjqcn0r?TePcA%6gbl>Jboi+cX;y`f(d0h?^gntP2UY7#}J`s^X*5yF)K9Th}P+*o8 z$!ZtO1l*xj4wUYC9Vn~W(j^WQ+WprQl>ahoC2^pfmWlI%GF%Np$<9P-U}ls1tE|z) zfda1qhVKRC)v89T1m&+~4Ocl(ViJs|9SPQvz{tzK`928Be2N4{I!9QDMqm8n9wLE} zuTMD#3MZPOBvRNt%<-LjNJ#LJNKjsZWr#)L^iV;W5lcd-k5mfEaEMrW6O`csNd;v% zOS}VR*&HbI&VjOk_C-MuiI~n2wVF{`fuMX`2GfllDD&QdG7lq`sDdUhA1gahPV|$P z|2|v0#DSt76OU<20!Wz>_wC?2SqF&&WkFi}|Ji%9C`ps6OfWJcGBa|I(wb69Dz7Xp zQQ9g>NU8(^$PA##Ug*vMGF-Z%?Qc0 zfj7RV+qKWGUAxyTa9uAJ z5Of1`3;4^bfZ_n9ofn|zDLER?E#R-J0-6p`Ko%@5MQIagqy`RRd{j9zlngBoI+&=d zX+5K`tOpYQHmSw)NHPy>s|u8iK#Ki%fP&K!>Kw#?&JY)e9?H!;84Y zesT^%vLhrb&INH;5)6)}OF9jBAR>&+1Ce-uGF(pDPPU$4!$-2aNH6nefb{VI1;-=C z+4zxat#L?iSiOt-aN0;R-!JYR^#G;wc&QjG4p2tun?u3+O%;{m0A(mW9H!8KMA?_~ zv>I=&h!zJZeIXjA%}x{1Cb0hQig42b3dlJ(Ywi1bfWr95%?$Yn>2OP>`g(xk850I( zvte*a&7~i(*a6B&a@q;E2MU13@kls8;rYnPmSp1ji18`UN9+J)8V^vWNPv0AGAHo> zWr75DfHFY>({zmE0m>K&>;Pqq1dtMV$Kl`O0SeBM{zo`K;VDHtKw&5xpfsG4_@vm+ z4p11HeSq?z$kW*Y3d@>%fD+D1R>&N7s=~5v?*Qe?C*ZwuA@N>;_sROgZT>rkGoKk= z)jwMtI&j8by%@Yb)+%R@kRj;~m`)Yxw%g6=|{KJWggE}Gv{&4=mb&h9uID6zO zhCf@Ff~Q(|01hX3oRB!X!>J`sG!eQf56CJ_4veG5T4u0Ykej*%0whD%NvXP;p`==~>EhmXvLgW+^ zg~)Uhc9AFz%lRe3*wgU%^5Trs%P-U4{cJw@?mA@dajt=Hi|Rk#9{EJe=FP<--PVkB zD@D4SGt#ZHeLBA`%BL)2j1`F&Q%62!kz}mRFUGFw{9>%lFUE3y!FQaO4uh%5(%6nX zh8cAR48o&r5vk~R!|P`eg;OY*bvMaCGUMdjoIhdGiNC7+B=Zh8y9%dq>YXF2$xkbo zG>ha=nZ}?CK~iRjupF<5wHX8Y=fLjEDxw|dQ9drP#iRt;6E@Sp#5N0P^>CU1Knka~ zICrHHIJ;L#1Egr-&b9yeV`%k>EuXFUA(LV88>%F2r?jZmLH#MO1_@DEas_W_iAf_y z0G|4Go{mrOzHlKvu`ZDd!`rQTiN=SXUohX|mHGd}%J5xe&g^8|eG}zxeN3*0=8cEt z@K$W_RCJHU#=q3FnQP(hvD&rpmwgJDYoXj~x4Re?o8e-?2LuT_^ zqJ_3kj+=uh{!jzSCQ1B_71<^&pLC<)0&bl#*%@D408n#$aa!X`oA#h=_Cjb&S7G~& zYXnkqFxX}q6Um20a^@#NJYvYz*VGcaI-(?60TE9mg6VMy0jhFF*5B4yjfND>87e1= z+>zoGoPZ-+M~0;xxNBQCZ-{{pHwshT4aGy83?hhmE0~0pEYQVdzAX^@Srf?* z5alF=j|@e5FNt)8ZTfzQC~hd}#l)o>%6qGEDO7lSN8!XDtf&+!yiv}HL*vA~d7Rj< zh!!e5JzWT_2*(F0B_rCzi$7EmZc^b1FN&X;`c(KvPRiKTQxy7IY$?xxHyF~PlYzjd z&(dy@b39P&5QoB0vM9pOlL^`5U}+Fe0)FW2KYBT2JS3Z7>9CJvSpaL`H#uz~L&`U* zs~?qaqtB(r)WiMk5T7A0kYX8DEYrS$bGaKmxh=d4Aq-2Z$f8&Xg>!o|IJY~4b9+bT z+z(fySSa&4=*L4b^dl7&)z}3LZOdo`41H92tTT^s2NlgiN%t^EAn@%Y4J4b`_M;Wq zCe@sj~ zUWoB)&-t~Nx=AT(cIg0R{Mto2;n!~MDAjX*6@c$~qb%eF-X_0ZM{x~6d#xE~yGQ2M zU#SMK(7s&(7ufDYM24mX|5qy_h4Sq(MD%C!MPn4z;-qg>6HP?w>!kTaZID%x zIMfFD2sXu(5g_>BSwOICuv3;jNnvP=-3j(5lx}=;p4uAgF$XP3lA|dKEc#@EchaE0TyW!Y3ahB8MDvWrWO6LppdkEG_tp&HHR#$#cxP&i~niRh$QPYiviAbc~n&j=T0#<>t7!Va2M z(benKVuf#2bPMZZoCbqVfP7m-GP>faP}KL072U$BSdaLmBcN1mVbf$HVp|q?#Msp= z_#$?&G165$(v#hv2hFP3gJxB%9sRJ~%wi$Cn8iYe-OBWYbYC*V?yMJye(#Pr#TNg(ex`Z55TmtXM681H+9-6qTLK ztJ>QuqJ>%UK;}$fieVGcCQ0BO72zhcVvuuDKx;oxQ)0$r{a~-71q}ImE!FX~rt(7) zkI`hzG?LA?a8n!R2htJzZ*N(|2xZF2qKgF+A>6Yac)ra+uJ&=;q#HpiM`jFecA?lR z`|>`ePNeVRa8S6(LY7_%!Ff%X0zEf9=Az1SkWZRzA!~Nn-|w4#TZeX>8p1U3%=@ZQ zDC~s0QcmERHiE21Mz{&2-d_PIWW zP4>Vb=M2dzbAK(o!}!RM4B5y~@q*!&|3XAyz%xef^cc^h8ym|Lw`5Mmm<6ODs`#D@ zx0^uOB=!x!O<_X{xYRv)$npux^|?nfriALi;!>vUTN9M=WKV@u6sJaL9vi})RbNa=Z$7H5 z$@@(rUi$qe%7##s1-!ItR1OR-hsYK=ly{zp4k~cwG>6M{C2WGrQ8fmIcK#tYEilZ3 zU}J>GDcL5l{7)6x!c6xX$pn_UK7(utmA_b#Efn^$RSsma@vUmx1eCv2k!@1gUkQAO z>f**~+jb{Rh!oBn!h_Ox*Cd^0iOi^BPc0y#sUtRO*tiG<;sC(5?rrdG0gP?1MFhrn z#(a-PTwGJ$EKvc4}w0~^wk zuOiw6h`(JCZc^5RoCBiP9wvb#&-e(44C!FW7(s%UO7)i`4|a4nS|*Q^ks*NP0;S#D`m%8@NgEG(DaieuT&_5Q;0OvR_AR2hcari;b2%F6GINrQ;G$;1Hth?H$lFSVZ}P&ru2pmKtQ3YC-Prv{aeKVIr(3Vr)7NBuCUyirjp6z)4R zYJvItB#KVoRaIj1^?F+s(L(3m5u$-Vdrd@}pmMt++@y8~Ip57I79us-34_-6baim1q%KktWG z*+R-gBrx2gsjX?^ag!<3jZ*Ca62LZwwsTLbCLXK5XxUK*0B@peC(a&z_Xm6%z~7i0 z`Q0BdmYbuJ*UL!es^npUe>^g3rjln_G^0_KeE0YhK_$;`sN{pS>Iw(nB3V{c$uknunkxCu@fj-l zH`9vlcy2}aoQ1}J$Aa4WJM*Vf+U?&cRMwnq!B90C9kQmSG3t$&Iq3k%&xN_s_KbAv z(oMqPm$k>hHYjK9F<5kh`GMA8&`aPlz%@tMtROSMliTqHiAjzYlq5lVw6D}Wl})6g zGBd#JG-O!y4AS>fmC{`Dt#g_phwWOlpk6Sdq?IW_32o9Ei5aEZvmDi;(wJeEMdcsz zrODNt7fvWE%o+P})7bkPLG`;jH`*b?A>-Ygjt|8Ji-Z=3i7~S5=%?9C>4S1IrkCyM zh~t}U9S8u&H`hBr)#IC&JA_e20zw&yci9=qJI7lcfaEg&oWouSf6ik$JI~3q#0(b@ zxes3fAQNA|Eyx=z#pR`Ou|ZTt|BEc z6MymB691e>O8hbYMv{w2A`1dCoZVP3zH8x43~%enjRiR)K!TNx1xPt$r`Gbuf*=Jx z@7P!nb1-~f*jNx#FeVVva&Uyuxs8Rhmh;rc!a4gqy|I9P5PD}e7EpcpT-sPb56I{0 z#sZozpXWCgp5Y0E^fN7lpD%7K;8`|FhW{edvttN#eohRnZ7e)DhFTj7Kr_#`u(9ww z3*r64=f@vfQr?}wpoT}0ADnEV2#gpxi_PS($JoDBMTmNP*=&p;Nk&(kENv8TM0P~8=e z39UPcm=l|qZ?Q>Sd)Hd$89LuO%Rj=Rtjr1gesXjDmJ9VQSpFk)0eSH!&_9mfS2ovf zu`60DoXx8Yts*b}gvKu8_fwm#TkIwp$gj5UVCW9y#UGhQEOZIKFK%AE#S!9ias{T4 z2w_6C@NDG@C+jUV{1pF$4qrrS%jZ?V@9{ey!Z{&BS`^ z*!>G9H#Gvy=9f(1>p%nS8_+xz_E^6Kg3YZrya6s0{AWk{NO`_>p@lZVJ{#1Qaitr) z@GOZm4oNUXYy6KOtjxJp9=hI-@yA|;zpPje8E?%2^%{DGKdx(U86Jdr-t(XT{5$W&GcYfF;R|0RFTdP<_uZE+-E+@9FMjb$Ui#9P zzU*Z$TU)#L-g{sE@>jg_m9Ko&t6uf$SKoKvee3J@zveZs`MR%r?Q38Ay4St_fd?MA zjDKH`-ZmqFrbo~w1r&WFl3xvvpgolr&uAE2;MZ0=6l3`HjrxWd6wtyV(_>FuZGGi5 zI1Lgh)a5GnrUCF%`~|EM1Kc|0I_{5>Wq)B}>o1CqxB$b+qa*|aw` zH;r`~hR4+?@=506fd6}9=HJ(+m%f4hVy%)I!RltO#yR;|mv=^LR+k5y8pa@PS?s5n`&}`&)#dePHjmxCc(sK$ zw_b~#p}g6JjsjRdXdPCO^@vFJy%kx|Lf1a1?|;c-sCS}-*T@TN##YUB4Z~2E^8Q$g zHT`~XI#?+uSLc2r=C-D@LWIZA_{eu-*&_dI%Ytv8gz0iA6!YgMt z-Rl~fUYGI{u@r0iE6!}fh2!eigY><5<*yxm+&&V?TAzRxDt}EYzsSnJ7A3qaRK8#G zSd5tY(BUUzDOUNH`nbiW%S>*XKEs&X>i7~Jw_jL5&F;zDe&y(G|GA1TXrb*_5}y4T z7IAlI{IG0%jF{Q@Uy8+8<6AQu@8lwP{YuPjjlWA9|C_8COmfl*d->>%|MiNln)h7R z#-HcF@3DwGL*x5p<733k#(z2%V~v0Q%*H#p*!a)I+}8N#Y2$yFHG_>s+W7UOH~x1j zx@xbnu8qHgjsF6Rz{`?G)knq_jR>t_&bF<4V)g$Z7GsTnmXq_u6}g!Ek790X{4=%j z|CKev8E@M7wWBxw&nvomUc9D_UuWb0ghk->$giUDe;JFh#-Dd`M`-*(%x#T7r;Yzx z)(nSrY2&%9H!dk&Q0&ydsp#s#UrQT*7aRX27I7*xzW)^1e(Uidm09Cg6s_NU4770$ zlUDztRexqdvHG1z*SbZ|bf9e^&EHvI{cp02EFv-~Ja@YSY=Th%A?Xb)gNZvp?P<~0%jI3K|lYhfPd&2Ys3FNL(talLx5 zAkLA(9eko$6vb?S2Sg_IfXJjCfK18;mv7SJXKiG7rf|C*ivF)E8}i6EJf>?K&xfTB z=y1^(gElnLk1*LhsW*>OC~DNHYQ%nvHIjxs+*;%->gT~L#VhJ; z_QR^jctqa-hM;jm-T_YDREG_Zt54C*wdxvb(Bt~1I?fK{<0f|R$JI$6yI|ZLK=*!; z4DUcC@UAs90e^dJ3x^+mG!-vx=n0&L}ti))IE6%ccxny0TdP5BtVv zFW{fCl57=E@*mG`XYkRq;3E#^)v59kJJI<=wl*G^!$vahw?D{wOdOVn>N)4_cBrUv zT{*^!n=KA7pDHf~7{j@Q|1Zn?<;jp9V1}5^9W8DcQa*w%N(=1=3*F=?8pjoS{MK=t zaPblK7Lkb0dvjcu4P&9GU`mSMSEt8eT7`Gj3AU^=G%4vR0G(JUadH7@7* zoglkl@>v0rA`X409eVMvbQau6?!NtnRr)qBzCzvaj)fWO(m_DrgX=oh`moB1j`iS} zE}*h_USz#CCm(ul(SmLyIyiRE!rjNt(JWo&J&0aflt0e!g7WtllTSTFKl&W$>!W|E&c0n$MmIM9R(2v_uNPbTZ94ga)x-4O3O8;Sz%Klwg#qmh_@0mO-N&Y>DD_QyP`8Ys1>OZb( zc1*I{;7j=z#Ue;YysNv>mvUIzq z=rE_uu{vcoz4Zbk#nU*TrCX-jt+IC#r_4o2maSt!JSHqP+4a7?>LqoL3!^*{Mh(L} zMUZWs_=-isO_uiWs0gcjTwxEmWW%E*DFEq!M|^l+H5Tek7zVf}WrhLnNH7PWxdptxDnMP}0&5-!CkEDR z#{vQZ%`M#8WP?E69q#g$~yyOx5>{@v#3R>)|Jc z61JdgBBP-#bAt9hxuiE zh@&hs#wy2O2W*0Vq|-v`zDqVW%-!Q%Nl3o~`u3x>-9ky*IVFZN7JZmE+lA8f1daYi zJE5;YwFNdFg!IyOW=z^mIOk;9Rqodbkh*6!LFb?v-Napyb?oQtvxA^CF_~43(D~7d zaN&d36FOmLb(;v6(D|{7XySnvcu|eQpM*&QW zk}}}bu^Q0N(sYP|wAHp4VA?7~*RT z<=8ow{C}#*CmxLC&C4Vhpz}%~ACPk{`CqKat216e&b5sEdLSP}x4GnhsUojldO|+% z>Uw}pslGa>Au?hn0tsxuh=TQSKTUkXBMtx6+zCGz(`#x;qMr$1Fdr^Qs{Jn=Cm*$$ zKtD{dJCA;n%jtsjfcHxT9pQkff71ydES)%D;{6htCjK%?lP6~2{I=a@_ux@pMu8g# zxE=;JaM6>$NmG43_`M4vRvw0ppRY!c8(uOr8b$saOLGGQP7&nqJBMN87b?Q)5*g-= zUf~iZ&ZvoSiH*Nq5mnuH&TlC;q7=tQenxC$C}Jag6&)M-g1Rum(Xes2tYa-C;D!Vn2hyMHMzES*_Q3=xIPx74y`Rv=U^mMnjP3-I*+7aqS_gDmGj!aMydIwb zqen?m%!_LhT!`pr?w6x^`1q&Qkf<^!jB`&a5XQMH!5ksy7Vu|P0fnbzTPOw&?Zg5C zM$RqZ&#M9wk4a8}ePM@Cz<~s%1py`J7O-Cxpl*IS*MclKRVuGdfKw!gh4B$78A`YV z(xv2Rt0%E%6c+J7!XhpuSRP5{1QH}+vGl`q=`u2gqb8pdk!~0+yL7qS1e?<(g-gC7 zB8BpO^(Z+AaKd*vNSBi(olQHSZ$DbwEtIsKL$gPhOw_iI^a8m%C@7IGmpwgxq;xq7 z=?y^ps886M`V$AezV^gHT)84y%G2m|{J&~L2rp$NKF5mpz>FtgOR zG0d!f6X6m;w=1Ge?w6qKyvWbUehg`sO0Po|W0wfwosX6<#G$AuY{0ibY(>?#K+qu= zdlV|e$xrHPWY8y2>c|IsPCS*>(BFgfvqZcHx7F-kdmSF0>O0{!(zctHS3AR?ote6bz-69sELY~VMh^W>XHTsOHTv^xrs zoP3E!$#v?Ax@X>SNnQ*%1%rQFJ$P39no+$Ws(l*dao!?t4k$UmGd$?}b`w`VI6(#d#clNS8$j%E9@w$r70oi0h z@t!>z!jP%L8y{qMty4S8#So|Mf(%%xxc#xno2KCYKqSkO$W<*22Q2FHush4+a{tv&pSJ$TL|dQf>c3`H^#`}Fst;K*RlR7|!?lO1 zHkP=6VX7^YI9*%8N2+a?xbVU{)}hQafMW}$ib}8TcBsN_Xx*(cfGF}zSJ_NWF-oo4 z&8mPSXx)W=kV@v#zg5vMwC>oEppIc#X)%;^++p>9V@1Evx~qIBBSUASsCDm4!LzmQ z5TF&sRm~2;m|~@C-60+;d{3m057oN!Tv}9X`dUQTknPRZxOeAk-1m>DaeqtILxskD zEUQu&feC_aXLcc7lg9n672!hTP8EBiQy4W7E*JK-pUQm_TrI9Zs-LD)i&Yr`;P!|sOZ`{mXMgP3lOq}l97%smx;nIPR7 z?KNxMJ&)AN1Bu)#l@+@CEYG(_5~HKIk777>mgrE8doS7lRwr`(YAlYTanHeLZUH}3 z6>t=ddyYPH3;5xxfTL*KbNHEC!27BKzGgM85{OQx219a$!c_urg85lv#L?!{^5%7(KPNE;SxGO zQW0&^xTnzhRcPG%$8EzbV5q40|2vKQbe?4ObJcJhu5r(?b1wOxugD*+anF%+F8N=m z$RDn8&vA1u`B6pwYewVlIC(^kJG7z#t4Gqfw@ZzChLDfs0D0g_bl13N@c2-Uj{Bb2 z6h;p=V548%c_fYdXQ~k_H15z$LlTK%C4veQ(FUjy8$VkSE;Q~VAsqHv!zRKdHh!)m z+N5z$u@R-XSjkV5-q0e3qF6bM8h1Xq4Uv)Z;Zd-0u&nD?2dPD@guXn{DS{5TArUK8 zdp?oILo?2Tm>?A^+oi^RM^bwp6)TN^F^j8ebhMy54`O9s5_){1arY=;Fjiw46|22W z)s80U@zbA+5*z#mry6dLyf8Lhyf?N~tA+s-ZEPpSe6jr%k& zU|)hcO3p3dPpbl&H0~e^PL;}Q6R5<*urNNVJQ-59l_NW9#+m3q(|Sf>5f3CRVj6eP zBgs6FAPFhrDnsl{q^VG^`%#Q*+@U4+-)xdlmCkDs4X==qo36=HOX|0~j3$sQALK4H z?$E9Wjr({>ClNL1B2MlgJvZDYT|%L*(jtDO-fd(W^qy<$dZ&})=P;x<0L8ua zwZ?sLI~w=Dtwy)dxI;^gh6n!KW!E4gWtm0UkHbp)oUVLBIx54(I$;M zC_69mGqN8;5jA0m<{J0O?P=U6QR6;=5?ELRV~;{bW8DPPMievx9q8$sIKA?d&IpY?;6t zMD8OZxfn{+<;68JJCQdtjk_t-<$gV!tkfEJmRM=rS=Q}o+<*53H15SS-LG1>oqxx` zYcpIrzf!2JIqkyLhp;Ir`r<}AWJvm=z7}zNM!K(|H@c6#;Svs^ws6{IFLc}c+?e#Z zeu}ovKm(k3y#Z%hXVQ}|M&k^N9=zoP-JS=B{Q#*r$wliCJq*xBZ@P(^HajYd5pHgtd)8BXFJyfQ_Nge_wf!T4F zxqU9kETS74ZX3f1gB%9LNlEt=+snqO`h-nWsLcx=`#>Y_L`O1NrtrYFl0<$v$wDD< zu1Qof%@D@X1e|wfKF9sLPvdjk?N8Co@9M&8Hbv^^xSP|}&v7@W<73+5R)6wN(R$ zo)(UmWgnklNI6EuCuB@=Tk-7nZ#)}Fe)6#c_p*SCV4xO zvh&G8O{C_pQHCW^NLyofvz_J6akC;^Je<%LIzfhgxPfjd!rrQACMpXPw0T?_CnySW zB>+F|Wo&+$WQk6Kpm-AODvcs@+b2;OhkoR4D5` ztcmfUZu;#5l*$O(cJMRb((H?+1NtG=J~s{8+pB&kG%PT4M%_Z+j%?5l4jZ(0RD@N_ z5=?!DIpIMQ;d0d8SrJt|L2h;?qh>EiqZA)Cej3K0MGVDF2#l}U`E2TeTg}3~K?X@9 zEv;y0_VuM)B!-PPjz}z$OEBX0Q%iE&ENd^q37iR-Y0E#7ouh5WJ*_11K(ha4PW84D zmcT(Y4Z6S*)GmT0WCNYB1X@Le>!Va8k$p3mEbNwh@_dx;k0suA#nWIcqXh&>p^1(D zT{SSOUkRh#%}1N(=xoQKZ1jPOaJVN36oBDkm><~lkp{9Q6a834vPqL7Ok~~&j|LvX zS7adsA_qNkI}C(-ig@ZT?9vCn*~fON)#x#u{HXm$?;P31@*QWz6ZRq=bB@y=s3l!H zMH2kxfr5cL;;wgF4D?Vl|2)Xmxn`fq?Xb^JRYRickH9`+1RqBETEi$eSta~*MYd3W zTwxCdvhYi&c(P=kVMVe@^>Kv^Bl-w@Ma2gKkzp<$kzs_)L&7im8O#hHqRxZ!88RE^ zzFO@mgFJ`~%l63(!Zi=dUV$0JdPO>Q0+!;>{(ih9v|r2z)j~9KS>mNBd;XKgjURP{_`^2i5B|eu+J;VRDk=Pfg3QP_qkk|%tOSGQq zDG&&1ina6y1cH*HmHvQ0*zt5qnd|o=4<&mJDN{BH!i61u;uxq4HL5<0jMCz!$>LCu z#I1TdEcldV+q0fU{?sdwe+6-{iRe6#e#l4SxHbLTDDh{a*Cj z-zlv+Z?r=e8$k8j-^twZr!rk7E8_l*DE3_?hhXH<%Z{s#ij!7J;E2 z%@%?C!b+iZ7v54Uz0L0`%nWbF#u?GV3h*JaT9D%VD1s3gO-|yUE}`>QMYu5kn@EQR z$^hqzFyt7_h}Z*ftY{V{e>hn~<)jDbZ3Ph;5uCGXYls*FIeZZ%keDr^lewvpJ!mF> z9yF6b?cs;)^f5y zF!|dTmJGe#X3fz4fm(;Ea!5eA==!%-gbR~DHGB=sH$gcS;gUz*RuOG7`2%HNU-=mq zScc*XJ3%6DlhB&r0Y$G3X&qQW#zR9cKiROrX3nyKw&qV|GZ4VQ@jTX;X(WBft^-)( z5JP8q_L%TaY34V~@<^?mKq0H?2;oRM?EeOm*W)Fx2a^2+k3qz19`@W744Sd*ZBHD;6KU`5R4EwM(LhSKR$|!mu;Q-qJcpgdSfn=~rs*lRpaqAeL zwlj1;PguRSmY8ge8Dk$!$E{P~Ba@9dvGgNlerdrlVg3nso=86cef!a7q=k~U6RyVG za3cM#+0xQYUzB)8#gYeRZ@Xv)E<4O~=|k196;^t~oEP>GWL>(co}>xwezGE5Sm_Of zPM8zBO@vFd`*20H$x08Doyqta(T*YQEa^^BVaR}Sn&jk9t?3Z;5}(7yN=2`8}tb?6H#T*C&!9G?`Cb zxc_bo!@!+hb_0%fZQFS2z#gRQVvI1A~NzK0?CNqt7;keeJGIj@0^D02`DmhHE?E@&ebOBvIbp0SgL~?=O{C4T9Z=W zg8L-Gn!c{621SXobT?!0Zpq+lBIBU}9i)qJ*0FSKTHCZa6zpfc#onY``&2bXiLP1@ zRoWBysiot7D5i}ox~1+{=mt!KwVNQ@)1K3(?$@&O%%I) zTaY%ir+hElSYJ+u8bg8G8RAIqN;A=GI6=3;Ubh+vn5`$A&F)r9I!!M;tDgy5lax9e z!8$MCSYOJ4siyoIam-_K9Lvq;_ENlQ#IfJ6I{t7QI@TnkTq4;YR74NAo2!U6V%fB! ze7M0}MY%+?Kdgv0sdj1pCes{KQU+uCkHtuC7>(pyY70hk!(~Ia;c}DIHd$&(TfPb- zxs>N&G8a|KWcoch!r}<@QIQC6eM`t+U_cj`JzUuV%s5PH`%*P*h4tG|U_Aib2tk&Y z0a26G_T`Fjp#UBT;ec>%R+kYj5$-D$(IyozC_9t!)A|;bW+)=uE;JH`a1*zFJ5*|u zfu78Db&5LCtA+=EZ6^&6G8 zg*!R4&WF08HyF9WlN_{8!KjCR=u{Wqefl5J)x4isw=onn$}oU@BAVYY6m-fB4(hrN z(6GEP#ChN2K^d57m04C)EBB8_#WcU6>Sl>iuWXSlIVzSJX^Q3EELZcV=W*YEQ|Mwd z3%B%k``U`_MmuCqIslh06&tH4~k$oyUEfo6M%j*%@CiwH-k)$)YZjctl;K znM1S=x4_X9M7yzR$*yG>*7FB{aa0o-VZ42O(&bGpBm$9?4iUwPk@=Q8quue@!l z&-vm3Uwi6zjR=dUaI*(|`7CdIz}KGoT?r|Z2YmU|Z+yVlN>~Uf^&MY6x+|B1;Llks z;rJt~gB07sQ@;Z62;I*6zIfDE?kYhxJoW4E`{M0ZSu+sJca5LU_kHnDtUvC%B&3ta zeeu+9^0+Ua`aR;~zIX=MANR#D;Hh7K-xp8);$>eM8T_{;<-H({SVP-hm`1E4;zeo1 zWklSCGmBZT1OL*>Q<*DoZ<;In{Y=|W`xvfuze^cLzF(xL zCG!13D#BSP(!4+o7UcU*DrGGG`MPhnmz?G2=V5Kf)42A|vqW9Ql6|a&SD>-Uw~WtK zTYUNXIVy_C_p?QcdXS9uz zCF%m}VHG&9ZwpJjJvl7jXIXtqbA|=k_i1mbOaV!H%A;h0NYsi)MIt8=waBN2F)b-` zKa5jsgph}C{I0_E5h0ux@lWiZ6G#qV36K0jG@F?_W4)5%({g;TIoU z!k@@!$JmJb7tZs!VyoCiMx3>X`xj30OCFSd6w*)&9f2h=5?DZ2@F`>dYn{|v{Gpfv zz_nI!RCht&CSGZswKLdn3Jh`jcG)MBV zF_eV58z5m1NRb|pB0Yd2pWMVFt1*uUB##Fqj|Zfhdu27>)Lcz#pB(<`wLxg(o?3s# zbNKIxng2qcwg?Xc_ruFKu#&_r4}9rE~rT-76;RBi@B{XujhL; zX;EcE=G5h#k($-zbxsXqkakN`UEURQTU}nOuRpf%rpasa*ApMKN>*e&B6iSwE3%-4 zu6O-{(ySE9FhEb3YMtThm{yP3L1gugsf% z-I`vJ^@v!h4_0JB3r)YSO%IP0zkGJny{@6@btyj)OR=Wkdu9`xLwTh5WqIYV9evzB z63JShfEFrmj}*(e@sZ+}gv$44@mQ$5wp&i(T-x7Fot<)Qz~mrd`=$KlG+ndp})x}b$|xS~w7$|wIu zEaHV>AiQ!_ZNor#dt&2%Ef!;qe}Qt*n6zQ3ls=w%`RHu)Tam7Hi&{Nh*6Lqi^?#j3 zTnyFkKLtMeTr9?_|6Hy9?~*pmH`3~_AHDj&6X{y@)f8l1s~;aN#)DkVRFA@We-KNt z+CM{U|7WZ{4%*Y&uQit=D{!&A{7Iy1wbw&?dv*BV9%JwSA=r? zmSVNHXM;!jY%p>pG8>E_M6wx~STt;Srb}PX`W`wi&VRxYGW1cN4Tf*zcP?K^Z6Vw3 z_Y~qR2li@D#aUqwzD;>`;p+NV&Mc5$XzQ3S<491j;dZ3@wN=S?VUj=` zEOwAL+9AK~Aemn$TsnV|vzomj=gsHbvw#;l$qFJbrx{s+BInImW=C_X9mn;eZnt7O ztDC*a3xOQ7?y0`Xdog>H_rBsy-u1>edCAo_p>0pRZjF=&AvJIndVovEUJU$8{C&|S zsa33{3=gBfCAP78l=u739E#|RR}TLlQ2(oXly}tN47^h?ojl4riq60jo1@92ygl4^ z5f~9KXL6bI_2S9RK@2M1GeX^RtfPmFh$r!Q(vuNH6EGba76n*RTj5cJMVKT6ni7#L z#_iCO?dJ#+$A@u4?HY+!Ys+^>QifZUoWsI})hw(ta#B8CJkqnbp?-%vd;9a@*;`!N z8dWw23?$Fqwt;iLGL0G>d7vqU85~Soj&H92y*_(ewsY3Aw@+6)F&fEI#la!&H@s+z z=!C6&E`y^s%enmC$N{rov}Gx`^`fo9mA`0vUwF}$gv1O43i`$uZDC#*XBZoZh@>Uj z;$l8L5u5NPoeyg1wO2Zt?ZkwJ%}hx2PmR9PQsboiK+Jnf3!&xLlbdARjDj$)>qyDD z{#b1z=Zatm@RbcpH8@YkLT}@-+Q5|+IDhcb;%x13ApVC-fhFLFmlot7FWIjzkB}GI z&z_t0?>s%}o;ma1v+$JrMQGG#{k!u8FMQEmt(pJszI4xvU-HtI&HT3pO+3}`Gyc8$ zzV-WG^L4MC`R{eFf8g@hf5Xgw-?;Hj-~26CuFm|o`K{mf?f>LEX8ybOPyg9J{}{GbPahsS_7JFJYUh0KYWrl2Dtx63A_Xt#Ptmywsp)Yqr zkp575Bp44~4)nDz4x`_x=znKUe;^0Rfqq+xlLmyxj^{SuO;rK^A}^qm7qBZqDInZU zIk$i}R|Wj@ynwC*LkmU{lmg;wQ0b1a9D?tz3ixM6(bWT1p2$=nAKfsg(p!u&KTLj_ zBc?XAd&V3wJ!p=Y9yCWx>-MweiRnRe#q=P3F)`r60|TU$uC&mW+7MW1TMvkpIfv)o zpy&G@+@cWy3{ZtVhv&9&zOI)niBT0zWqFZHc-dikYNng#{t8SKv)7cRxjZHx@vQkA zp6ih-nrOlpd>=+9aTI-rUiIOA^jG9cL(aecNgTU2dWWtSlk+{*$o4XSX7#UBqO9uqdl zIgrSsR~kD3$>RaLd^pSoOhREWTs+LIPC)W_AhVapxp>SY$(+Ep*bIxUFw^Yg8m3d2 z*7%&BGw+iQ?vOyZLkJ7*!<{qU?j`Ux6rW@Bh@757_h|mq{{%b?lBc4r{GNG4?yul3 zj^IN#J+-~1=G#*>V5X(GOvd4{)=APBA-!1QOAqX?AiaH=?LI;Tk^zjYB>l-Z2$pzm zq&GU29w8d*@5&7A!w?(xFRYK{Mtb|Q^av4ec0zjT9cE1WQZ2f80a5x7IoX19!uHK8 z`^PIz-4sp@x5D&eyCMYkfh8$E!Hd)I367ls?}<-4A-(h~GbWv?My0@;a|Pa{*PYVOvJ{3sQ*q>m zaAd?Alsi`#`fNqv8*>U>sd+>!62zGHl8I7DSf8tienXrntj>PEKR7_}P@0r z+b|pQNltXyM6?u!zEBapoD<#4iH@6yHVH$&T@j{XUsBs)PI%NrxJekARD@q22?r38 zCB=jxkal5+)rYWhR?vX)Q5a&#g#umfCGDQ3^^C&39>}msrpbZinP{G=5s*9{sPRS_ zY+v&@0mW{JN|&u#lh!{q{J6(itLD_F6P zw2od1HfvE3>Yr7BXr*${8el;Ba4iR=-dRPN0fe(C1+|b`daspZO!utHF1tw0{gmfL za*=@s=W>i`OMe4tG8t(19MX#nwCm|j209SF>7NrB61zS0%MKIUmk~#Z=)QlZfF`8g zPvFT;qoUCMrHW5qC*=ibni|_;K)4)CB$$gra|`%#RlsYFqT#`wm1hNvV*x=Hnp?nE zssg?)FJO=tFpLERX=rW%e^V8pHjx3*cJcytV*x=Pnp?nsuL`(dNQ44(=cK#+*$ z7Vx)K0qe1V07f9|j-}d!-WdTP#$)j(YlE8@$^d96q;@o|XOtQ5fee6TuIeBUG>;RI zJRYbeBxS@s&Eo_lj|Xbd@;s8v0|`#CK@+HfOibEQB~L0Q^#OQGGUv|v9S~=m#H98a z6_5HzCh}Du$qGE`osDwR0WT{=>0Qu|x103NVqyy<_0Hy)w0~N`r;YT{N4m@OM#s`4 zL`i9STG8hK{S_spHq#4;wVl36N)tYzOt3)uh++rWfI6KV#l|7M!Pfqnq+eZ9+B;pq zQ36GByjx02?|MAwtWBqTpYgt-#fT0Y5KR{Rq^H#Iyt|_C>YTz56cVlQfCLdSf+NgK zqTgQ;eN~)5tj>-Q4I8@MqY!;hMN|!r7lF|=UL|>8Dw38F`I=V=5Yd&#{)I!3?()kX)nK3~DLQN6HC%vAzTgk!fB5AFB#bWBvdPU7;AJ zS}zt5MW%TLe7q{)rE$s;&f0kaomfB=ndTMniK>8?+7>Wk)596cA#88Gr+MiQR>ltP0dmuw1 znX)>_ZACgKAbC7ci%dH*Ze7je1SF3KYV`6vlFS1MV6l1qQ$b{!;1i{!BGVY0T9kIHQP$VoU{QScgpeiWJZf--xrP-YK!c?akZkv@t{ zBc_)g9eH{anRfAb0@DwWK8j33rZ+kU9EM^$D=p!wU8IjFHehY|o&MW#nFk7ysl5_JrahqT5?gaLk!km& zg2dj6p~W6F!G*{)T!|vn4&EM;enl}+WE%41O!jj_y;(kpOudsW>8D+!k0R3`oU{!* zy@5@acR8c>J4heFW|!%WP7XF5UUr1^eWZ^f(+<-c9ZS!-jCtG^Dm_3{5SjW+Y(y-v zA^pLL0;5pS0LmfXKUE^rLB+6oLw7)!iF95-n6U(Nk!fxLU#tpH$F(qrM?x{6&0Z`Z zh)i<}_)=9saohDEFJKr82qM$m0=`@oa4`pqoxFhESU?b&<`(dks(|DMYyxsGFQ6X_ z2qM$m0{*5dKyP=JF$kyxvMw@d6M82Ei5MS6CWbO38cJ<;G_7ZpsqcXdiDZG_lRN{> z;{+s+2WpXNB6&ud#|cOt57g-8c_f(!62Rg-9G?gx)9%SiWZD7pEiu{dNfViNPd156 zof9f4?I4+mOgl(cpi=K-6q(w*k_lwHpdUr1-bqYs)iNcIbC3lN?6!&y(npc0%k)Oa zfWSniDc{!s{Wj7^k*UM<$~{gWA=(Q}_&^8JAE19DinW>E=;SCi4(ScH4o)Qf>LSyg z-{UN(gpv*unZEBvsbx|>(Evvywh#T`fL0xy^(qQ_HF%&fl>Q2Uwo8I&_z0@GnMB`J z5lyZJXLb5QG=LbMJ3gG~yDOr_#nt*=K_J>|B3g<}-(L~cOREFiw)2{Hnus=uOz)`( zujVMImji~{@`lr@Uz9!+E#FSmq#=Y*j}2a~k`r}l{`GVLuZNF1OIQDkbL02l~3we@+QATo`X6(pue zA4R4EJV)Ux2muS`b90xdnWzDuCXL$^L4b7chwh1d(ZO0Uxgl zpp#=#z$hKn+fNl4qcKoPgx92Qy zd`pZwR7?{5*?~g}A39|7;gACPk)M5duHe8@Kly65eey9u!4X`h45t$Nq(_N;Zu1I6 zX2ZqG@GP-UzE^Lb+izuJTSqG1XuJ8+o(#c*6BA~B9x-puwKKZ*{w4QalD^=#UFND(vO=IrtT0- zdu)^ZzRHe9E(tus^-gAiq*MBjZKA@b1bxwm=g~8G^81_=fd?Q@Z+;h`d-J;_gR1-= zqn9%bFj%KE@OL@EhwU$D24bvw@1X4`TQKK9^I?c)PBPq3gSs?8$jJNV%zu_iBnswZ zBqA1>`!bH`AlS5l(AWr_$Bp6VmAu3}hKnmMWgLL>Nj|*fAf_H=mxnl8Yg(d_r(P`-vgy1>`3<>?gSxvitqPe&?>| zSJL#i!Vcbi8x@-l&OPC6kW0ovn7JjAwU~S$y!R} znmA+D7eL76nSb_wd~JCP|DbpaH~I?yPgmi8WUj)~23O(TCRgEUbQP|q(~Wk>lDP_F z<|H1#LqRl&3sTxtcDoX%yFwh)(zQ=!-M!HRcvn_PNrxMgAlhKotGBPjt+@vH!=LR<~nSkM8v=WwhiV88w^h(|WU_UwHk(2LUvKI3-@4N&63@f2*Qjc>SvT zX`rvx)lxv%70+$J8><2euU|Dl4h8IpJ+c%KcExiG=u`z1UcVia>oMe9NYtcL3JAO6 zxdptbDxmQCg|Q{NS$Gh7tkmll!U=w1lzIK~)4YDQp&j@7^`LqEdeFRnwcBBB$$cl7 zSvm1>bR;cSoJ;ard3-jO|i-&KuT;qg1+w4b+`dv`_QTE0WX@rRE)8EeWdH6kW1 zK{UA$e}6@^@c5mGC?2MRYwG6`eNRQS@c13%M8^nLH7$3DKTr`ZJbv{Sg-}!K=PII2 zJH+=^gbR<~wt#aW43$YuxM_#@gB9T>k6)SjYXo2Jc(_}XtqZFUMY*bt7$24D3}w4T z_8*U!Wf$iew;1PvY_}+E!hu8{s7>(42}m9f)H^?Au!-hz0+PoA$u`iG>YhiEd7x0L zLuCydkqV97n$%ecSMeIyL9 zxK}`N6E}K7h?8+>9>1_<&<*1hb`I2InL27(*dYvHEkHU$ocPJU5hf0zmojx!uyeqV z(c>4^4lt6kjMjx7wD#i1=<&<+(mVV}`jTMG)4e8--(lkFRv91+Do#C$$FFd15F6$e z@X@M(BY6A@{h&;rOaEgP{VTQz+CVqt*v zb9K3U@KU&d91uNt4WIaAD|I@qF8B0?Pkj;6`oJE+8-64Z56zRHQtx&>em_-lWa05k zZ^*gA(72*dc>H#x=3yh&CP6?zH-W**Y~j-t(Zb_*Dspas5jp@LO7t@o(Zb_*oD-ci z5iNzG&sIb)=Xf{DiP8bMs%euj^tp;~;qg1j2@jhHHwiFa**r46*tU zR@A$e@lhCJ$b|x3!X@oU(|ShXUJum5(7xmuYo3V_kUSn}5Qc=orkckINFEO)GsT4= z%OlB@L#Jnx1)QyH*B-x=ZkG5P^rQY!d;Ioq$K$tmJ08DX^Y|4XUe=@Kpd^@6c>H$E z<97$5oX9|M-c2zkc<>s=90=zEXL~5`X17=Dt#oTg@M~*dSXNO zX@ke_G&#+yM4`W~__Xl&o!CUffN+z(G|&;qg0?0s_eFNl*$1ve4WD zzE~Adc>Jp4X((V23kcHC+ycH-6;OEm_VX6(!~%jmG`D~+R|OOvzumlmUMwI;L~{%H zN>#wRkjM=SKo$U`8#DPCSE7;S7|(+i_4s8d1E7JV?Q2?XdsjCz9>@Sl)^#1^UCrYJ z1SLGsaCRrQ!A(c>5Hy``80FI|Noy7CGr(UrG$Ux5d& z^c*~O{iE8M!MisY7VMkHZwK_FVS#w?3aoeCBi96ac<>7NhzBpL-9a@HNvY%MO;Vbe z$FF$sGCiDkQ%ULIj7e4|DY*yl6#XkGMi1UZQrh?QhGKN5BiSkX);^McbxCP-yB@#q zd_1V0n>~K%4LMg*`o4-n;qglsUsD$n(CCH9h~Yes-(E$u@c8Wu(SR{@06vuHyDFlE z$8R?$+G`?ON=omph!!5d?VKnbfUBA|NlM>e5iUG__4d!u1qWP_%6@He_py|sD8@%giJ=Ur*nf~W;5CXro>2hA0~t`sblZ_UUCrYJB##Gb&>2Xc zzUFZPlE(wdOfgBx^GGre6q3?z^!SB)t_wy-5tYWKZGxw+s*T{hTUtHAyEm$h%;T3H zyisi=9=rlh!GqVpX=EP1;=#+_h4Zd~ll0=$J#r0fhUW1r9=uEs=iL-+f(NgG&A>c< z_fQ`Jn=#Uhubc;Swb8DKN~6;%GVLL8A~NlHWlUt+Y4G?>Z#S$&rVm#PyCzFhFkR|P z@nJ94lVBk-B}(e5fR9uK6du1Fp%|u`Isg|U)4T!(RRM*^uR5NF0@|?!QDmA|z(=bB z3Xk833}Yw&x08YkqySmA06P$M3*Ae(Av*MJDm!6;uiy zyoO4<=J6{YysS2ycTf z_4I~fy^!8SrX8dg6yuSei%i|y_4xhGic<@ZUwT8%6`6jkqELAJwq^DNKs#WA&_A7d z9>1Teh_(bJgCXKn`Yg=Q{i6^aS40bs-*HZK(nPcrnLb?+Ej)flInli)qD>;xXDY&l z$M0@Vc+f<+No4wLMYzf1Hx-#c+C?T-pRQ#BRE&=z6GItLvHxHpp=mv%AcF@oppwOY zU-FDKj}wqQ9;iV_8EmR~oPgxA@RCCh_1Ea0(v022Ne`_!SRc8Ib&>ZMQgS>zFmBc#Bgl<99bN zKplXkfFLr>E#ROk;9`!K{k(vk*n%K3%`M=IRRM*^Z#OSM9e||;L1da+z?Z55nmm3% z)`eaX{-rzx^J0mZ)E+yXva6;OEmPL|l+p@69bbCGFo0UxOfC_H}m@&d-OfFLr>EnrX;PE#RY70ZksiAnPKNHeslykBpBZ6GIsiO{F$_n$|OJvCBP>A(75q8RUuP zaRQRZ1GUJcjJU6P+D1U~c%Viv&m+k^kN_5I*@+&%d(q<;E&);mymS?u=*qh!^LDvO zWa=+@debt&dAHOu;USnHGWC`eyy(FjMW!J=Yz38u%Z4(BO7P$n3>ObxRs+tvsmK&O zc+tN!Vd|L2uXyk>J)Cz_k!i>2o5{)aN+UW%?Z;1xFXynGJU!t z+~n~Kat==FvkZ?xl4pDbCx$X`8c3!3n$|N48hD@vr;+5@)jUo>@_3*Ir?KQ2Y91#b zc|1^qljo6S9!Mq;o41EXoBp~FPL^?KAcgO6;|lbYaYKn zBruQP9ukIq3hxGVG+uh?A14^%(OVN{eDtv{8W6a48?#YYA z0G1u4OYoT%Wa7jnSp0oqWoC}aU#-6{U45}?(G&PMwCo7b>6Zh41b^QKr(Rd(wQHwd z)$BdF+2GXcINjjX>$~0tr(QpVo4|KAdI>WW{C)RJf8QV23j6oW-*^Aq6ZH2DuDw`` zuuITLwncn%m3cKXxb}*_ucZvGz2fg{k-@dMmC$4@gTL?e+zfx;?>$}k`{D)O?^t+x z{vE?2tgpm=XYLZ+Zhxq7`y_Z@9WR6zVjsSq=eQAbWS#m*k#2iNx`){nyuIVzrAOpb z5RkDVY-{X_diyYTm5!epyGno0dzTn{krIl=UZj>xV_WKIN4hONn_}8E^~`7Nn)t~B zx6Wg6JO98E-t(f<-vz)haE%ZO36hfFaXQx_MBs(Wo|{p?Bd;?+h%*Kn@bLWQHHPRB zh(827yq_6VcUKtV-3|D&jq06k!H^YQ+&c3B-u*;~ATFVGhPF}H^L{G=9^16*4UmSe z{;2jMr|kvS)qVqp(BzKu7*0VDDG5M}h~&Kj6a;V;0;7=|FSO&{f@Rc4VG3Vi zKZ5!W%KZrHO~@MFyL1hA3h>SY&5JKyk+5u6B0(1ay z=NXcuI7tmjFJpf!cM(VfXeojtm6#Mp8X+lrN@?DG77%%sIX!LbERxBU2$#fQ`TCZ0 z8XPNmZv_4f;N;PmKY-P7+5k zq%g7tOJr9h5MS0(q(Y$O+w4~Q0|G&XcrpC}0UDl(pvNJYQ4T*qS;(ye zbHwC+Rl>bX4;3@?=Vr{%hXfr_VZkf`M~y;NBQ$ChDk)I{j2eaNNtD2%MxkO7C7>u# z8eS8qnSqBtf3n8ISKl5S9s}dffW1Kz?5zgWYZZNUqa8A2sJB+6+n$l`Vv+9FjC3t_ zjH2V3ds0vm>@VRg`K`&461b! zj~3(kV?m(DP`Oh;F$m-q7G(x6RiQAZSpaN66g^SbiEnvj}wpTIm>!h;3=V zKuD-XIN9r9Oin&VWXI9UW1^@)3<~6bB|kM490?mD`3=V;_FHxoBKy3HPqfYoc7SJ| zXu--=T8mG}Ycjj>2{@8jjZX-8GMn)U$l*j@oiUF;^KHdEUcB=3{|~a#Pb?A~^!|~P zNB_5S>hzhj=guGL--XpXp7G3QJ^M)ip7Y#`&wKuzFF4Y_7ryAO*4>xxInuuuzvQJa zTf6t=PtQLZ{VG6SJvjcqRkGnH3Xr7X@zsM90VO*p3s}3+4p|H))mFK467V9pMt0({ zYFP8IHZ(r!v>i#AiMLuP2lGj)12Zb+qfR#~3TlcRDC`U42h})l7NOA6_00>bRua8c z5lzgHS)B(-A}EsDN1^$~il$nM1{C3*o_S06Y?-b8&=+v|^oYA(7F;Z&xO`#q8p(0p3JRM6M!5?@T3no6NvYhKW+Cukm;SnQDl%o9)Qw&v5 zOSy|uJE@4(gJzSWke2XCmZeo-7)vZx^<@g~+5;_ifE|jVVluplGu1t7gpf4|UBabl z3OGn=6%G(5uqi0&CcuGP64--j9mV(BW~iAPNB$G3B~ztX$HIk4Qqzv&CfknFx>e zd^m>=kO~if{IR@}!Mso?pfF%M3wb)?HRw&yTKh=)1_-!JAjD!skz9Zf z5w=a>Z#e{BN$`){V+eH_P3KOH@JeMCnodz=Jwd+~tj*AmD$K*E)l*|{gAR~O5>B9k zu$8x8g7$0N41cMgT+{RBzf;WzwR#TV)n~b=Z34jG zuLu_=rm$r}yNMHZ}nRS$#f*Az;P$2!jmybdp)k{=<~l zw4PD$#{)GOav*6dB=ntt=RSAcx*A1n$z7HI+;a19!kAO(58(X5VGN1OYis^MyY z!5IdYbBT5O+E8yHUnR7-Yz&lnOVJmKIRR;u!^ZJW#{nzT_Ee zo{15VJRYcFP#J8hd7Oac@jwlOo=1{-Aer{8GOS}A2Jyg*%Ya9b3U`ki5bhqYkPw!u zK`P`+IMP)+%s}bPLa`qO-+D+V>q8&uA|Cefa*J=XMXc*0on=T7u@}-AB*M&JA+Za3 z5fZy0ok8NBL*m|71&Pq#H$oy9rV$dUIc|bP=$xA%5jLfbkT`m3koeJRey9z0fW$V~ zaxNr(tfEjD#U3n?zXBxEgq0EPd78hES40a#*ohDgKr=lG(N9!F3**-Y+tjM2B_w{b zB3c-{4)dChnrhkvi9b~lE(~3FbHalr!cCC)(-q++16NW0t*L$pq#Y7jeQ5dAu$1u; z5*hL-Dl>a5X@{EDGj1`z2Wm*1N}l-!va%~uD3JMoAbBQQjuVh_JWxZT=aFO{C?FB$ zvjGx;w^GW{Hp(zC1q!gEmTO3)VJqbz{7i#W1wm$rkhmQCQ4tR5EJFr~A)U#H9i+1i z86<{u28nztAWIwrDjO%gJGH=vA5I=i7@MJhQy_2NE|*j zNc_EOeiUZ4ZE(U|Nc{bZLSa^WAcGzu5kay;+f5Lfq{Kg{h!$qG6CoNQ@hC*6716@1 zmKMK>Ku62Vs-`6*{$WM5FsmKrL}~R|5p9CRKdJ~9X0))5$9P)jsGg9aIDOH1>@$d!bIn~v08mI1+)z_S7_>606A-NOz_tnpE)gNwfs`}R zJWfFJc%YUhJ&z>wK!TPmo~EbeLpq1Tpa`?oLpt0lLcc~uo8I`M=-21rJLMyk)`y80 z4psD%hf3^MD6pklV3CW=Ft{>F(Clz&ooicoTIXW($vk$wAdGa8=Qu5m~M$B7F zxHwoOq_5^^=ZIApwCps+*kM!8rVr(4AJ}s?TszQ7ypS+88-sCjYW9jBHQfby+Q!Yx zxB#HlY>Qr9h_-N{0Qe`b=)gK-1v>v|A1hh|bm?PkI*c9eUP80+hXaW}tT6ttyYUDA z(NgX}87*}960I`C)Js`~@8n?OARF!UTE{tzr}!lnfM^NICSh$Y64NG0D!lO3GFe8BA{1#N=RxZOMQ8U;iF# zOBS!(-v3~W^5tNQvYh-oenK9?IWyxQtWYjA{!^=y=gj&?LzBjTcfLRjOYWZW@6tUl zeo5m$F)(?>D`)+C)vNDYZ~S-vYrgKauY3Iiv;JNF`fvEg#(x{%^v&OLj9R{pMlJ2L!KkHswwMw(+98Wg31)$o_AJEafpbf2?lBJVN@37R&>h>->T?d&FLP9Ek>Z*!><)# z9x;^_eq%-Wiq#N(OH9=p^klf?{!*;8R4rhX4kRH;!iuZQe0&lH?Sf>3TlQr8VrjoaJj8DR-RW{H5uw=nFL}UnV z0I;~=7CEt^t?QATUw8dEfZ%LMM6!YhDS4b9UeFq}N(qMa3(uIV)I z?NwLnQvg9{(f15QkCgM7#}w%3}qV>_E}JKdq&w2cp%f$NNPQE zGc~jmkUSo!Hz>+fcIxK@B##H`4T|THWF9CsCPDT{hq8Fz3_HR&##v=%|L6#fo?JKCj1xgOodP;I22{6U;dqZt8+s9JIUt!%G zueF;LUKA{OSIoZ628t|RE+GF`#fg{m1!PaAN|@zi1RDvL3&@8m!o{`!!<_JF7U8nS zKUon@uKg!2shv!y@t}!t(~|e$im=|(E-(@%CCK@tWR=myux7y@#>Yv?kdK)#)mYNf z@&#!PhK&B$)@2c}P+^Jhe=)GiTbh2RA z;lJ5AQ6EP2;V_wYi#p3_%Lfu&wpTx@S%%F@oMo5`OoqKmGRr#XAM7j<-&qXXfAkvM z_c0e3k8MmV&ayVs8=bKA*I6cA%PEo0vV&ttZ*=lmCMI2zkjW+*3M2_1G@EGS?#wEJT$t|7M_2-2U;>>EpO_F7|Gw|pzy?{r@)7uh_M*?Jt zel*37cEFCdCkIgq`%}A+_?au2c+Z3_T_xwOtf4#*P16xFs2SP!MHY-r$ew z_fw>4TDSkW;=C_`MS+2gKoGzKADqDl}$?a8`gMD>ltNUc%Yt` zo=1{-AeoV*sKbM+Ms0ekx?>bBX-|?Uvz*j9g$F~NZ?Mmn8H5K`{WqI|U9efbZuji{ zjE+mk9V9Eve%llzZ0dFG{R~`NpG-YIn5a{)9o6=_Zrl4AywX0d+j6D7OucZWy-mHg zO+8*|AEjg5Yj5jzd8Pe<*!Ye^E<-JydF6ffd$+f6Z$Dlte$+K7th@X4rvSbz%yKBW zSy50&q(DI*ZVpTLgak3l`>C%(JechC%n@{xM>}Kb46G^K=O4QAA$XBQEef4Mgf5cI@_1p-h(#VHnDE?4+-gp-h)3pbNaeCE*La zo$|Fal<6?NF7Te-Q09P#U#va)D56X|piJA-+X|280kAG(W0kG&2h<4|onnm->1~bQ zYh2^YE9X(derhq*w8p=$;?TmK2-o|APMH0B6eyYqmuvj{E5e0K5#9kv2@huxF4y=U zsR%=93QA$J;sJn^Fy0TSYuvQP|7b-xaV!dJJjnTEWtDk@w@eJi$H~f2Hd*&1Ev_18 z7SAZN!vpnX^*oZy1Ihd(DIK1D8VHF@s>c_+HL1Mg4?c8|tX$(04Oqt>d^kYkqj=p88nAYu0c+cX5Bo?T*Z2cE&&%vP2u|`C zSZKfw><)H5#1UuTKGSQLczU0GGRMX?XD6YnBzoeB5#o`~==Rq5PgFdlUSwf~o{;Xm zHU5(og~IPZ7~ zgbju=*kGSwozt|QQSiV6HEfI|Pkb3d2uL2MmSBj%##r(UwHzlPc|1_B@t#MLd7xP1 z_u#f>aM8u|Tw-gEw#K*Vfy@rVHAD7Mp-hKc8(ZTK%n7-jp-hJ;AZvWbC$_Ee(-Vpg zcv~VtnRY;#wx_o>eq!c6`$!*A<^ak(r(Hrefo3nH zw>5s$w8rNq+d7}dDV#K|@t>_YH1X>axmj>B%>E&pfUd6ymuvjzD#FQA0VLed3Gd7z zT(0q-uL!HpOjzT)IpJOt;ifhI3l-tSZzfDukPDMl3WCFz%tOS-$;wpOWM#iWc-ORS zE4UX1QTXG5da`;RN#=oMelqv2kQ!6nZC@Ijtnr>CTjSd@`LZ>hH~h;aZ2JoZyz0MR zmLcs*|;~GCb;j?e*F9P`NGm|>{p2anO!t}Dn!`(JJ z8=uhI3td6Sj5zz?h-R}7zG=a%kvg=oP#M{rrFVvkLq^0B+teH0-WvZG6%VPKR9NHT z?>K*r|I3Pk`a}f^>cJV-_yGyB^=?eoWbFG_716>U3LbW#5oS3Y@eU{Y*A>y#xVUkK z!woMb+HWFSuJH#I(c}_;5~WXFQd79})irHe^@-&S8U9#!3g87%8Zddq72>}FqE0-C1lc{M48>?mTc>W z*&2`c25gNFPYoE*?1c2T#t)m;_vWtCw-q0T^zkCT<5 zY_hW7Fr#&1dq$ZZ9;hd)=aFO{NaiOg>hQo)*Cwl(7cTq4l_U|K^)q&Of|j~^+_JBe zaJ+1~`Z37VYy5brC5_?D`}R?-@o-L!vu{af%@FkC>>DkE+eN}2E!%9eHGZ_DvyWHs z$JsYzdYQ#TPmd7y@xvvZeLF}WXCK_5Z1#mK_%WwB`v!tEeVem8Xk)U*?>KRrdV||r z<3CvOP~p(COKwajWvNzwvZ7Ep^uWalgBsTOJ_#ZseVePg{O89jqJ=|GSBQo=(>n^$ z|Fa@mIP|o0qMat94Ic%`X(7OcZnFKbNDuWI7nYhL9k7wLU0}ZetdD;p~PC)W_Ai)rWjUCBD{}q(O z(Fay7NgfZ>YrN-?WF9Eic(~j68b1bcA$;f>FQ76Ory2VU_vFJ{6HYzSfqO_`_vG)v z$-~U$Mo3`yNj|aQYc$KQR>0e~|se5LYuf#NEw)Vu%Zu z{Irw(#1OSW_z9}P(!=445t=fmpU&AQcvQ?bM5iB%WbLEVk43WH(dow`S!0P5ryq-C zT_v)mHIjl@ONm?)my8)sKOa60r=R8Tx@Y0;V~bb#KRDd977qD$46HNbD(Igr96|`o zSJ%xSBwpjqdS1I;UWOksXB~IFNVnZ?PIryXr3VQvmz2*Xa5Mr}9>WX=sDOLHua{(h z2X0-&N+T5tyx~`gtHeWcuFfPq%xKHgbjx_mvuXkw^Q?wEynxWj#t=DC>Uxft^B zZgS5bn2ftVgKvN2bm6Q9zCEFA8@cmptM*tLH8E)aSnycdJy!I? zjdsYAvE@#gaC=6=-D7CZn!7f&Rls3f3oLnzcqRs@k}P;OJwncvs8#iuk?$4NDayAv zGSLqPShTT#tF<@RI#~8kZmxH*NS)lg%)7EdL=tSSbT$?sh~qETl@Pm%SeUSHu6F26 zO9JQc2L$NA0s{MKTu=iey$1iez9-yqJ)|*>6Hd*jan*BKiiK zqRoq}_;LQha}WFjFyS9;Hu*>JMsu`~Lu4lgS2h-8s`C5P#)1eu{64+0ATkZVPi!oR z1jFw$8w+B(!SAyh3t{N)*jNYyc4Cu7$c4E~c5Y)quFK{3`3>NeHx^!$1iL8st|a{E z#)7PYR`A-!!rjTQt&N3C9$ea3xW~Uy@S{@ji<6j(8w)Q zJ-f28aBmV^*jRYE2NyRMUg6)!&^{(bzcPufB%Dvw%6)T{HT%ZR!UDA_+Y118(& zj{=kX3pGyuauZJON1SXgRyY~5WH@oS))~V~)V->Gu_+-@Yrx85oS-r(CF*60oAUiqMN9d9 zi3;EH{r|CdAK-IT=e_uUXGRh#fCM%eO#2D25y*DHj$@M8u_QNAoDkbdNGEX$u~SIL z3D~2`P=rPjNGpn1K%hkh7SV=2h@znnO&aij!-uv9=|G)P! zek|$C?tZ>g&Y5%e?Ck8mattjSplWDp(LQj}6t*3zMSH^uRE$D%EbnS9w_|E~GS#hE zJ!`Z)G3s`%7VRb1N^k9+@?rh&J>;wPzjrqqqw2qU*={CJH4(Mw(`GNIMx++)Y8I(x zrWWmD7OB&YTJ$NoNJs4~UH$K!UsanM zBe8=M3latHQCkwICA;b+2aW6`|1}wo4E$BKM-@QkC?f1_iM*6%yzbK!m-@XmS? z+4QR27!b0p$q!$Kmo1I1=*C`_Qrvf_Ap8em*Qa5?*3g0m@M8;7_P0 z@TWYW@IF`lS?(5fmN=?s*1-#94Kd$vOW@xJmE)NhzSAN9lMjx< z%T>3nUk)t-mL4MifC>k1P2?Zyps91xwCa`c4e#;?Q~Dp(18&|OdO)Gy;QBMX|6lzN z-n3jKM(Y2;S2jJ*^L-y~buo7AxN+mQf!kb6m@skT#7UF3-FDmU)NL)MOqsI74m<9+ z<0sVbr|i7*r#|(mUDSOmcH2$zq*pa1+9)ZHfzI_QgE{Nk73b`xLz@-N9dP82u3vvUA)wqoYU%md$> zG$M~{j}9c}23F7mi9;qqg;+mJP06TNtcF)lg!eqKFsN%Vy#hZEXmPm33NH3XYLCh( zUNVL`t~pwV>&YPb78};0U%oZ3?iI1Hdhwi{<%G(1-;wL>dhz;M@;!dJX-coOsM2Pa z+P6PKQ#*#ddTI4)y)NG}uZBIOo~*tdSlbZCx-6?Sy)NH08XS|lrVapEmlf5k^}2jx z(kwC6n>jjlWZRiAn>-6{(*Ql0oVPfld51M^;!4JX1;^!xsW9i{&GNrLX2#6jAmQti zK6YIlo4%?_(VPBjhJ%`iH{I-u>L9MJUadF%YvrbY0ags|Nl@SP!}X>!)-0&lb&M_V zZ*X|I>Eq<4?+*#TY&YE)`k+_)({8$XMwPOmO3|Bsu-SBIR(R9-t1qoytvCHE<)(iX zRt&yJUElP>^rkb`ET~rMO2(Go$v&*y^ljy)e+3f0^wFDc*41u0Pf4m2z3E?^Gz;by zXKoq+`#`+*hYo+>ZmL|pQ^0~cduZ*zZIlsTu&Zw>)&IeYHBKWAQT_S8q7I}BfGcUPKTm+3|`Pqv$8`0Ca7Rj=0Ta==Ht+MbZ@VKscE zZK*W9F8dn|dWMgy(GOOy*6T8@tkI9lBL-iYs#oblbfsXfSx~LjW6UkTesxG$DfW_8 z`e7NdudNhjN3lI;H=f5lRmJFy-{&JY-uTr@_NrIwjo-W6_?P9H!5Fl@@iT_s_!pTA z7PN>N<;H(qZv1mHV$c7rjeo6*(HpS-o0s{O;w(zc1Geu6eI-{K3O-{JYF8 zub)4--1rYhHw=_Ri#)^xq82p zSN6q1eBxiD~nB`TBUj6OL)n6%XxInAE_hA?W|5L-- zk2@coUb%Yp%Zt56%hi8W)t(hHV}f1(|CQe4>?%jE|M+tK&zJT%y#BlB_5aAAYQLmkjQOb5=jVJATcxb8QuNyUvgOP79cJWRdp9wFcN67bS-&exByIn`%KLP*gH+AwY-8SRpfATUn{U$1Dn0~#Fyor*B zc4ksezp4uIQu$V9A$Uf)5##k+uUYc~%P!nmy+e^#@vWa#eoSY^ z;9a2t$`9(yBvq`IeNMf7s%2&*^K&#ZWRY^it4Ltw=Uk)S_uy!64+nd^+){Niu%G63 zML8)Ii>YH^6gC$AKW^qHRNa$B9N0v0q1;Cuj*rQ?obp$3@%74sZmjyrTTBw$(_rN(!9Wi=!!v)k~eGPh&)6S`5}U1;KTpN%$$r5Nm4r`-KIkVQ(fgD zfmMRas!Q|XfcWyb$ayfhO)OlB=0mtVFx%+^Gv?zD%(k@yvtg*Fx}!QYaA4%2kJ0G2xxHJk~QO!M=s-BjMg^aP5?AQ*w@5 z{S7TjeX2P!I!1pgT^>n!2&aDkTlx@=n>1zkOzf5UnKEhAbutV$LsMas6x`xHohAtbUPKVIyMcJ4a zPWsr>yEo(G{|8MT_K)lUbQe%g>*-t9!hGKLljUR{{1CGIC1jY$+hteyp<`R^W@a8g z9~7kO$*-Kw%zS$VLr*pr*;Zw9*}XiS!hNr6^>O{Iq?|R=^%M4NIZvj_<>_B8Q5Uws zb)AXanv>V(SD zrz$ySu6G!=b5WmU6n@!hs19Qn89S@EP&LSdUTAM`^{n0Hlsf$V z#FEeHtsTHFEicJ|CkA7nkZ;^%>ShRK(;a1gL)9#M9(e;%IJL=!u{#{Bo#0@}eoD5d zQU3>Wv79LSBrG1M+nMRTp!0%WOEww#LKt7er2aVdiXEZ6qZ%oEaQe|_s&e!#N1Wvu>N5bqWV<{=dB@0sM=7ZbiDk=@`+RSB z&V)%br^8>e?}k~FTKg%t2A1fGqT7ktysBBOuC}68HVcWtS2=xhM($Kk)MsS*#PX>) z#H3asYpU0tQijM&+o8on^+kfJ!u9&AD>s~48tN~Mf~sVGfYw*3`qVmB9cFW_rQ9ba zP_1c~y{0-H|D^UIjy&tadDR~o84+rKjVHTncCgi)BK7X_;0=r1*eS=9ADNDa#wp9A z@NEdVCQ$wpF1u43G;_S#+L(D?|K(r*?ce|7Kacv!fBpB-$NcnXftW4kh`C~(m@gKHV?`*A6UU1a#ED{|I7uuL zkytF2h^69Waf(4!w8dHCY;lfQCC(M+iPfSb&KGOMTCq;7 z7Z->NMOR!THi(PGCE`+XnYdiU;tFx4xJq0tt`XOY>qH{17aPS5;zn_kxLIrxsklYl zDsB_Ei#x=f;x3ViyTv`?UU8qeUu+gzL@pi>4~mDx!{QO~sCY~i;&JhWcv5T?Pl>0+ zGomM+70-$1#S7v^@sfC1^u;UURq>j5UA!UQ6mN-vcw4+9-WBhO_r(X|LlJnhy*b`o zZ=N^bTi_k*h2C-A@!kpEiQYo*ByW)yd5gUz-cs*m?-XyDx7=%aE4)*^)4bEYGrX1F znO@sF%RAdU$6Mu{>z(JV_B!7A-WqSMx6WJdUEp2lb-jzc4c^7xCElgpW!~jp>|Nnq z>0RYr?Oo$t>s{w1-u2!_?*{Ki?fm+ZS|h=p7x&cdfv0%bKdjb3*L*~OWw;~ z-+RS-)qBl*-Fw4((|gMscyD{}c<*}edGC84cprL!Kii+<&-Lf|^Zf<>vGCh9$N9(m zC-^7&3;mP)MSkQj_Lule{geGu{AK=f_y*Am|5X1p|8)Nhf2Dt>-}cY)&-TypSNZ4q z=lQGsj(@(t#$W5N^VjRj({^l$KQ^l$QS_BX+gy4~X6>fh$y?%(0x>EGpN{@wmP{=NQv{{8-De+vv-9`GOZ zAMzjeAMqdcAM*?UasLVbNq?*Vl>fB<418zvS^qizdH)6fMgJxLW%a+l{63hT`p6F8 z?{#{nBi}kf4f9@+&!3r1w{Lce>7?_Y6WG`2&R@L-=KJU~=Y7;Oi|KH2_INWLmQI($ z1GUV4|F8IrU1qP??v2`I_O~b^b%~vNt^F;Ej=EA!EjtiK@#XzQ)Mblm*}>&yeQ>8F zb&;D|Hp5(D)>4->sbwSP8njehP1Td@JOi$NQrD%yV5b~Kmv{TF##jrgZPq_Kp^kw3 zYNP%HK2X=G+OPU0YU`DLu)4Mk_C;#O=5iEQ{<}&zmL!a|ntEJb&&~ zQM0LX)ygk`z&~0>Q|}c)-?!4)`=p5JPZPaRry{EdM$>x!8Hc`@=}!?o#CpeQT2DUf z(3dcME7AMv+GV@$q0!8q+0UUbW%`pu53xQVdOFRapUm_ph~8EgS=)7Q8BMQyyuU*~ zh3StIJye~E)kCA1{XX5HFJpQ^^sc&wyVT*V96(W4(ca!#g_Kzz!UNCUwb7fp*lj;I{9~p~%wcm-JgK?9npJ_Fc&?60v8rJ`_JzUBT2x zh}u>iwpD{+)Ki)IFj2ee>U66XQ2f|+J&mak5j9m8xLb7q#gA1_XX=AQ?Wk+ytr`rY zp25@yh#IS}Z&-Bz#gARrl}ycvnyR6cRl{M_Gnu-jrq*i|T$OFUUO7v*yYLfLyJI~; zyOMQJu(_0N{}QMRy=|*bcdXi*+#7?M&U%8gn0`OeJL;lttH(yu>mKY>tvl1tX8L_Z zkJQ&ftls$~S$CIy4%6=?dPjZH#OkTh^tu;2JJx*_)9)dAqK4O2?;6eQnOz+ExlF&C z=pFSXJ*&6N4;;!dIULo#OFxh48PQW1=GR6KiP7}B=es)AeKphXB6^`N?=ROKPWYkx zt_#G~djeVR?@*<%df#Cwca|wqgRd9tYCDGVhUIooWmC0kjzcYl)zI@<${l1|%KH{u zy%@!M$BgRaM_06STf_9*iQa;@Z?)qP5g_$qx^L^yFJO8~^a9>G*7rMnI9DH=r{*`VnvUv) zOy5NH@}mLu{uE-myJ5Y6?|rGXCcVq_n~C02jmhqr?x(SynY;ft=@&8mCZdNm9qRL; zazClJLo@8#Au~*r4UE2d-%thU@!XANfE{85YCgbruW{4#fGgo*mT&_}h{*(mDynU$ zrUzUJm#~D5B%y;7x>Z6oJ>W{XlqFnG5?VN+T_sf01FnS2SVBS)LYxp)3Dxv~E8%jM za2-kL<7t{fHBD1Z54aLymT)aeC~!irN~op>TnSgOglkAbh74Oy{YyL^cVVeH z+K|HP{S7ST;xa{QFk>*?4h(y0f$eDu9j<5fTIKzh?1(z4g|cq#Mi#n(Y+9~$IVTOP zk&MHe)UE4uoOlz{FCuz|^}K!+1f+Fb`pr!55MEkPu-YC* zy_c!y5H-YVG>m#5Q_m)9AAcGa45Qx9)U#@8ZSd9uoDSZC+UE?c6Wd(LdhpgRWjlB) z)cV@NTc3Q+5Y==xGq8o}XA(WfdT2D=&9_at>CBTeeI?N|thbD&^{y#5=?^gd45Fu4 z?-)(%i77Yf4>J99qQ_W|ji&Y7l$-R2n0^}3yI4<+ruCjFH|Y;E{ZyiNuwEEV>jP76 z(jQ^^3Zl1bI-K%bP^9N(S?-yd3Ms7KKgv>CWs1~bMsPnnc#CRj@JL?kSX62)h1LJZ zSjuv;EdkauqUSEXVEQtm57Y znZA_h8P+>Q@4ED@OkYCu6zgrGcU<~YOkYg&1nUve+b;cSrbk4Nu^tjVa_P@7eG$>S zr7l}eFs=I8b+r`F?iKY9M9ev4FgqFd&$o3ITM~|2`7+*0w?sU1UtLuOn8AM98VHboRC)u zc6QI1@FGh%jwHl5A*mAV?4C2>C6*A9gbq&VRta`?&zbNtOE{J!v~WVZO0ctg&V)Wo zSWru-4G<%c=>V~9E~;tjC|{{$JwTja%65Pls+F~!Ov`Axv+tU6Q)mAw)8`R=pss_m zddFy5PfWQjP76 z(%)oyK=d5zeWPhTG-u}~{Vk?{D8Je)tD(L$GsSvfG_AKxxk(=|{R5&WH5~?sF%(sY zW4bP#5}9p+6gEJ7o29&8rbrF$B=;FRKbwTIO{6j>#pN9#DI zzDU#@tHm(t@l1Vzs0minVbl|t`g~2T?ax?h`sDCjDchd7tJc?! zuM(r_?y4~5rk;2q)1M`J2kW`fwB9%6CjBI)_lVxcde3ND56lI>P5L6HKST5u)(1q7 zTzbUxr->e6Jv5qL_qHiFt@~o8KSlHq>n)>cy=%%%`VyvZC3=AMj?uK9m~xZ8l<7|r zeNek7A5QswDALw0%dt5gkitf9C$p3%$`q-=YxlOJx4f1HkF;wYi+pCcmcpj@PGKpJ zlWobc9ud9c(w8y4AbN`RkmzlfzMScg5k0|rK=hVNZ!!H*qQ_Vtm^!2DP~_5AF#Qpt zcd_0ldg#(mW%|QJ?_j+kdf?JeWBNlxZ(}_t`oLV8+0?pDXZnLgZ(%(ndhXKCVEO|@ zk4jy(oD|xae3#o>usZHJvQYgeGSuZCwhkUuFpfF$($_Qn7NW;kFN~)3fhjlX7ce~~dbg%S@6v&y>~OMr zj{@a^`5pkIuzG(XOW9PWNDV&!-OCOT+iHRBX<9m5Pw%B9v{wsd-CCE0-b^+v(z@(8 zVKow>7j+#reWd;k#*3JK6VU^#$3)Lv`Ua-oNb~{z%4nD9nM=Qz={FF)kM$1GQD^mhxInm6PJD|)2}Cbf%O*AW0!sz(-WfSSdWO_b?KKg{W_v&SPzKacIh$GuO)g~ z)1f{mP?Yt)WmGs}@aerPDprpUuPIqOI_xUew%NFe{TXRKS2Fc#qPDQw8AiQ|saFv- z#A-B*dNot8BNlprd~nR9#;EMWQU9H*K3&?6E(+bF^qa0Q!giKiq&iw zHDT&yM2)eU45MDp)Jtn>ZS>Zanx{u=y01*kH^Q2Fv5l3iM{k#uvK_s3)cV@#z1V14 z&rG?gC%%E{7ZbgW_0(uuFHE^fzme%1h~C0_ZZxg;O}Rm~?_s@VG_A*`+@#;a^z}q9 zYC4?qb12eth%9%_9)lD%db^dStSeKb2Cv=2j^46b8axu!Iu`lNPA!E^@7=~y){<>W zu^te;?b2^&`Wm7qSRa`Eu8%{@rQgBy^NAi~y-)POrQgZ)4$(VU?-6}qzKPmYhwftf zYNEHXUJ$+S(le%?NAwofbE5ZL`rS-Fm*^4JGolwR{T`;TB6^7Rl<1jDznAIf5PhI- zeWGUb5@=(3datjR;_1D}R3BMc>Ga-xRgfOQom~dm0bHR-JACO?33htVnQ%W#IEy4? zI3ceR?DU>9VKYl;lY|5(q*a2Q-g72wVF_oFgbq%Ks{}i}=S;|1!b+0R!U^pv!A|cv z6CPj*XOM&tCqz|(o!)aMJjfDGCkX?6gB~*(T_xD*J!is0Ea5bg(8CFRRaEW4PVYGr z9%c!r))Hz1#6sR&hzt<>wOeGcj`ER8)&s;9rECX?nOa#pKqQ_Wo8BOc4DL3hlGyN2zcd_0vn$}ZO zZqlD%`pHCZV?8mN)^k&C(w}7dQlhu8o*7N+JyUMdw=#VR(W9CU1H=%Da;TP?u1lvB zrY=DWtM^Z_l*MI=)Zp8JpSA>wQV+PV(BzgpQ#Io+Q&D?8$gk*ELC4&>U^RWSnUm? zzRJ{jM9r|852L=u)VV}Wu$m5|zRuJ+MD1cV9!7nGsk4b1VYM}k`X*BYq6SzEhf&{R z>WAfzIjH(t8@&zWjS4 zo0}9u3LCuzbJ!*AWs21H_rqQ6=&e;tgGYL1-SxKgYbk7cZ#GMLgKSHL^@8XGPQWD$)Du=B)O-lM+33>GPTX3ekI5kBOeR^aV`s z6TQHCm*}xeKbGk)6FtXzhv*%b9y0wUqGwod6TRiqk7N3aL{Caxwy_qpF+E`ttEG5) zuTwv1(CNM7s~|mqd!Y=n1GtVN?EtP@CD`dbXTk|A;dzqK!U^pv!A|cv6Ha6a&yj=> zCqz|(o!)aMEMy7Kl7v3KSMfj<)p4-zPn`)Tv4kE;C~!irO0d&=&V)rQ;Te*U;e@WvqiH=iDFN~)3fhjlX%bETd(fjI-;C8?Fji&X;+yS~tZ!!H*qW7>K8cpkM zQ*P2%F#Qpt7g%o@P3v7#ZqiR>`ol!eYdQ=NGbqXqCo)}^*#@)6AcYMOPh%+$l_^q# zPjz>)1H@D*>9K=uus#(|czy{Q;tPu--R^ zLGQ58rLSaqPV_d`dqfXh`k74MLi85a3!?YU&D@)+RGaCWi5_7+CwkANpT+e1i5_4* zBYNS|&u034L?5V|{M!>nLiF6FpTqQfiQdP0O!U;HuVVT=MDNvfsLuryW%Emn3N@2Y z@10w*dUSYq$=cCjqFCEz^Cp%~#GS{~jHq3##>1$qnR*vd+gR-kqjs2jCs8A;wuVv9 zXX+h94X_#xqpo4r{0wAM29HlpTOErwCoG4)oWrdZ8}QP(r| zmYP}{y(Lm3(|cL%p8u>DyP%Tw=q)W}J9>-N`r4C2YBYVyFHE`Vw0R-ZHxa#y_1tJ$ zADD8J-evmDMDJj|XEf7YnO_HK(l28AO+;^FJusTqTc+HkZ(#b3L~mg|GMd&qrre}o z%=8LhvEDVB)^k&C(l2HD^+X@keuV{2`F$wT)~?FtXhRCC z_m{Dhq)d?-bRRp~(Oa*U29I=W9gBQsTuWiodzZ76>&UhgSnm+M>(XPUUrY2H>usWU zT>2GEzlP`;)>}kxyYwrWel^iktVcv|x%8`;eihLZtOrDoT>8~azmn)N)(57(>-rzM z^lO-Y1<|`$?-PCC`W2RInI03pjrAVUdoKMtre99=vIDq4k#yj33htVnUJ!C3u+0q0b&3$9U!)9Kdi($%3CT~ z4-nUvvK=4}@DGcHMl%ByQ*P?)Z)N&AqW7`hHkuizm~xYT8`IYky@&O#(X^hLa+7{L z)7KEaz>oPq~F2x^NF5gJu{ltd#2o^-^uh2(KDc0MpMP zdXDvo=v|loAk$ALdREh+KBrKW&97}#Xv%zg@1cs-qr=lm){YLlinVPvZer<#(ZftV zm8fm3c7{^fuNrqiMZo%1!#yOpl1(!g^setq)AONq>gvi-;a! zy>B$FhpwOW>@oc$qK8-yjHdOLDL1YAvrJz|^Z@IT(X`$%Jkw7gdcUT_DZd9rdJd80*c=Z?VfFq6mU4WVA~l%A+s=;Oidq^x(yDbV>Y23^ zHof;EOF52gOOEx3=xvw&64OJXXIKx3-g48PmF4 z`YTMIPxLO=mu&n0>r>p9W;F8y_;&mnpX>lx7t zm;MIRXA?atb=h)KXk&VMFH}qM^xmKzOy38+Sq13=L~q81ssC|5*(0L0d{WB8SoAZI2s3Z zaX?%J*r`2dz`HEqzi~ht2Xv|cJG18uc#j4A7Y>MUK&uL{6MN2p_gTPCaKK;!uBKIh zo!4^)e82*Zssd{DzYjTdU>HoSPD8AN{IG)c!0>L-& zrPt2?2gVDGM+P&)6H{&)K+IxeWhT zj3*dR45snil$-E*4F4C5#~9BHrt!WhH{tUc{?8ciV!UTCjR&q?WdXyF#CWHM!+@|2 zMcJxygPJWcRTQ>>)%Rmr$UmtNiNTivC))8~q!!qYCDhq^HZLQYy;>%_STAIm|A;p% z(72w=O9)=naXOiI9K-(sX%WMOV37)&~;~D<<81G}eOYqc%pTO`RW4wp)4#5)_ zej>wvgz*C7ZGy)xd?CaC4&yn-TLkaA@RJyR1jaLrM+EP<@I?&&Ta2d|4+$Q*@QC4m zgYl$>Lp|<7QP$1SpwNK%B;Mjm)nmZFR;nGLwUugHYNtu1b4^Pa`d1i@FxnahUCPiO zVl=>LI1G9+L;n(^{cYqvw3|PGBHO8S^G{*uUtqMrXm1#F8AA`pXok^z7<4&9{~V(U zM$=)?7DN9Gqg{-~!=Nh|`ll6IJ3t+Yk-58g8^;js)C$%^v_Da>9ip|>+S)UG*I>Fo zOij6|M?a0>e~j@6_WX61;HXYZ(4p7!NU?5Il3?YZ?BV z7!OKZHkd9nEj?2=7%LaxnYvcJebJe^bybcYrTvD=v7@w}674XhUj^8SI%mLo7Vzsh zAj1Jg6<{yJa|T?%0uI3e2@XiB06S6V47iX5d5*9G43aG(7Igvm{frGM9t)JD@D_&Z`dK5TQ!FCi_s8zM2z`nuEh-9qe%zPQc zXJ9_D;WMYjCV2K zHJHXzQ*OeqWcXJx-obccFpU?c+=O4n@L$Dv8{?V5G~PGmCj4rK{|d%iH5^8P5fo*s zN=-+lLwcr)LI@iLUc*9uS%pXpdZw{<6d0-nwqpr&w$6-6W>L#z6Lr_J%!BcU4WN6h z&82k-p4V|YQFk4~zk=~T#ybShTzJCpU&43~<86Y+F8q3ie;MOB##;pMy6}w*|3!>v z7>@|vap5;G{7V>5F&+}U?ZR(l_!lvrU_2mr%Z1;>@PjZOV|-v5tZrMO3%{A+2V%Ti z!=WB`peQSTU{DC*6Lp&^RSyAwL8*2K*ix!(sqH3}&Qzrg{Q^cqj7Gztw=nec7#(PVYClLwo~cm-^S4C7|k%64};#$&;u}Dy@R3qW3-FWco_6f zhEBt18>5|J(7PDAUxn6=dP`zth}JRXrY! zH^V=J@et!(gK0c9D__{t&}=!*~bdIl%|Q@s90bhJPC4ZH#9G@4N6v7``jUTNqCXUbyf_ z8NLg~Ba9~m&t3Rq4F43y1B}N6&s=!H@SQP!l&tsmJk}+4;<6uS_D#?ugwP$ZZenKE>P}uzN6aTf@3fGj|Gh4@7P>tosaeCu4US za)V*r9&@+HZg)C@kJ9HSQu){^{8{F1husc#kF2>Lnnu*r%RR^7Z86-&@ZmLh#Bp+c zp1G5hJ33Vl30vT&e3hS%6W<9j8{2*oC8I7&cQfG zx9KY9WtOvz%IV=8D7teF#5uZ+S2=x_Gfw3cI0uUEoM|{mxA`jP6_ztr<>WXAite1Q zsTaD!>61Ve^ePJ)qk=LV1VwjHhXj=;g(~MYmgB3O6z4$Eozo^cH-d7b5yw^Prj zA36s5h3biKR8L$oMzu8aL};jGqu$>y&kk^H;dHf7wnDXVyll&Qp=>g0p}M7nUMTCg zS_r=bV4o=~qgtqbtx7*r)*Q7^ovrmkd6?Bg)ivma@{p*7svpt|<^EF(<;G>xf3&yQ zcSLTc`p3+X$&*GV%@mW?ec*ZGXA^!Zx6_;P^Z)&P5Bz)&{J*>hMn|@P!ykeFgy)YL zJ8qlt6DCgDcDwB-PuXF|PkeHxoj%aNiBmVA3KmPlF_{V=b@}K|ZU;pjj|KmT8 z`pJL&_tD4v^k;#XE#`>1VxE{U7Kmd-D2@}yixb3&Vxc%mEE17eES89+;$(4(SSFT> zmRKQ96{m^Q#TjCyI8(I6S>kMQj#wqm73Yc7q9e{1Ys6ZyPOKLfhzmtmTqHJ#i^V14 zQgNBMT*TrEaizFQTrI8<*NW>zBCZ!3#SP*{ag(@NY!a!sMcgWG6Ss>y#GT?Uk%_y- zJ>p(*pSWLa7F$Fv9uNI^kiGg@qyd&Nf?}_)t2jW8!c(c7Z-dt~3Z<)8;Yk4cYQ@zu?)4emimEM_N+dIoU+dIcw<(=!D z=dJcS-ud1dZ>_h^Tkl=qUFdbai@Xiq#oi^}rQT)UJ?U-rp7Ngdp7DC#v)*&w^WF>Ii{4A#%U<7m#e3Cz&3oN@!+XFGXHWv_OI}-^sn--_OJ1;^{?|2|9XF;e}jLcf0KW+zsXPi zTl`!7+x*-8JN!HSyZp?*+rP)Z*T2ud-{0(S@pJzH|3UvD|6%_T|55)jzwjUTpYWgb zxB5@{Py5gKJ^xw%IsbY81^-3=CI4mhzrGyE?BlJT=1rNI9q^;?;$cP*ys$;S@tQd@ zW$Oer%y>mUAG+!vmt8g7_=*lq=2WlILlgBH`Aq2R$D4N_$#glkP|K#63wH9)*k$Fl z9Pm+1p@tjkd81R|N{LbUj3`vUG_00Qn+liyjKYUfZS_MlYT1EPw}EAFg;=WY Ij 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 vzqF4wa=QF&h|Q_oqfhKXbou*0Dsf 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 z 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π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ξYpGc8Gf|_t}>Ow7^5J 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

HXgf*>XgfncNXES2$v9-ZhCN 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

=e#(0uOGu~>I&`2>c^9kxWX35K# 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

4OJUxLqjwTW=5BU(Rm8?*sRJyzIGmG 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μWv%NbRhUmuL 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� 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

  • @Bbn9?l@j3N1R+o4nNC6a~VBN<-47ccE#bqeh-Q)tI~IK~hlX4D>F;_ssVzBBzf zLgxH95|=R9Q0|H-5oWtdnCgqLFFY?VQx%?P{~5>JK+k1284G%|k)sg=k2)d4*1{-dGh^<05J#3)R*i~-;@E&O2&0H+?FQ1daA`Gc}hW*T|{EQ=g0+XWW; zfrS=f)frZ>M4zwhnrPJF5((gJX9#w;{B?g{BZI1Kk}I{X-;aah!5WS#MWx#Sbi&>k zx%GSH0h-C6Fu=egivv_4i$kXyeV0b_?mQNKBYI1C&?5Bq?s9J)fS@r7OGYZd!9pXL z{s^b92y{xSlu_x70s$LNmt}S2)`;uA>we25`XyrGC8^x66fTN?w|fI=9K;G?B{rF7 zmf|7k>oGhtGg2YUx0EY_E1`($S9(!0b?|RORSt0w45R(8oDariYRqzAtql`+w@p&K zQ5xdmCSD)M&4BG1xAyiKN6V&j7fRI0$0o&QB^6_!eHT@`qwB9XJq8K_!ystDT7eH( z0JTXsK}8zt)9LXv6|CPNu65#W$v)VCNcXVMVBD`%2S%BwV5>FB#}87Uj1-& zwTdx#e4y1!F9tZwoQ$Ww%~)Z1D!da*3`2BNI^&6U&fcHkp5Nt{D;+!H$lSbzsy6XF z0$?>!j3-yg#A*FNb|lzK4L&f~Xtku$zJpV6kTBc<1C<%)SAC$L=aRxV3}v`%CL`j( z5U>N=J~!hsvA!76(->`2BY2y@#*t%yIvk~U8ODLzz5C4P7DodfpekUu;S*eGu=zJc-CrW&K(a6g zu5a^|{M97Gkhx=UK$JQmsXk3A!7j2VyJ$&AOHISLEu@U>qYf{3IR!J~FRVZL&op4c z5?i$3hWWY0$HlPi;WwI!!*|&8a{(?=@ozcA5M<#e>=t4;o+C$o+Kw?7{ICNF_XvLg zOOu_3<%}Z+9iQSz!C`R5B*)=td=eV4Kmo8%C(Qq^;$YoU^;-5tcp1xz^ZM&p^fHT1 zU~nQLH+Zgs3e$ndQM%&`I~qp`N_c!>=tcFRLdvV|^gBtXJl(KPbL-TeiIc;0Pn2gD zyfnHeiu?Qfu{W1DaJ<3DvVQrt4U3grOIBk3dRP){avFK2v?AJTlq8sO7?_21Vr?9) zfxnzQMsIM0oWXaC=NZE&Gt84g(NB-BmZD!B@zA2w)K54<$U58%&G##=@(&{jrfij2MI?o1 zvKTb?dEB;q4h|ffWaD) z@hZMN#9tOY7(qf}kmO}7_2MCG5`lL^aB0Mx*Yowkf`R!lUdb19tP7Pbjp!A8J&M;9 z>YJDIiOy}o4FJ@;5Q2rE9C$f1Xb)=hI^aP;)INt*8R^!8I=v7d&f^OPf{_sO9EV%2 zjZc$#s)g?EMsF%`Z#>Ox6{&i_=5sy@{*g0Kt-z#6GZ9@}2WSDl%Ju1+0qp=B7G(`y zJ)>gakcL19i03uG&aL|b!r6}JKE!Ds*u6F-tu}{2JGcG{juvVx8-fI%cUa)+t-vwq2UOFi&pDhLo9pDD3%d^g5=eku^H_0!CkxF=U+*C+P;A555Utkr10v^bq! z{Pp$WX6*rFNaStvynYR~O#Z=|$t;O9WWL}4&o5(vJIW{lWO38tlGH1yhLZIh%QUB<{ZXnSH z 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�$+SiSWtXb6ORp8ABgefigc*>B)GSu3 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

    #+H-7fefjiR+9e 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%0Ap`Wm^{8tm4MR2s*bmYK6YlKx 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

    !6?m#gnB!oo&=Oz9 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�fu9MS>qq3J_-xtf>*;fYzVt5}vx@Rh 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

    }@72o}}t8eX(yT05XSM}p~ zwUs}vf_VA3Yr_5U2yfWquhAHP+l#$?yNTT&cZs>bQD%=nuIh(>{Bf6r z`#V|e{!SCSzcb7pe>05nH%ILLZWOz}Tg2|~4ztJK{l@tFnb`fkB6fd27rVbV%^rX6 z8{_X&vHPoQ)7l@8t+~Gr;;1kDEoO|r2C@6=DfaU97P~+0GIM_$8{?0^61cyiV)wU` z*!}Hl_LOgwG5!t}hd-`@jW;=0)i}xAUVR*it7?hr@1$$xX=iHRpArY-sLxFGR`i7!e#EAb_X zFHOvR$@9BB@$AG`B>qpIul*?He|O@0606HKJ`Q)O>-*=r~ zc1!x*6LbFN`hL6R(qay~OJ$-XQUYiTfqqDDifQnVWg} zc1S!l@s5dyC1x(^{&r40Jn@LcyCmK<@xh4?NqlJH!xA5!_{hXZCFXjC@6XYRk4b!N z;xiMUmH6z$=Omt%_}s+P6Q7rOM&g-?&rf_o;u{j*nE0l|Hz&R&@vVt(OMH9cI}+cS z_^!l1P5iUOPbGdj@iU2^P5fNq=M%q>_{GF8C4M>azj}QCIQjo1@gEcaDe<2Zf0{Ut z=l|^W;ziY8dwct?@%^8uACf+Xb_K9~$%=JFspB)nqOZ;8)nd6iG35ickd{ScW!t(NP{m^-0Vq`8qIq@lp zPc>$KbDB8jC-CWsCnuhgcxvJ^jG5n@CHDEsw8ZBnK0onAi7zoGz86pJb&14FCSEG> z(uw(dg4gHjiPuQHX5zIHubp_E#Oo$rFY)?`H%OeXS8S8y+a}&F@%D*#NIW$0j){jQ z-YN0UiH9d1m-xWM2PHl@@ga#1OMH0ZBN88(_^8C=6HiGzHSrmV&rEz);7(!2iVwZxKJcGOS3 zOZDRIN@(;d)momU>{;<%)q3@6y-v0MVu5l4U!*Gg;%ODQYvsQKpv3h{68D*qdY7x( z@FmNQ6)Rq>S}$JdSJ~8NZC?t$Ua4HKQt8c|JG}>Y&<~#8qxj{5drQIa%JG7gUR9jp zX&8R`x~jm;9!AT3m`YKPY~7h6?z7f*@v!vV#wqyM|NUxTwTF*hv z#a4&K8jAHI#s8952ZZZNq|xQ7_ElBTugb$%JNlSoj^U>tE1{zJsE%*3s(tl!>1fl+ ze*J1)Ra48Wn|H5%-+6dxuxfQ+7Oj5oSFPWwD&#K}AJ(>QLxWBZ4_>&|^yDvfyYR28 zyWFXC($`9?{odX+~`*ori}zBtwkSGZiYKCN1>SFPL6D|cjviod#kZndLj$TU<( z_^WQE!f>ugE0u>`k3n}Tt8yu3HcG>*h}^iu;xT?U`&Yb1wce~+tIsJ?tZMyp{ z?eF__Wy7nL#Ze@8DHV@c_NJZLnyW-fdsREkm2py^?aSDkJGY_W?%j)3t#ViE_4%`f z=2=Uf)SuQiWolUgS9M*YP#j)W@E+eQ?Jn+AU)01VB^ECpXLJ9}9xQ%&s>-*=;ORw^ z(0|46bLaj{slK+K5jmshS@9_djQ zZ2k?U{E%w@eo&S7;9;j0mLseE*MTZxf?Er{(=DkXg}7a*9s++t+2_sNRbG`fd4h@uqS%pE|Pq;h8F*TG@ja zFYZFpRMks|sy>?*D=VNnoV8D?xU6=sHl@Dda*{= zlJBXGAD8Gz>M)Bv*sf#AJqPzF4(#-DRlHCG$-Y(lSu&2tUZVp}E}A zugb$$`+7pH>6726CEr}%Tx2o$?b1Vi!zqR3qgBP!7VK8A4pi~W&cn|u#?o~PV2`H7*y)3U1!p5A4^ zl|#FoI%L5n$(z)=)yUsprLsS_$KW1a&K+15M!$7ynml*00nv|@fkv>!oZ;N=GkXjk zIBfdh)q2!cnP01I*?aKx$yfF`Z|I;}x!==g>zK=aSchJNC-oS-n1+zS@;mL6w%z6q zSy0ri$AUW!A26t@c|B1x@As;=y0*2Z$scIr{x(%;DRxvz|AYVOKo!Xk$G>&^Kb>FN znc6h{pmy-yM>>pM8j|$uTGQztbD;Gw){|^}y>!_mvflp$rl$WVl=I(E#ziN5)!OTX z39b2Sei*y^xP9l&9X@k}2CU)3Ck%UOSf8DS-!XUYlk43vWcctt6Nb;6yZg+GUVC8f zh?%=zbkVG(CeX#)DCOQSJU?t7&6*}Kfl_*e|L77YOrA3NBGQz}QzvU{nF;HzyYAwe zKD49>-Mf!w!nNOiTJ_e1VuH-xz`jb`PAD9F^IzdZZb)*aMLy((|Ee@$;I^{fmJ*O2 z*;eJauJWK_OrG3TLTk(z|!>&3Z3er3ve$G+}?zwbxFbJg7_)rg_q&XhQcn zWdY{QR?_B#Ej?|!#TFAzyKw5%si(B0wi7y}G-0v-hrM@!b8FoG|I-U?UF*(q98*+P zwKJWz+M-N)(fd{JoFmiebf)dJ(@yVonY4l+G$>L+qk@zm2!c2^f*_8#2f;2m1VIo4 zq5o&^wLWtut9AU&|MmTy-|P2!{pLm2d+oJ8&-3iH?@w;xuk|?b*UH_uneuVC-Q8Pz zh`-k1;;*%B1O)%n)0_zt#%z*IFa~TJ7b3>gP7a z-~Wkm9Cz8_t(G&@2g=8E?BTG`f33s2b}0L=wR=ZL*?+B_yY?viuT`De%l>P1bXVv5 zfBo0FwMR|Yvj1A`-G{gT&!RRZ4}hUn45MqS7)D36vCD?hRSmst7{goJjlmpGs~AR& z8hZO-*t@riVRUXSuSVAnYURpCqE@ba7(H6WFuJz>s}xigHT3e4w2EO2Z!NEe!?MeE zIk$VqOZGXUdVbv9;}VO-XMR`Z1r}@Svgg&8BUJEn%h?v|XU2jl&(S0gPvMwv+cZ*m z>cIT6b;IXJb@R(P4c~5j-lUz?E+qe4i}mTtRl6T_7-r5AG@4l!3*v3|8Oqm$H9xmv zXpGOVs6WJOo}f7zElReAt@b!C7Z!0?=wQ(vtnU+^GkBKQtF_!(+{4ZBG&J|`S3RI# zwZ$56snwh_Z7aR-F~E#kEEj%3lOA|kLkm$H)6c*5A-@Ob+ux^rOgYS(K=GaytNTjT z!L=Q=6*Q8X%{0RQwx5mhbRzF5<|mKT=zTn%|F&=J5!TQqRhv%6&ScdLe7w{CGpKOb zkz-q^u;vV>8m@gcmC<$`mGQsr5BZM9gV)F2eSv%&ScO-}$ANcnj(qG$&!0!@cM|V7 z-w8kVIOX%)oaO94Q9fQLk(*JE(`LniEPcxh|2|$J;#Ib_QO!v_zuI%yru z*+R9R*FHo(?|_z~IG9f2iF>@pGjcQK)0(SqO1_6^FxSjxe4VTM!@<{A)cC7G6hDUZ zyRRm{5Bt4tCw~z8TQ`u8ms2^>G_K=Se0;2q1zKat~~YUJZ3 zoE?kE@6GXZM7{P}Tpq8VNPbVwzg+m6uB3P+$L|yICb7>Z#QMG=@>|}b`Wx?UGyYnV z3 zaSZ7zSf3Qza*OT9$`#(qQZ!WQa z-TM#9AIbUei}6>B`n-J_zZdI&7U!I|#qrulr~H|m z|Isz%SFwMos7K8(ier2S^3RMQf1}ucUKjN`bv5bxaQnB3`d%!ySJnNLkBjq*qWwYq zGb-2~Uy1k{u|K^mj`w>-e=l#Pz7mMTR#Eull_PkHjfAThp4`lsg;`kpiiQ+h)-1#$&2QPWM-zFc&|FR| zu95FJV-iMHn@tu7k`8Zx@yg~kG9`BJ~Q~$VT-?)O}Cvtp;*dEu3^_l%FUFmR> z>`s>ZHpKa+IfOX-&KszI>eXWTMVvowe~#kVpOQPs$M$&ab@Fk(KIc*LX%y<4p`WIf zaeiy)Pd=`vK5>40iGPO{+b47nwTJ8VaZ^Z-{b`w4KliKLGd~PSKlBIjq=@Unm+k$L zuU$p=kQF|@75^{$wHHynuzwDwmp{#K95!~bW8Wy>eq%*_eSaf8&fkyxg?#M)mpxB< z>>t;>MRDUbMdPp9OFq9oYq{|b@^L>j|K9TLd-6vVKZoR&3gb%$)L+FZRKFTLWU=qN zp5oe2il4HI+M`E2bw9X_e2S{?BoY1@B7dat#|r;~UNpW6b5s_~)9c9Z!~QE`{kH!` z{p0)+lYXA!IR1yfM?TJn^DiME=kLyb@^L-*+k4diWbXeS;rq5yee^r10@8o^P}1Xk zb^KWJkK^_>99ACh^&0u3INl_D-Tc--^$p!@wZrM@0={Ledj3k@rS9FgbkTe6X|@7e z^C!;b<#p#$U)cA&J89if%Y&^HKbFTb>PGVWvp?ht@^No{+nwZN-&-y6f0p~|Bb1M~ zOC5D9`FL=Dd@A`k7wvNj`M9?{_rg#O9Z{`5-e1M|*NE}|EXIFklG-21>-*IJ_WJ9haFD&*!L&e$jAQn zy*M{^J&WR~??=~>k9*C_#rCc)()!`~{qh*)pTXnn%J*Klm)ti%aqOQLiT!O%gyPsA zb7}I`dvtV1KjNf%4*jf42)21UIkxEu_Z;kF9Nmslf|He}B4`^66joGh`YO zou(|7+4s=RMh6~G#r;$-+jgqgf7@SqDUA;oi_>|+2p8vws8{D6R3BW-i+nR>;TcW+ zU0OdoUv#B!dGFuHD@43X__Dn}@@Gt^@!|md+vl{t*nxcmDUK8B4KI;z1L?r{oSbSj~jjES=D~3)#@`t-7)*vZdTT+nIRuHSf# z6l#BmYt_t<_6CL8->g}6Beb^@gEpqL?SD7=&>yDTsEUPTYnt{{>tlrWM##MD(#-6N zv*~i{yOGXOwnZv?hY>pP9qP6HS>9@Y(&(aMcOjn{vVXW6m1c&j`1H~KG-%b$(3IVU z?3%ec++dl?XNGF{{L%hAVvQT2P8-yhpIB1{dOO)-HuW=M-h&$`etB8E;sF}p{Z$9@C4YHY+|Ka>w)VV~^eyG_zmwkAH?fT3fkQ0T z4bP||Rr3+EyJOo(?T+J+U$e8QS8}YHp?q*Z8*6uW7#muYM}MDIuj9PJ1IBXoGi&CF zx-H&^_SfT2nlp;xF>_V{aob$dKX}{b2PuAuc_V<$V@uKIJ^GNUt0^9)_7{-O_8!F# z413m4e0y2{wl^qm=CTf4-gCnjKAhgTEBJEt{Y1F zBWd^J@zoqfyVq-(*$-2^ml?P5?pgCFAEEc<#!-AA#d-I(oloOm`eqAn-XZ3Nz;-q* zuQ{ZPDciE@1X^IpnQS2N8Ng_+WsiTtIa!6^k1=+*8h!*XSygps7zlmjp}#Dw-b5x=zjCU*S7t4 z8UG}6{5bsWqp1DS8=mk|`=e?7xxU&;8vnD8`tG9mcys?l`@3#`TlxNDqxEZiJGYSZ z&y>Y=jz99=2%gP)mg0@1vyZ0ryZid@G}6~l{dxQ7T)#;8k(VfbG_4<>o^(FEKMUP? zFU50*7#8)_TdDo{=jZ%J@h((<>|eua9G$XZ#iy9t-?oU__0`b+`N?KC4&LV2aNyi`TqF`qL*Z zZKC*$vbg10T90)*cQ#YpRTj5%{P2o9AEEe_W*qxp%{DrIeM9^6@xQ4oUU4Js-wQ8& z=n~Q&T(*B$Ce!x&@`Nk-33nm&kNrPEsN6Kjo&g}dzlhClZ)j#@S`4Z~-stUuRv^o#%wHx~I#Gs=rUZYe0b1wW_*3eljYb%U@ zp|40%{Ox|7FE^H}_d-+{{~}&9lr~Mbk$3T`Uu4EHKKoQE&73(Czc6&_yMil>f7>?Q zmo)w%r*1jHSgwBImP*UJrtK?=KRN8!(G-8MEMBvY#&=%pO&uxzQCZxFc-=Sk6#tmw z*HOFnM`(QS?al9{vGAphtvw+hKZ`o2K+bf?~*^au7d^?Ybo(1)okTaS454vOzb zmrm?I7tx_zI(pmb6u+4+J*?N})AqaihZo`$-$?C4zl=^zN1b$pmEuR5aSe}iIVyYm z2Q(uu#1C%T@5F8Q(0XYfQ2k1GKD3(JUr6KQ{w)_!yu*?6Hc4yaT||)O>6C1YGg^-zHNDlYEZH7NZ$9Cmc_NMG`6adZ<)6v z>htAgar^reUo-S(-uD-k#q}>~e1AFb#Jf zszjH4f4h|8w&U9CHQp00`DWl%6kkvl*Y6;GO?LjH6pxn0ZFf?9%Pqb6DiAm07M(V% zzMGkV_WkR7)0X^X{w7}k9_ALqmZsQtaK zeSZqYJC?=m96xi!hkYnc-;99$L%)yoolpDg-zeU>Os}&((&5#5ivL!&eYL$wf6AY$ zKc{#S2Hd3;&+I{1)7|8l~KeNO7zud=Ft^?=jP96e>`-1$qE zHZNP=vSQ`hbr!4si8>YRt)ELRXkFEL*!QWi$o?cP(qC6UR;QbbY;!ovVq|5FEE@~$ zhEO*b*`M!Z4#IwzTIBppWj)x@{uDQM4%u0U+{)+NLFV;beRl`hrzvimPj<+%u6)Kg z&b;ob@8UD3W-OeizfE~ZUzEI+*8CXGJC-c+xV`!(_v=M@J$Kult)AL*{P6i#ly`i2 z-ZK=h=|N|NBkqhpMS1&}j}+>+S;%r;g-+Lq13PwarMzyOx3_7h@GPqj@0L+h#Kxcf zFGkV7P_;X<5fiaU;WyOiMv5Fc;~($Zjn1eQ9Q0Ph+vDpNp{S<|2J9 z3GK!r-&bbVdRnBJZJCR->quztt+ForT4g=cf!EKzg+e#{Q292kpR)(q%g7?{7`o5t zd+6Me6mQ_Xd1ZOF3#j*4_^=NtkGD6rJGZBEo^R!g@!jRwdAs}Gr}2GcE#@fi3EuCX zR5O%2@@ifF^ch_QG=5aVyZgc+mC1m?9cWk1(FU;F#^%Fs4IZx-jgX??TM0uZZUbZaHb}6;@%cV}<*3WR> z%Vl{w=N){`AM-OG6om*wf4*Xf&|TB*ISIWJ$9XSq%Lkmd zqb$#MIkorPcK7MjUYhgXFU!+8@0c6*y_oVo>;hMR_mtTHj3en)f~CW!+-gX5JoKEVr4~ z&UrfLbwB*Ohp68*oVU6x&wdfDUWXHodxP?VoOe%Io^3Mq+k5KyBPj1K&bzxTPv1&; zuPqPI3R&*pygSSDe3ZB9xMBxtFTi=*%knht_xw*CHI(P)yxYt2Y}=^4hxa@8uatK$ z=iOJ9S22b1&K=P67RtMY^R}9{#zFP4-KMU1+ONjWVe^wjHx_O9O)c8%b-HqD>c@+$ znz3Z>8eU|Xt`^yMn!0`VGJDVt+Dm1bi+ppsnv3j4)&_fAHT5GkRbwpCj3s+(14-w* zTP^y`STsIHBiMCv^bo#dIFu~%c6p7jf%6)VP`zw0deM2Uw3)_$H=2w1Va|S#F&1-? zZ65V(*~=J)+;er}plz`hg#@ci*1Q zdCT{^;hlfm-T~C!)9L;ANcx@jIPXV$mtniKXVo2QosXP?BmI2ZJG7x(7Uf%g7aPT^ znNExB>IbT`rD{;Uhtc`cQe#?t60qVoYN5Sv z{m2ybVL?CB;-iFmhi+yM?S1Pur_sX^Eci3^5T$kUSx8XR&bNMK2wvQy3oG`bE*>X^ zZ6}QhpLT?AN^{KU#zf|Nmm*v~`q4hm=!(k^- z{$i2eWcvC}+MfEkl)vc2&!d!odj;7$*xqScs7=iSEEUzTtC6Xn1E zKsHAC19&`x*bX!;+P57^`OB}lX)NVeab7js{$=^v651cahg9+U+KwgNxom5XRj1Oc z)GmE&MTE}uu(n`lGqt9f+Ayp&Z=@zW*!W!pwlt0Bka8vGe}a%65Zk^^+*y zay%U;XK%Fdc7tvc9|u>n-E3O@MAF$Vpd+%U>y{U&zjwI(6x+AizH8bW%`c^S^9(b0 z(HN^?>tBA^TH5~2YZK>9q2)E3YSg=<-D<@KVtf@nX?$<~^B+D_D~_MGM{i@f)pxZ~ zznVYOK7(f`?Nh2}`RjHxPzNus|1E5tR0pn~w#zdWba=M9 zkag#k>FjUNwmjik|MEXvFO`6C>b$+qpR$8r^+SKVx6sv8QyrI=MtREnyPn7AVSA%# zZGEX8HG9%HkG3}PODU&SlbGgp_*-oT!4yfeU z@GP#sP=A});?>-%OkW)d$?MdXR5Sio=k*2{cVh;;u@~B`SVwJM>i_N{YU_Sp*D%`$ z*gi;h4vpRNDcR8j2CX1np2zSF+ppPv$M##(`lgf4$NDZ89m~@;S%q5*RgSK7lL_cr43;9}!+S}RRz_!)2ZTi)u zZ+x=&9QA*l&|k~`HEcJR>1)=K{-oxMZX~^1=&xe`O17KI^x8Vozw(WK59zNE`pejN zvb~%vZ@-H5wB0vdxACu}@5*)BgKZbKd$H|C7W$J&e`NNHM$-RcUgIs6AK3oP_E)wg zvaGM^L;C*jhi@SLWb?^Eea$r6No=RGokEuN_OEC=9(MmvkCT2Ck8?HKm26wst{@A2 zZ|eVoVNX&+mTDenKeqkZ4rDukEY|-#(!cuSq(`a$2e_Xw+XvY`%Jvb{*6_8uqCnm5 zxiP<<^tbV~?hdwowzsq0W?Ja&-;sXf>TNv!Eu80Ndn4PM*m_J0z5Xr9KHXuzfcn3M z^KNCkm93BM&8F2hkWTAP```Mdy*TdXYudGJuVK51?bU4Q_^OCdJGMuuj;F@%TTJ6P ziMKb7!@lhIV_V6#%Cu;wLZfyz-Fe)1)Xq_yhj#wL{?TlYWcz2+qMe$jsGX*>a`UO3 z!#EG^9M1j`Y!6|3=%3X!_EvRrJ=Ip?ImdqVZV%s=r8_T@uYPGlh^GY z7OdNDGaBm2!sFOhu>Ff^E4U$z8;G+ldoJ1NHyRqu!jsunv#m0%-ibz(`s=aM;HEny#9-`VE*|)Im z#)Ebhd!A`)UZHksnrPSg z{?;4#bb;Mb+HS0Gx7@1VsRq@jhPSBkCUE1g&GK@54$rVwEnrBr$EZ-oJHd@VSS-iK z^9*ZsZ&#ArI@mv>Twjb&33%^fUKbUr>vQIW>cd4FH7&1VzlQA;wl=mE zhw)}?_Zc>;{XV1V3jQ#H#!c6-Uz6u9*yYQ1?)=dO3-7oU z{2qs{>`&o1J_2Q9e;Jl@ANVMih?QC1w z;+5a?*gv1GI>%VG`;9v3IH%wogL8^l{(E^iH?@yjwFiu*eT&8Eikp!-4G9ujDj&Cl386;@qNpId}Sa@ytB_j(@JX-j( z#OjrF&Z8In=~wKGMZCLM_zuuQPm&f~M2&B2H2*5t@|>*t=?-i15j6n(bb&>Ekf&%Y z=%BzEVR+hr4IOZILbIdl>zeph0Cy{Nms0a*z8diJoAx^vv#K(V~2gVPTlj(UjG5S^y<9<&wyQ)_#g4jXB4TEg=G)c>E*SvNjsRsyFxoc{21H$a>Q z`80VfRl@QgT0HPei_;>O|EK={gwDDxZdL-PTbzFJbUI3$hUqk2aU50RKed>$kQS$F zEdNja{|TM-Y4vWey+1v${Dnw$r@$51pDpGlXs)8BC!eGKL)$i6f>{%`c!3k~|J47V z(%FX51;_RQUw~TYHI!d?_Toq162IpVCwgi3;k>=sc3|6)E%H0D-&rj0CVb@Y!OMT; z{`dTyJPR-HBI3XO!MM>+E9cqS?qvH5+n?F4XG^*cR4fah?Jac6V6pJDTHF2S{+x&V zP)wu1~ z0*~e8JXK@q$^P+dd$B!%ZEvaBDuVTNN?LZMn zyC?t7a>R%HK^%Ffh`iH;e>(d$Vmb7~e`h)3up>p@nZifjnBQ5B`2VcM_SBB1?OE5| z?JM7&o%vA>{o>~a;dd4By@mfP9~vcbh(Hh9P3W*3cF#YEBX2K}*G2e0@i=~F3mxn) zzq1^1*dIk+QTQFX-<@JP^#6No2R=?avc-86&-Huoa(X2D*LjuhIW29^`?NRw>$!g) z*6qs{^8o+vJWK`o@12LO+WYE$>!nU@->r8LUGwy#$^PDQ3(tIM{E`)(4)Ok7=wNlx zZWX_^4|?RmM?Tuc`+?=tB%TKGS_I|=|5x+d&mS7K$J1$><@X`Om;LP0Kj;6^IDfC- zw)VLl%a{D5$zPk+wqE?5h&5P_c~tduZq;^}+Z5k{Si>)9=oPe0e|I^yX%%mKewxPH zFxzyzT()b&Hf25XHTZa8h4mJGTj%dRo#Vx#wmHoI#r*bjoyIoBQ#>sCg}+NbJS%|Z z$p52p{$9Vb9W6)ORKJtYqr6_o!*Z;*F-~jfpK6<4wpZq6I+x-M8h(;|+F};V_u@Nm zpBCStn-kxGJ4Adh;p-y*7m+{rBkGTD<1JIfced6Ef3@&4qWzlv_BJ+A+mDxSx{cb$ zmErI2l8-y>=d$EuX81X={xigPkRBtxBUOGU@Ef9iujv1l2dO_i8GJ9sKT*{012Mim zA0s`UDCUaqynXHmierZR#+S**lg7QmUoPsuPPF&rd8Ee`dBt|}afKZ%w&xf3QXE&_ zceas_`adB24UH7X9l_IX^66iTW&Jhf{^{at5GRWL^JDRy)yXZS$NqhoSf8_+DULgk z4PyPy72nBwr}&QI4@G>k@VkiZ`-xcpJ3Q1s?X?!mlOi78KylmwIYd3q5nmg5s#rh2 z_>SKDMSstV{Hm*|Kl;~VxmT?3rbQIN_BvkVU$BJYxU<_&{H8^t81G8q&lBx^(@O2( z3434hoySEH-zofy#s1M-?5{)GeCtzRt21J9A928*y^aQe10eS+`FI5XlUU(SVu1UK z_WmUNIpRyqKX`!J#|h#q;a@9O=rPISNy)F zwhK94qLouy$8kTHy5e^ywf!g#Kj&JGzZ2WeZ1-S`JAzMJ=!Av2kvVJ0Z@VCg z_&35IyO{Dj@qm61@n3}h@P(AG-U|BauWI1My;qbE;9N0)df_h?{&L~35&j;c{R>2V zFA={;#GhyzFs?B{ANw zMf`i=pCHE5SNOk({0`y{?lsZhJHo$L)TfKk?<;&==&Qwe1`Gcnp+7?SpNjUr5`LxF z{znV_X`;WLBL0Y2zwbr+CE;r#KO?qxAJKj%afi5<@DC9F;le*!_&L#Ef6?Dy;TJ@H zQXF3;5pQ(U{!9O=@6ouP2q)lcgXH6pcAM~9gg!0$%L@N|kv~p6@^uz>us@0Mydbtm zL9~B~X#aRo&%VOnNA&kvTl>~mFMC0KGh|0`3;kYO0-bR85%G+OA1>ktiw--BTj*h8 zgANn}{!+C6gYd2502m?KJ5{vzXEC1Rgzpvw-CvAXKC>p(PmEgKE>*e*JIUwQXBW}V zgsZWPSBl3O`Mf)n=Sy&#FXJs@Z1VYduxMY#wdFKE+-=C`=?d}qA>)_*LEQBR@lAga zzvd6($NoWljfl(n0dw0WH>qtmKu#5m@>6LrmG!Tw13C;$>D6u}J@B^jOfwQPA_vLo z1nSQW$(aQ+ls7|ilEDnQuQnQ#^9|IO8In^E)R!5Ovk=sm8Iltc)YmmeUvh4O`Z7au znu7W=LvqG~`Z7au@`C!h*62&lV^CjaNKR=`UuH|#E z%M8hx8|upp$w?gQYm3pBoX?@Y%#fVgp}x$JoaLdu%#fV$p}uZ3`jT@$)R!5O(?Hah z8Im(X)R!5OlS5|6ca!SNc|g^g`}VnJW!H|@9Zz-n>>`<;p=*2aX?Fd*<4yOIFrS9JWh~ z%a%3OS1w!J)VHD8Xmm)wDx=BK)9Qw=K66(6>_yXuw$u%_4r&-Pe#p?}E%i;+Yevr< zP+2>;p?+Y?l&0x}c5QOO+S(?Yq)-IjfIIW?!VfBR3OD8O99ARD4 zFktcYWz(y6(`Zxe(uTf^)~u{F{$D+)+v-7TtMxb9oxE!1yfY_{Tvb1>YRJ$Djs2^K zOt;o8T(WS%tl9~U(})k)6mkVaZ<~?L4)i23>|pp zu4~^^J8#8GwI5X0*EKd*t{&KJ^}v4p)n03?z1h^#<(2hKW6zvErltR=Im;H#S-Ea} z!`gwYo7u2<`S5jfYbRCjI?}dw8`L4wywq6#fi&86gX>nWY#e1BHE%}Mx-pX% z46I!{X2{&p)sw~yS-f=k(1nxEYMwrM$ozF<7Z2H`rb}v9u3T!Aw63|SxuteqQ$6nm z1B~%5IMX_C*4(x8N1Zuv=P%`=vcm_EI^YRLRmGX}3&TVFSS)N1SR zx4dwL>SLYJtg3=}l&xJbvTEVTRinl)9l5xvYQXY=O$(O{@3VSLpV4b4j9NLNa?!kj zYiEu-Yu2n$b9QZZ;mW$k`lhDF$|beSR;+AURkw0giyCzQeuJnQi|Qw?m^*gPsLHCL zD`rioT|aQZlnH}JuRD3#s)>t6R@aZ4xo%Z$-JrSEjq`VHd}&ktvf2i77hANV@3NNW zB@0)WZL6^x^%y^R@{(}_`cw^Xm^H3?!h+d#jSbZ+#-2QFWXoXdtjh7TrVZ&oq`H3D znQKN*-DTj-OII{6ZK*W=>2|{W`qlMKy}QY?(u(>94(>gOPE?XT9atLDNT6R#jE^pHn$+=$WGjPF^^4V#|Q#gJ;iK zd-C|EruDUJ&K%oVH-E~ST~-T?FQ{Fy(mX}it~4uFO?!OP+6l8qSFIW~VCvEpjZH(R zuB#n?^6YVIC(dq~I(O8B)gu~*Pad&k>d2}I&CR2GY%>` znW!VmC`#SbmWAsU&RD%@`kKjO8iq`rTRUZ8)p*Mab>^m%HkV~x)zEpXX3U$`XWpRNb#*h(oVud2VQ|&5<>P10oiu#O z+BMe3$%8A$u9-A(Xu~dJUpsK%kje#3&9y80pKR>Szop6&%S2t+%#2MqN`pg))e946ALr$KxaMZfN3umnx+qiy6!}=kk z2G$R1#6_xoV=L>|nyvNc)@HAsIC9~n^;4`(Rf}5s4_H^0fJ* zM@(9=YQmB!qpPb24%=(qs)bGSyY)5AlIHpK!|K=8W1+eMSf=)ZmSGKbylBMe$>)xm zWF0$DMLhOMbxv7~LuIN~dwL(0`FBb8&B7U)W%=d|j?<+*SS+sYX$X_AiYlMG+=>HC(-!A;1@Xr(N z-6!H#i}ALK{ELLYQH5KduMEfq0e}%~3B>byI{>`Gj+l0Se`1c9_A>ltR{Od)3 zPl@=oVthA=e4p^27y6fl|GMyR7y27SfA5I=4~2i1(BCBV4~XsmPoe)p_}>WsKGFV< zBED7h7Z&-yiu_LNX%+)7G<6gHqe6e1Xn%i^|96r9jPMT;`9}&rF7kVb_?@Evmqq?- z!tW*YeT6?j_-_mS-J-vtBL58Gr-lALp?^qh|4~9eUiedmzeBV?OT-@({ry$M>x92h z_|3xqMD+KFXn&Q+|3c(HF7lrgeqQ81BjVqS_|L-MB&K;%{cxo1Jjrv~rKMMbPF}|%L{`;m;BM{V3wU2!E&WJ1wK*9q%mbBK$34{m&IIt^7^&Unl%V;qNWl zUn1fi7Secde%W8-e<-$pi_mWs<6R@-2Z{F17x9lo`-6qwNsRBGBAylgyW*v=+r{|4 z5c!9R@of;}+e7q!iHLU*@ovKJBKrGE_(zKVj~4#1!oNcFf45k_ULwDb@ZCaxo$&7$ z?L8v=O3~f`;eR96?+Ky5QS|qWh;J3~I&u8mEZYBCoL|2YzF)MrUHC7E{$COPV6lFu z3jbcw-Wei3Lilfr_D73&L9E}8!v9(L4~qUH!hb^ePYeHf;U|Rus_@?u{(EA5b_oAd z;eRRo?}R^I)MIaPJnbv|{e^#k@DCFHA;LdQ_(ur;NZ}tP{G)~6L-@xEzo+nf3BR}S z`v||U@GFJiU-$!r|Cu;G28sA!;SUx5slp#7{4<1a75)g}j}rc9;g1#mc;QbJ{$$}# z75-VmpCSBN!k;7jvxWax;h!t~TH)6Tzh3wa!e1!-#ll}A{AS@V7yb(2uM++m;ja_^ zdBVRy_^ra8 zoA7TJ{++_#F8sTNe~<9*6aM|ee^B@j3I7q{KPvpkh5v-`pA`O6!hc5i&kFx};lCjK zmxTYa@Lv)BtHOU>_-_jTZQ;Ko{P%?azVJU3{tn@PEc|~8|5M?ACj2ji|E2K17XCNF z|4#Vd3;##q|0Mihg#WAXcM87)-;d+@qLc9V5PlcocN6~J!rxc;`wRa7;U6UYLxg{r z@Q)Dwk-|Sp_(u!BhwzUTeox`|5`J&t_YrxI8X_+H^}75+Bi-!A-s@b4D>y~4j=_+jBcBK*gM z|Ag>0;Xfn%=Y;=)@Dsv+MffM&Lm%S9dyDhxeayxmeEr^X|L{<`KR}$o1_^(#@P`Wj zRN)U3{u#o5O^p9d;irWEp71{q{tn@1g#W4VKNtR&!p{r;JK_Hz{GWth68=u%cNFhs z-b46Zg}=A(_iOX5_OH|h#`sd(&42(P3P=JnfFi*4HOqZ~Fdz;{1M&bzo>d+|5TKc$ zzJB)&Ko(E}xW6&vD#s6q01^NlPyjf;WtA5Y0>l6*Kn`I4&QPhZDc=kT0HS~-AOk1@ zTm_c<0AWBJkOt%dj_+CJ0R#b>37u7a09il@;Qqmos~kTd0!RRKKmp+VkyTzm2oM9L z06BoYXsFZ|r)~xW08u~^kO33{uAf-$1B3x_KpKz-IDTf82M`2kCaAADc>|CIlmPBu z47tkj10sL~KnD~6&JwG%#deWY?TAOMI0l7I}L2yp$zavvZJhy&7q zJixJ&RUSYPpqbEB)d!FTlmKq~i)zd&#}9}A5&#`g05~_W$_oeqVt^DN2e5B6RO)9n zHUk2HC?E;Q0Ez(DMJ)FL!hkp+4afr=4pw;pL4an0`n|_D09il@;J(<9s~kTd0!RRK zKmp*qgjHTZ2oM9L06BpDQbV=3st+Ilhys#;44?>bIa%%lgaL6t8juG#E@PDk5Cmu@ z?4#-f$O1|L_vMCM<@f;+Kmwox3IOL7tnvavfEXYJ$N}swL$$A}4y6n43Glk z0QRd5)&8nJfB+y0NCGl|BEWSG%YA?_APz_a@&L!RtnvVY0L=vTrQmM>vVao6z1fhf z96uleNC0#|0pPrjRbD^{5CfzDIe`6oL!~~pw;2!sL;*=a22cdJZeY0&5C+5nX+R#} z@UY4Q2m&+{4pj94WC10Bdy64gIetI{kO1g_0>F7AtGs{^AO=VQasc~HhUy?yA3y*Q z1tb9(KoQ{bvfKv<1LA-*AP;cd%qkBc2+&M8Sk(uR1(X2pTMW6%@dF}&1V9HA0M4zf z@&ZDD7$6160qj0Qb%?4DAOMI0l7I}L2yorXavvZJhy&7qJixJyRUSYPpqX%}st+Iw zC;{BJ8FH252Sfk~fDR}CoPJh$0U3XlWX?=n>C zSG_j_0)QwW3CIA70N33t_W{CyI3Nwk0~|qCc>qCxX2PFTeE?ZN3E;lRkgFU&AOc7L zbU*>%yq8s8KnM^6qyRa9{XRo=q^b`f0EhyTfDE7raD`az1B3x_KpKz-IPPba2M`2k zCa7PydjpUKlmPAr47tkj10sL~KnD~6&IeiL1%v=GKnjop*u#eEC{-Uo01yQv0U1CM z;ChJVK0p`{2c!Xcfa76Sc>qCxX2M@oeE?ZN3E+OjkgFU&AOc7LbU*>%jIhcJ2mxY% z6d(t%KWeCsR`me{08u~^kO33{uE$vJ1B3x_KpKz-I38z}2M`2kCRC{U0J4A*z#TQ@ zD#s6q01^NlPyjfeV3ijT0>l6*Kn`I4yP@i#>H`P>qJShI11JJqPqN$x2m|7PG$0Rf zXsq%8f&k5gV^nb zhys#;44?>b#aQkGgaL6t8juG#o@JE>5Cmu@9H;67$O1|L_j86^<@f;+Kmwox3IONx ztnvavfEXYJ$N}teL)BB&2M_>60ZBjxPz1PMV7U(v2E+krKpxy6n43Glk0QQ#+RWDT^KmZU0Bmo&f5#ag<%YA?_ zAPz_a@&LyxtnvVY0L_FGRDA$hKndVZ8giB62Sfk~fDR}CoUgLV3kU&XfD|AHu)k)g zdaL>X0)QwW3CIA70N3j*_W{CyI3Nwk0~~L#$^!@jG!sr#^#No7C4l=)L#}fCfCwM~ z&;bR2^DS0+0U3XlWX(}t?Ast+Ilhys#;44?>b zz0YzVAPk5D(ttd`@d2wmfFM9Kp`WS`APXn~+#ecpmE#9Q011E&C;*%~tGs{^AO=VQ zasc}dLshBj0|)@3fFvLTC<0s`vD^m;1LA-*AP;bS%qkBc2+&NZQuP630VRMtW5`vG z9}oc~06L%maQ>53UO)&C1Ec^sfc+Cg)nC;I5CB90Nk9fr1h_tBxepKq!~tnQ9^lBb z$^!@jG!v>-eE?ZN3E=+BkgFU&AOc7LbU*>%{G3%@KnM^6qyRa9{R=}iK-C8j07L;v zKn73*xNaFgaL6t8juG#zGamM5Cmu@oUG~t$O1|L z_jiU|<@f;+Kmwox3IJz;RbD^{5CfzDIe`6pLp4~{2M_>60ZBjxPz1PsV7U(v2E+kr zKpx=ukyRc*5TKbbMAZk71(X2pq9Io~en13}0O)`M!1)uaynqlO21o&N0Q=8|YN)CY zAOMI0l7I}L2yp$vavvZJhy&7qJit+6l?M<6XeOMZ>I29EN&xq-hFs^lwBsj5DJ03ZrT0y2Oiz-51lqCxX2R*JK7cHs1aMz!$W@LX5CJ3rI-me>I$7lfga9!>3XlWX zFEdnUsQLf`fG8jd$N-7}*X1nt0m6VdAPvX^99OW)0|){%6KYg_09il@;C2~umE#9Q z011E&C;*&SvdRkx0b+m@AP2BtWvHyGK7arq3P=JnfFi)PiRC^(7!U`f0eOJK%_0-ys50OvKV@&ZDD7$6160qoZrsu8L_fB+y0NCGl| zBEYqoeE4~PH~03A>OIB#H;7Z3u( z04YEYVD}iRQK~+G03ZrT0y2Oiz_o?tK0p`{2c!Xcfa6A1c>qCxX2O}OK7cHs1aRME z$W@LX5CJ3rI-me>dRgTKga9!>3XlWXZ#Gn;Reb;fKopP!WB^5g>lT*#0AWBJkOt%d zj;*Zn0D=I`gfXf*+U05L!ckOSDa8LF|WK7arq z3P=JnfFi(k8_RuwFdz;{1M&cepH&_}5TKbbPSppH1(X2p+YPzO@dF}&1V9HA0M0vD zdVu9VKo}4Qqyc$=<3Uz=06~Ce!W2~>Ko(E}xWk5A<@f;+Kmwox z3IOLrtnvavfEXYJ$N}sR8>*?QK7arq3P=JnfFi*42+MtdFdz;{1M&bzgjF6u5TKbb zP1OgG1(X2pM-92k@dF}&1V9HA0M5r)j03ZrT0y2Oi!1WZ%eSk0^4oCy?0LRm;@&JMW&4ih%K7cHs1aLoN$W@LX z5CJ3rI-me>##rSAga9!>3XlWXpEXpoRDA#eKopP!WB^5g>p7PD0AWBJkOt%dj^|nB z0R#b>3A0sw09il@;Eo$|mE#9Q011E&C;*%`TzoeC?E;Q z0Ez(DODy*R!hkp+4afr=308RkL4an$TvZ=H7El7XUpC|_#}9}A5&#`g0671_DlZ@e zhyhZ79KimHp*maD2M_>60ZBjxPz1P=EcXGzfH)ux$O9a&vdRMp0yGoOQS||20VRO@ zHAAj){D24`0nh;jfb(@$c>y6n43Glk0QNTw)n8S800BT0kOX7^MS$x~miqu zzRxNzAOwg3Qh*%5{(+&YRrLV`08u~^kO33{t`Ax61B3x_KpKz-ICNHd06~Ce!aP+U zKo(E}xOW(GmE#9Q011E&C;*%vvC0bw0b+m@AP2C2Y^dr~eEOICHG>0z!ZoAO*+)>|YwH22~$G01yQv0U1CM;QET?K0p`{2c!Xcfa7acc>qCx zW z`i|v3Ko}4Qqyc$=qrfT;APCS*SfuI$$O1|L_xFZe<@f;+Kmwox3IOL1tnvavfEXYJ z$N}s>8mh&rK7arq3P=JnfFi(EWVsIz2E+krKpx=uiB%pz5TKdRr0N660!je)&xTy( z_yG|>0-ys50Ov2P@&ZDD7$6160qiA1wM5ki5CB90Nk9fr1h{@>xepKq!~tnQ9^m+m zRUSYPpqa2#)d!FTlmPCXhFs z2mxY%6d(t%Ut*}1tNH)}fG8jd$N-7}*QG4?0m6VdAPvX^98Okw06~CeLW`;oAPXn~ z+?N@0mE#9Q011E&C;*(7v&sty0b+m@AP2BtVW?K9`TzoeC?E;Q0Ez&Yi{(B*7!U`f z0eOJqN>+IQL4an$N>v{~7El7XuQKE+#}9}A5&#`g05~_X$_oeqVt^DN2e7*h)hbmV zKmZU0Bmo&f5#YL-O zI5)G(3kU&XfD|AHuwQ4W)~Nab0)QwW3CIA70N3>__W{CyI3Nwk0~|N7$^!@jG!xdU z`T(+k62R>-l6*Kn`Hv zYN*ar^#KF`Q9u%q0Tcl)AIp7!Fdz;{1M&dJt*r6@f&k5g^HqHSSwIQk-e$;Ejvo*K zBmg>~0C3*MDlZ@ehyhZ79Kh~3RO+|JHv z2m&+{E>!gaWC10B`%Xiya{Pb@AOX+;1%NZaDlZ@ehyhZ79KgQaP_?T100Mw0APL9- ziU8MLEcXGzfH)ux$O9aAv&sVq0yGossy=`$pagIS4Y|tk10sL~KnD~6&U;wp1%v=G zKnjop*zYw|8&rJ&0YDUx1Y`h3fa^Y%`v74;9FPX&0ge!>Jb)lTGhw5u4!3 zfD*v18FH252Sfk~fDR}CoKLaJ3kU&XfD|AHus?06E>raZ1OQP$5|9BD0j_6Q?gNAY zaX=c72RLG^@&JMW&4kNUeE?ZN3E+O#kgFU&AOc7LbU*>%e2!IKKnM^6qyRa9{dq%m zg{luA0EhyTfDE7raK%~f1B3x_KpKz-I9_0t2M`2kCb(3609il@;C|7Ns~kTd0!RRK zKmp)0-ys50Oy;m@&ZDD7$616 z0qk!Xs;gCf00BT0kOX7^MS$yVmiquOINxQJ7Z3u(04YEYV1Lh0U90K?2mqphBp?GQ0$gd9`v74;9FPX&0gm@s z%{E$^%KnM^6qyRa9T{l$Msrmo{fG8jd z$N-7}*AABZ0AWBJkOt%dj*nR70R#b>3D>Lo0J4A*!2PiyS2=z_1dssefC9joVU-sU z0>l6*Kn`I4r=hw*)dvs&L;*=a22cdJK4G~J5C+5nX+R#}_>@&1KoFpr;8FDfWC10B zJ8Q^Qjvo*KBmg>~0C0ZBDlZ@ehyhZ79Kim$q1vMA0|)@3fFvLTC<0txu-pd-1LA-* zAP;clSmgl(0h$Rns`>!3fD*v{r6E^2en13}0O)`M!1)!cynqlO21o&N0Q=X5>Lyhm zKmZU0Bmo&f5#Y+R+y@8);(#@0HS~-AOk1@T;H?Y2M7b=fHWWvaQwh34b{mgP7 zAPk5D(ttd`@e8XwfFM9K!Kdm2$O1|Lcgc{e96uleNC0#|0pR?VRbD^{5CfzDIe`5) zLv^dF4*+U05L!ckOSB+GE}#z`TzoeC?E;Q0Ez&YgXKOz7!U`f0eOJqVpe$o zL4an0U)2YY1(X2pOANWn@dF}&1V9HA0M1KUULEhKmZU0Bmo&f z5#YLvVngQ2=x)dvs& zL;*=a22cdJJS_JC!hkp+4afr=TUg}*1Ob`}K~*0>7El7XZ#3j8#}9}A5&#`g061@A zl@|~K!~iKk4q*2hs(Vy@00BT0kOX7^MS$yOmiqu!3 zfD*vH)sU+kKOh1~0CYeB;PkP|3kU&XfD|AHu-|H^?o;&v1OQP$5|9BD0j_N<_W{Cy zI3Nwk101)p$^!@jG!sIqK7cHs1aSKexytbaB7g)y2NVF#+garWga9!>3XlWX?=V#N ztNH)}fG8jd$N-7}*PSf)0m6VdAPvX^9068&06~Ce!UL*4fGnT{aBnx{D#s6q01^Nl zPyjgZVwD#V0>l6*Kn`HP+fY5I>H`P>qJShI11JJqL6-XfVL%*^2IK*bdsyWG1Ob`} zVO1Z%|HlJ;$59N=|GjU2ZEyG9z3uJZ<97Gn+uqy$y7%7ucJFm(dsh$yLF^z1f*=Tj zAP9mWh#dq$5ClOG1owRMIPceg&p*De&&hc&!YKqVw*2-c5lW#GCSe!6m)xsJ$c082 zgjH~It6p*2M@WTA=!IE01plS?JQfO}6-Hqb+?U;}P{@S(!Ygn42#atE!OJbby-9>p z=!8kw1+TbQk&p|GFbJ#Qyuzwi-S!bup%Qvw77oFGt01dE;Pa*tb+4ytKN9qM@WTA=!IE01phtvJQfO} z6-Hqb-2PsLLMGG~-gMhXScFpu-fQ{oO(K*+CrrXFc<;Mck&p|GFbJ#Qyx*!f-}Vtw zp%Qvw77oGxz&($JLTH6i*aY{3_bL=Jp}x@E_7N806oL;~etVM$rO*kJunXRY?^Pt^ zLL&^qDma5xZ@KLwq(UY1!Ymwu|B-th3x&`Mqp%6?NAFcAWI}!6t+#!IML31vW0v3E zBtj{4!X)g1H{PpA$c082gjH}pZq?gv`v|E}3B522hv0wWp2tEVw8AKCg8RvP6$+V9 zUubXp2#atE!DRXEO(K*+CrrXFc%Qmgk&p|GFbJ#QeA=qF-}Vtwp%Qvw77oGx%sr2V zLTH6i*aUaJSD}yz^@Vrb_7N806oSuMetVM$rO*kJunXSj?o}k@LL&^qDmb6F>YcZJ zgjA@6UYLbL@RxfY3x&`Mqp%6?7w%OkWI}zRyX_+^!YKq_wEXra5lW#GCSe!6FWsw1 z$c082gjH}>tKN0nM@WTA=!IE01pmwTJQfO}6-Hqb+^^iLP{@S(!n<$#2#atE!B;K6 zy-9>p=!8kw1#i1ok&p|GFbJ#Qe9fx&-1ZStp%Qvw77oGx`aO?@LTH6i*aY_*_bL=J zp}x@H_7N806oTFI+nYovg-)1+UGTnnuOcBA8etGt!TFX|@4f9Kq(UY1!Ymwu|LuDo z3x&`Mqp%6?aj!xl6Y2}^yX_+^!YKsbvHbQX5lW#GCSe!6@7}9O$c082gjI09XVv>} z`v|E}3B522hv1+0JQfO}6-Hqb-0$D3P{@S(!Ut~q2#atE!4E9Iy-9>p=!8kw1@DLV zDiU&`5e8uu9OvD)-}>NfA0ZVgp%-T15c~(+^H?Z^Rv3j%a36TDLLn3C3m>}eBP_xx z1P`+O_9hWZp%W%y7d-b~MM5q#!XT`I^I)q!eA`Dzg-Ym!SvUm$A@@8M3ZWH7VH4bk z-m6f^g!;m8+ecW0QwTiEZ*LNz6gpuNcENkty^4ffXoNvn1?S;bedM-}kP4O13$t(t z{v+;rEEGa3jKU_k{=Eu?OsFq>^tO+%2&WJ{((>DzL@0$$n1o&M9(AuGAr~595LUr? zv{fIw?IWZ@CG^599D*O*^H?Z^Rv3j%a36E8LLn3C3*&7cVG&Ltc&z2OH;GURoiGWz z;63hMMM5q#!XT`I^LVR1e%nV#g-Ym!SvUm$3HLk}3ZWH7VH4aZ-m6f^g!;lKZucXL?IWZ@CG^59 z9D@Ihdmamg&ng-Ym! zSvUm$<@Y=m3ZWH7VH4cqUWGy?)EB;Z+ecW0QwUyR`Rz?2ltL#=!Y+8PyjPKs3ym-c ztKhuKsxRI45mKQNdSMn0!7uN5EEGa3jKU_kufA8IkO}pL^|p_&2&WLd#`4>nL@0$$ zn1o&MUVE=1Ar~595LUsdtorh8A0ZVgp%-T15d7EO^H?Z^Rv3j%a9@9~LLn3C3tzeI zBP_xx1aGkX_9hWZp%W%y7rgpjMM5q#!XT`I^G2(_dfP`xg-Ym!SvUm$P4_$&3ZWH7 zVH4ap->Xo_g!;mE+ecW0QwSQ%Z*LNz6gpuNcENkgy^4ffXoNvn1?R0+eeJf7kP4O1 z3$t(t{@d<(EEGa3jKU_k?Y#{kD&=2&WLd-SXR;L@0$$n1o&M-f^!YAr~59 z5LUr?r&Zs$?IWZ@CG^599D?87^H?Z^Rv3j%aNl*WLLn3C3;S&!VG&Ltc(>)ZH;GUR zoiGWz;JxQwMM5q#!XT`I(_8h;+de`nR6;Mz!XfzYz2~t|2(2&*o8Z3hUWGy?)EB;W z+ecW0QwZK~`Rz?2ltL#=!Y+6pxL1*o3ym-ctKfXls&C)+5mKQNdSMn0!T-=bkA*^L zg;Cf9_rv!p6f&W{aNPD07U2|v!SdUiL@0$$n1o&MK60-jAr~595LUtYs8!#&?IWZ@ zCG^599D@I`dmamg&-K$W@g!;mH+ecW0QwTn7`Rz?2 zltL#=!Y+89xmS^p3ym-ctKiI5egC$PkP4O13$t(t{%7xbEEGa3jKU_kpSxF~kO}pL zAKdm47U2|v&s%l4f?IWZ@CG^599D@JFdmamg z&Lh6uuyQUwF)F`R&bfgjWmi5d}l2?fX7}7IdQEYj(xn zC8$Iln$V8Cud9tvjv6$e6*=Fq_Q%PU5_M=oJMtc)HbOaS z(12FtJk;8sYWtxSRj5ZZI*{+_N{kBBq7iM#eVE!1WvIUN(`-Mqpc4fTw=4E8K_%+Y zgm&aTLT!X{)Sv;a$nmZH>9!wAQH6RmqXYSm)Rh<&s6`{%kozdLA<9sF>1Wt}XhA0m z9&K0bU4lx~p$YBC3)Ds^M-3X#ik!z-`!j7nl%fjtXhsL}AFC@dDo~3?v?2F#YD1Kv z`qIy`{m_C=6g=Lp*t-Oks6!Llk@p0(5z0}62DBpQiPrvX+YhCvLOq(%f&3@wN{kBB zq7iM#4b_GyL-nPfWBZ{6ohW#+U9oowDp7|fv?K2+Y9o}R1`TLM&Qq=ZxwaolQH6Rm zqXYSouEeN7EgI2=+^4AxQHJVEKhO3<3p!Eobh~2j5>%oNO=w5nGt@>XM-3X#ik#Tm zpKtr26ji84Gdhs}OkIglfm$@84Y|)!8=?%=mwtimhZc0A;MsP?-X*9+9h%UNyhLq; za@3#!t;l(fwZG8zLn*3Ik7jfr|GBynqXM;PL>qFSr#3_xsxSQ_+Yc@1L_um->|KIN z)S(IO$a}up2<50j16q;u0&9PiDLB}N5m(TFzWW@%oNO=w5n%hg6GM-3X#ik!mQUuOHE6ji84Gdhs}3SEg& zfm$@84Y{vW8=?%=m;M{u4=w0K!K>_wy-QGuIy9jjd8OJ2<)}deT9NZ=Yk#@zhf-9b z9?j@L{%dq4Mg?loh&JTDR&9tfRA2fPwjWy1iGs?m*t-Oks6!Llk@q^a5z0}62DBpQ z_16AM+YhCvLOq(%f&4eQH6RmqXYSkuEeN7EgI2=+_$I=QHJVEzsB}M3p!EoR=Z;F z5>%oNO=w5n+tfxVM-3X#ik#NkUu*lJ6ji84Gdhs}c3p{4fm$@84Y}`78=?%=mwuh? zhZc0A;GK5G-X*9+9h%UNyiRR|a@3#!t;l(owZGo>Ln*3Ik7jfr|J}M0qXM;PL>qG7 zqc%htsxSQp+Yc@1L_u#?>|KIN)S(IO$a}Ba2<50j16q;uK5KuY?T1oSp&rfXK>qu6 zB}N5m(TFzWen4%AGE`ssO|~Ce(20T%+7)}3pb~XxLOb$4q&7l1YS4gI$o+`g5M`*o^jmB{w4f6OAGIs?EPP+G@}FgAJ>%_6{tlc+K~GRwIRw-ed)K^erQ1_3O;F9>|KIN)S(IO z$eYwgC`Sz%(2AT-S^MAGekes1>d}l2? zioHuvi8?f)9eJNs8=)LEXh17+K4DYqD%7JH9mxN@uEeN7EgI2=+(m7OGE`ss zowgrZ(20UC*cE%1pb~XxLOb%ls5U}5YS4gIPn0X)S?k> z$o;a~5M`*o^t)|8w4f6OU$HCpEPP+G@}Fg zU(=Ns6{tlc+K~HowIRw-ed+hwerQ1_3cg`i>|KIN)S(IO$lKLMC`Sz%(2AUITKoHK zKa`>h^=L*1^1r1kF)C1tMzkUK+iF9Uq59H)XZxWAohUf$ioHuvi8?f)9eLkT8=)LE zXh17+zH9A&Z~LJXRj5ZZI*|W8U5QbFS~Q{!xu@C?WvIUNKiGa~K_?2nZ&&PHf=bk( z3GK-Hf!YY=s6hi-k@G`qf4}XAQdFTH&FDbB)8DVes6Z_m(T3ays0~qu>PvsX_CpIg zQSd;!V($`Eq7F@HN8W?fMkq%O8qkUy*V_Nl_CqPEP>*JGApgO-5~BjOXha)wAEGuy z8LBV+PqrUg(20VF+7)}3pb~XxLOb$2wGqlug9fxB=V8|VLE8_ds6suO(SiJj>q?9Y z)S?k>$bE#`5M`*o^oMLew4f6OzFo0*2`W*CCbT2(k!mB9qXrFVMb4wF{ZZQwrKmzZ zn$dy$N9#(A3e=(zZO9GOhA2bzr9W)@p#_~Nc#K`KcL^#{hbFWm@3Cqll%oa>XhqKB ztoL$lqZu8@f3~i~s6Z_m(T3ba zZHO{dU;5LwA6n3fg6G&3dzYXRb!b96@}8?ULOE*CfL7!@&)Pp@`=Jz7s7Et8ke}*G zj0)7E5pBqQzS{vpaHGO$*lczwjWAS zg?coj1Nkq~l^7MMMI+jf`(m{r%20jj&)a@zK_?1cVpr^4f=bk(3GK+s)kY{s4I0pj zoR?br7i>S2q6+nBMhEg=rYkWjP>V*iA@}8KLzJQV(qFXw(1K1B6n4elC8$Iln$V8C zSE!9pjv6$e6*;f8_Al9fC`A?O(Ton{ze-nPRG=1(XhUwPHbfb!Fa2fP4=w0K!K>|x zy-QGuIy9jjd9P6$p&T`6Kr3=yYwcgL{ZNW3)T0?4$ggxIMg?loh&JTDPHl)XRA2h5 zwjWy1iGtVL6?>PU5_M=oJM!M3HbOaS(12Ft)Ykqr+YhCvLOq(%f&4e>N{kBBq7iM# zeUsV{WvIUN*KI$vpc4gewk!57K_%+Ygm&aLY9o}R1`TLM&ReYg8@3-xQH6RmqXYSG z)s+|(s6`{%koz{ZA<9sF>2KP8XhA0mTDxNJ5>%oNO=w5n+to%WM-3X#ikx>?`?qXA zl%fjtXhsL}->EAxDo~3?v>~@s8=?%=m;ScxhZc0A;9Yjb-X*9+9h%UNymzaOP>vcj zpcOgqvG(uSekes1>d}l2qG7t2RU#sxSRr+Yc@1M8W&)ioHuvi8?f) z9eM9p8=)LEXh17+K49(Nv;9ztD%7JH9mxNnuEeN7EgI2=+z+V@QHJVEf8X{)3p!Eo zVY_1Q5>%oNO=w5npf*A|YS4gI%oNO=w5nsy0G7 zYS4gIqEerQ1_ z3chJq>|KIN)S(IO$orPs2<50j16q;uZEOFv?T1oSp&rfXK>ndCF)C1tMzkUKJ8DCe zq59IlvHj43P859CuGqT-m8e4#+L8A?wGqlug9fxB=d||U+I}cS73$H94&;AdS7KD4 z7L8~_?hn+4C`0w7e`oul1)V7PpvcjpcOd}u=d~Eekes1 z>d}l23_BT(1K1BJj$-v zy9AY}LlfGO_h_{d%29&`v?3?4_J6beP>L$lqZu8@e~hlgs6Z_m(T3c|str+w>P!E- z?S~e0qTq3M#oi^TL>-#Yj=aaKjZlsnG@unZPq6m?u>DYqD%7JH9ms#8uEeN7EgI2= z+$X6GQHJVE|EKMT7IdN@v@7;5K_%+Ygm&aTS#5-J)Sv;a$a#vj|Jn9KDXLJ9W^^F` zsk#!Q0<~yF8*(GHA<9sF>A%>1XhA0mo@Q6*JGApbeK5~BjOXha)wpQ|=R8LBV+zqTJ*(20WQ*%f=2pb~Xx zLOb$OwGqlug9fxB=lRzDf3_b=QH6RmqXYRb(3Kb!s6`{%ko!WlA<9sF$+7*=f=(1< zcE#Q$s6-u_(2l$psf|#M8Z@94IWM;M0k$7XQH6RmqXYRb(Ulk#s6`{%kejOwQHJVE z548Qzf=(2?)UMdO1eK^m6WWpYGPM!PQG*7wBIo7SKFIb%DXLJ9W^^FG(3Kb!s6`{% zkoyX?A<9sF$+i8^f=(2?(yrLM1eK^m6WWpYDzy>HQG*7wBB!+W!L}btQH6RmqXYS` z)|D6)s6`{%koy|7A<9sF=^?fsTF{At*V+|(m!J}LXhJ*kDzy>HQG*7wBIkA1KGgO@ zDXLJ9W^^F`^|}(H0<~yF8*<;EHbfb!FL|~fTF{At+OF8U1eK^m6WWpYMzs;jQG*7w zBIixkKFsz*DXLJ9W^^F`&AJk!0<~yF8*&@9A<9sF>EX5?TF{Atx7ZbXm!J}LXhJ*k z-l{f2Icm^=R^+_R+DF)aC`A?O(Ton{x4IIe0<~yF8*<;SHbfb!FZs3~TF{Atci0ts zm!J}LXhJ*k-l;Z1Icm^=R^)WnKGOC>DXLJ9W^^F`UAhvZ0<~yF8*<;RHbfb!FFnfk zLkl`l@E*Hj?-Ep^4ozrBUavMnIcm^=R^+_b+DF@dC`A?O(Ton{zfV_URG=1(XhZJ% z)rKfT^`*e}Lkl`l@BzDG?-Ep^4ozrB-Uro2C`Sz%(2AT7S^F5<52dI=J(|&h{159& zj0)7E5pBpF)P^WS^`*z!erQ1_3O-_2>|KIN)S(IO$or_;2<50j16q;uF>4=Z`=Jz7 zs7Et8kU#25j0)7E5pBr*xY`h9sJ`@g+Yc@1M8PNQioHuvi8?f)9eJNr8=)LEXh17+ zCTpKy`=Jz7s7Et8kpC%NiBW-CG@=c;pH>^94AqyOX#1fBohbN>U9oowDp7|fv?Fg; z8=)LEXh17+K5OlhY(JEu3iW742l79sD={iii$=5|_w#B)l%e`kX#1fBohVrBioHuv zi8?f)9eH0+8=)LEXh17+zG&@}Z9kNv3iW742lBt9D={iii$=5|cU2pr4AqyOV*8;5 zohbOSU9oowDp7|fv?K2;Y9o}R1`TLM&R4B{s_lnTRG}Wt=s^CaD={iii$=5|_iJiH zl%e`kWc#57ohbOaU9oowDp7|fv?K2uY9o}R1`TLM&Tj3~Y(JEu3iW742lBtED={ii zi$=5|_giX1l%e|4(``Srpc4h(wk!57K_%+Ygm&Z|Y9o}R1`TLM&UdVRhV6$^RG}Wt z=s^B=btOgxYSD-`cR9||Q?S~e0qTm5`#oi^TL>-#Yj=Tq| zjZlsnG@unZ53=^zwjWASg?coj1NpA5#Hc_m8qtQ_2dfQHhU!a+?S~e0qTnHR#oi^T zL>-#Yj=YDejZlsnG@unZp0&@h{ZNW3)T0?4$bXow#Hc_m8qtQ_hpP=yhU!btwf)e7 zP82-CuGqT-m8e4#+L7n0jZlsnG@unZkF@rAwjWASg?coj1No2Al^7MMMI+jf`)IWx z%20hNwf)e7P80-o#oi^TL>-#Yj=aaHjZlsnG@unZkG1yswjWASg?coj1No2Bl^7MM zMI+jf`*^h>%20jj1-2hr(20U4*cE%1pb~XxLOb%Fs5U}5YS4gIa0tWwsw$(20Vl*cE%1pb~XxLOb%Fsy0G7YS4gIa0tz1a3c3p!Eo47+0Q5>%oNO=w46tTsY9 zYS4gIa0tz0CGQ3p!Eo ze7j=r5>%oNO=w5n3)Ds^M-3X#ikuf(`*Pb4rKmzZn$dy$Ojlx5pcaj2L+*>zhA2bz zrNZ_@3p!EoV!LAR5>%oNO=w5nOVmavM-3X#ik#fqSJ-|iMHTANj1J_#R99kDpcaj2 zL+;DehA2bzrB~X1XhA0mUT#%oNO=w5ntJOv*M-3X#ik#P2`)b<{ zrKmzZn$dy$*Xl})3e=(zZOEop%hi9M>9H*U+YSY3e=(zZODD2+7M-^zEs(MXhA0m-egzoU4lx~p$YBC zd$ZaI<)}deT9MOO`#ReXrKmzZn$dy$x9CcY3e=(zZODDA+7M-^zVv$A4=w0K!Q1SL zy-QGuIy9jjd9B(A<)}deT9Na1Yu{k|p%hi9M>9H*{|;S=QGr@Cq7Aw4R2!lU)t749 z4=w0KL1$O&U4lx~p$YBCdzab><)}deT9NZ^Yu{-5p%hi9M>9H*{~le5QGr@Cq7Avd z+7M-^zVs&B4=w0K!F%nBy-QGuIy9jjdGAvjp&T`6Kr3?IZ|$3HKa`>h^=L*1@;{&} zF)C1tMzkUKgK9&Rq54u|`=JG$DEN?Fv3Ch7QHLh9Bk#j%Bb1{C4QNHqVC`FMKa`>h z^=L*1@;{<0F)C1tMzkUKqiRExq59HWZ9lZ269pf$EA}oyCF;jCmB}N5m(TFzWeo}3SGE`q`Z9lZ269to9v3Ch7QHLh9Bkxmc zBb1{C4QNHqr>%Xv?T1oSp&rfXK>lZRB}N5m(TFzW&T2!Hq59H0Y(KQ169u2OEA}oy zCF;{vpaHGO`MkC7wEa+uD%7JH9mrpFB}N5m(TFzWenD-BGE`scY(KQ1 z69r$iEA}oyCF;{vpaHGOS*?AS?T1oSp&rfXK>n9?B}N5m(TFzWenoAF zGE`rBx9x`(bfVy^cE#Q$s6-u_(2l%KZG>{vpaHGO`I@!wvHehrD%7JH9mxN>uEeN7 zEgI2=+;6B2QHJVEz3qn{vpaHGO`Ifcswf#_vD%7JH z9mxN-uEeN7EgI2=+(T`MGE`rBpY4YhbfVxpcE#Q$s6-u_(2l(Cs*O;N8Z@94Ip4GP z{k9)UQH6RmqXYS;uEeN7EgI2=-0!OmQHJVEAF%zT41eK^m6WWpYL$wjg zQG*7wBFB0E?RP(D`=Jz7s7Et8kpBQ(iBW-CG@=c;4^$hX4AqxDWc#57ohW#aU9oow zDp7|fv?I?|8=)LEXh17+9&GK0Z9kNv3iW742l5}HD={iii$=5|_n~S-l%e|4VEds3 zohb0^ioHuvi8?f)9eEE^8=)LEXh17+9&YVNY(JEu3iW742l5}GD={iii$=5|*H;^& z4AqxDYWtxDohW#uU9oowDp7|fv?K3PY9o}R1`TLM&ZDjUnC*vBRG}Wt=sA)Sv;a$a%80 zpS1l@iYnBj86C)fimt?{KrI^4hTNyB4N->bOOx$~7IdN@vMcs3K_%+Ygm&aTO>Km7 z)Sv;a$a%W8pR)Z>iYnBj86C)fhOWe@KrI^4hTK?fh%!`P`n2tb7IdQEnRdnAC8$Il zn$V8CXQ_=)jv6$e6*PP+G@}FgiLS(`KrI^4hTP|<4N->bOSA2V7IdQE zxpu|gC8$Iln$V8C=c$cQjv6$e6*;N3pSAr^iYnBj86C)fzOKZmKrI^4hTIpZ4N->b zOP{m-(1K1BywI-Ly9AY}LlfGOm#K|Vjv6$e6*(`m_VczMN>PP+G@}FgFV>Y96{tlc z+K~GawIRw-eQB}%(1K1BPP+G@}Fg zFV~eA6{tlc+K^kQ4N->bOJB78(1K1Byuz;7y9AY}LlfGO_e!-9%29&`v?AwK)_%$M zLn*3Ik7jfrztoi&6{tlc+K~HdwIRw-eQCA*(1K1ByvDBBy9AY}LlfGO_gb|P%29&` zv?8an_RF>(N>PP+G@}FguhW$n6{tlc+K~HtwIRw-ed#NqG7tTsd$sxNJ}A6n3fg2t}c zy9AY}LlfGO_ZGDg%29&`v?AxN)_%?QLn*3Ik7jfr|82SwqXM;PL>qEjwIRw-ed+7A zA6n3fg16fhdzYXRb!b96^4_5~LOE*CfL7$Z)7o#?ekes1>d}l2qG7 zr8YzvsxR%fA6n3ff_K{$dzYXRb!b96^4_C1LOE*CfL7%6)_&9WLn*3Ik7jfr|Gl~r zqXM;PL>qG7r#3_xsxN)Z_CpIgQSg4dV($`Eq7F@HN8Sh2Mkq%O8qkWI4_f?L-nQa+J0z3Ckj4pSL|JaO4OkV?a2Ft z+6d*SK?7Qm^GR#JXZxWPRj5ZZI*>oDJ;p&faP+6d*SK?7Qm^95^vX#1fQRj5ZZI*|WGU5QbFS~Q{!xnEKn zq71#!^kaYI$NcCAg)a!-7ap_T-#kZnweT+CQ^Gfehkf~8JxzG2@D|}C!j}c-EB3Ya zL61i%s!)$+bRhq$x)P%TwP-{eayPXh%20jjM{eKu0kohK1z)o(_AWss>d=IC*JGAb;1D7!{~RBifMrO|>D)P<`pg+kR+4Ckno0SL|Ja zO4OkV?a2GK+6d*SK?7Qmb6EQmY(JEu3iW742lBt8D={iii$=5|_q%FCl%e|4e`Wij z1)V7Po?Wqb2`W*CCbT2(R2!ijHE2L9a=vfvPqh6|iYnBj86C*~fv&`;KrI^4hTI>j z4N->bOFzl>Lkl`l;C$frKkQwCO4OkV?Z|t8+6d*SK?7Qm^FV8Vvh9abRG}Wt=s^C1 zbR|XwYSD-`bf=(1X*sj>S1eK^m6WWpY5VaA?QG*7wBIlvj{#4r! zrKmzZn$dxLPgi18pcaj2L+-=WhA2bzrJrW|p#_~Nc(`4$cL^#{hbFWm?-6Pvl%oa> zXhn{1?N7J;P>L$lqZu8@f26L&s6Z_m(T3bdsSQzv>PtVv_CpIgQSfNHV($`Eq7F@H zM_!;dLOE*CfL7!@#@e50`=Jz7s7Et8kpEa+iBW-CG@=c;k5e0>4Aqx@mhFcYbfVz# zcE#Q$s6-u_(2l$(sEtsL8Z@94IZw3qXWM=#MHTANj1J^KNmpW2pcaj2LvE-xL>a0t z{T$m5E$BqSlkJMVOHheAG@%`NPf;7895rY_D{`J{?a#ISP>L$lqZu8@k8~wQ1!~cV zHsn4{ZHO{dU;25rA6n3ff~VURdzYXRb!b96@}8kKLOE*CfL7$h*8Y6k52dI=J(|&h z{AcP)j0)7E5pBqQmf8?ysJ`?IY(KQ169vzV*iAvaSSq72oSeu?de7IdQEMRvvBC8$Il zn$V8C7psj>jv6$e6*(`l_P@6MP>L$lqZu8@&vhk61!~cVHsrokZHO{dU;3rCA6n3f zf|uD9dzYXRb!b96@?NesLOE*CfL7!b*8Vcv52dI=J(|&h{8#8oj0)7E5pBqQrP>f> zsJ`^y*nVh1CkkF=SL|JaO4OkV?Z_+DMkq%O8qkWIS6lnbZ9kNv3iW742l8K|D={ii zi$=5|_qA$6l%e|4udw~lf=(1vcE#Q$s6-u_(2l&a0t{VLlJE$BqS8|{j{OHheAG@%`NZ&Dkf95rY_D{|g! z?XR}|P>L$lqZu8@Z*(O_1!~cVHsroVZHO{dU-~t+A6n3fg16cgdzYXRb!b96^4_L4 zLOE*CfL7$R*8W=C52dI=J(|&h{I}~$j0)7E5pBqQhuRQjsJ`^;Y(KQ169wV*iA@>7n zLzJQV(r>c;(1K1Be9*4gy9AY}LlfGO_aU_r%29&`v?Axj*8XPO52dI=J(|&h{6SY@ zRG=1(XhZHt)P^WS^`+lp`=JG$DEO#dv3Ch7QHLh9BkyBsBb1{C4QNHqXzg#c{ZNW3 z)T0?4$p5&m#Hc_m8qtQ_PpA!1hU!bd&GthJI#KXRyJGJWRH6<|Xh+_pHbOaS(12Ft ze9GGY*7idws!)$+bRhrJx)P%TwP-{eazCRsL>a0t{dU_AE$BqSY**}Ef=bk(3GK-H ztl9|Ws6hi-k@Goge~0adQdFTH&FDb>=XE7U1!~cVHsmg9LzJQV((knW(1K1Be8H~R zy9AY}LlfGO_eHf4%29&`v?AwA*8VQr52dI=J(|&h{8d+CRG=1(XhZIo)rKfT^`+l! z`=JG$DENw9v3Ch7QHLh9Bk!wfBb1{C4QNHqX6^5>{ZNW3)T0?4$p4zI#Hc_m8qtQ_ zud5AFhU!bd*Y-mTI#KWqyJGJWRH6<|Xh+_zHbOaS(12FteAC+BXZxWPRj5ZZI*|V@ zU5QbFS~Q{!x!+bBq72oS{yWh^=L*1@|_Rfuf(W8EgI2=+y|%)QHJVEf57%b3p!EoK)Yh^5>%oN zO=w5ngVaVSM-3X#iX7M4|IzkCDXLJ9W^^F`!MYNo0<~yF8*(3_Hbfb!Fa1xpA6n3f zf`{4_dzYXRb!b96@;tQ>%29&`v?AwW*8V};52dI=J(|&h{D5tleXhA0mo@iI>U4lx~p$YBCdy?7+<)}deT9Ff4 z`^RiQl%fjtXhsL}pR6k}Do~3?v?2E?YD1Kv`qCe_{m_C=6g<_g*t-Oks6!Llkr%0r zP>vcjpcOe!v-VHeekes1>d}l2Pn0X)S?k>$bG)r z5M`*o^k;29w4f6OFR&~2EPP+G@}FgFVdA5 z6{tlc+K~HVwIRw-ed*8JerQ1_3SMGY>|KIN)S(IO$jjA6C`Sz%(2AUwTKgAlKa`>h z^=L*1@?WMaF)C1tMzkUK-#Yj=Wc>jZlsnG@unZ zueA0r*?uTR73$H94&=W|S7KD47L8~_ZmBjz8LBV+W!n!e=tRM*?TWoiP>DJ;p&faz zQ5&HgHE2L9a$algU$OmAiYnBj86C*4bR|XwYSD-`%@Icm^=R^-&y{x#bVrKmzZn$dy$H|k1^3e=(zZODC-+7M-^zVz2^ zKeV6|1#h-1_AWss>d=ICXhqIjto<9dA4*Y$dNiX0`ES*g7!{~RBifMr zHnkzjP<`od+J0z3Ckk4-V($`Eq7F@HN8a1jMkq%O8qkWIcUb$kY(JEu3iW742lC&k zD={iii$=5|w^JLU4AqzZw(W-&bfVy0cE#Q$s6-u_(2l%!tBp{O8Z@94Iq$Ld@7R7Q zMHTANj1J`Yx)P%TwP-{ea^I^qL>a0t{axD+E$BqS`|OInOHheAG@%`N?^he495rY_ zD{?+y?ccNgP>L$lqZu8@|DdkKs6Z_m(T3a)sSQzv>Pvs$_CpIgQSf2AV($`Eq7F@H zN8X?|LOE*CfL7#u#M*yg`=Jz7s7Et8kpEF#iBW-CG@=c;A5$Bm4AqzZq3wqjbfRFi zEA}oyCF;{vpaHGO`GmFqv+ajcRG}Wt=s^A_btOgxYSD-`XhqIq?LW2sP>L$lqZu8@ z|AMZ>s6Z_m(T3bFstr+w>P!F3_CpIgQSc?ZV($`Eq7F@HN8YM7LOE*CfL7#u+1h_@ z`=Jz7s7Et8kpC53iBW-CG@=c;UsW5T4AqzZh3$tHbfRFhEA}oyCF;{v zpaHGO`MS0L()L3ss!)$+bRhp5x)P%TwP-{ea(A^M%20jjU)g?WK_?2nX;p(`;eP>V*iA@@6KLzJQV(!a6&(1K1B zeAlkny9AY}LlfGO_dT@{%29&`v?AxU_TSomC`A?O(Ton{e_vN(RG=1(XhZG~)P^WS z^`(Dj`=JG$DEOgWv3Ch7QHLh9BhUHJy^TxU?SHiWP>L$l zqZu8@f2gj+s6Z_m(S}@4ZHO{dU;0nBA6n3ff`{1^dzYXRb!b96@*b`>LOE*CfL7!@ z!rK4E_CqPEP>*JGAm7)O7!{~RBifMrNVOr#P<`otwf)e7P82-KuGqT-m8e4#+L8BY zwGqlug9fxBC$RQ^v;9ztD%7JH9ms!-uEeN7EgI2=+{da7QHJVE|GVvn7IdQEadySt zC8$Iln$V8C$E%G{jv6$e6**6^_W!W`P>L$lqZu8@f1<9$s6Z_m(T3b7sSQzv>P!Ep z?S~e0q9C*@_AWss>d=IC*JGApfbl5~BjOXha)w zBefyQP<`pY*nVh1CkmcsSL|JaO4OkV?Z|t&+6evsJkWO>uyWt_@%z57d+)vX-h1!s z*?aH3_ukKQuMj#3*&&1wLI@#*5W>&yBy$`u6hu{P+IjdmQ~bQdFT9O~^V| zvcD($p%@j&paHGO4Yegi8LCl-W@MkISsx{+-1Ymi9~#kyyz`|+?jn?<2K8t`&IOtc zP>L$lq6t}%WdA_+Loq6lK?7Qmd!e?3C_^>s(2VShH0z@TmAn2>_Cq7ukaw}P$X$eT z)SwIpmLWb`=JqS z$V;R}?jn?<2K8t`&gGg7P>L$lq6t}7NcJ$<55=fJ1`TLM?v>gSq72ojLo>2d&H5-o z<*vhJKQy8Zc~?n`+(jry4eHT?oU1h(pcGZ8MH8~Fk?aw&ABs_d3>wgi+)P_Sl%X1R zXh!z6n)OkF%3ZeXheos^?>cFby9ni|K|NZKbG>E*l%fi?XhK#l*&}5?6r%zeG@uo^ zH)unh?Bl{lB`Y1u=E?4$LBifL6ue8Wr zgmToN9xceZPqP6^QH5GGA*+$>ak3wZQGpB^(2CsqwIxIus!@k#WIv!;A0?>Vb-e6{ zMzkUCL1~e@2<50jJz9`sG#j84Rj5T1vL2G`39=uGQGpB^(2CrLwIxIus!@k#WIv)= zA0?>V<;i|%L>uxRl@_^+P>veZqXjvSX*NJ9s!)q2WIZm~6JveZqXjunYBoSAs!)q2WIZL>lVv{?qXHQ; zpcT2DwuC4{HR{le?58#BqXd<^PLci4h&JRsBQ0_lp&T`+M+8ChtQRDEy6lHyR3L)}v?BLKZ3$6^YSf__*)M6)OwQ}#n6+K~5} zw8&kAa@3$6Ey#IYvjIv`g<3Qr>kY}CCHtWm7093gt;n6VB}5sjQHN$^zo}UtC8*pL z$bM)<8}iUvHEs{N3_Cql$kU;}lk^7FegeXHb>d=hr zcQxyy1eLqak^Rt!Hsrl0Epiv395tv%3vyP?1}H@pYSDzO_a%F-?1y4hAcF?9BKHGr z2~mb>)S(&KA8OV|2`YDmvL71JhP+K$d}In!!;YA6ji82 z6S9tw>;Vb&>3cMzkUCSZR^F z2<50jJz9|CYBoSAs!)q2WF05ji)B9)qXHQ;pcT2tYfFeSRHF{f$UZ@{K1xuzE0+Dx zh&JST(js>e%29)Qv>@k1%?2n%6>8Chtdk^riR_1BR3L)}v?BLpZ3$6^YSf__*{5jM zM+qu-T`K#b5pBpjRa)dOLOE(sj~3*drr7|cs6s88kafCbFO&UHj0$AXfL7%C+7hA+ z)u=-=vd_@0j}lbwN@PDYq78XxN{ie@C`S$I(Sn?_G#j84Rj5T1vI5CoF8iSv7093g zt;juFTSAnf8g*z!_BopMQG&`{SIB;7L>uzXl@_^+P>veZqXjvkW&@O>3bklL)_Ib> zQuaeJDv&_~T9JFcwuC4{HR{le>hY=BZ! zp%zWZx=6BD$$ltC1u|$rD{?Q^mJnsAMje`w9c$J{2`YD8E&HJnZOFSsTI4Q5IciXk z7UW#2*#M=eLM@t*b(v(Zk^NAN3S`iLR^%qy5~2*%s6#WdFW0P(5>)QWWIr^b4S82c zi`+#hM-A%Hf}ATg8=w?bs6`X9QpsK``=J;W$e;nO$h}HiLX@Ezb!bNR)tdEDg34Xj z$$n@=8}hD^7P*U1jvCaX1v!~!1C*i)wP-@twUWJF_Cql$kU;}lk$auCgeXHb>d=hr z>ox161eLpT*$<6qLtZW|au=Z-HK<1ma&FLUfKpVU7EQ>yQL;D4ekeu-GH5_6a&OX> z5M`)F9h#9{Xx2vwDtFx|`=JqS$h%ou2()2xpYRPHKdKQy8ZdACc8+(jry4eHT?oI5ldpcGZ8MH8|r z$=)pcp%@j&paHGOy;EC4l%X1RXh!y3n)OkF%3Zg}erQA+^6r)vxr-Loq6lK?7Qmd#|>HC_^>s(2VT+H0z@TmAgvW4~=L;UL!4X7oi+A zs7DKO?$>O9QdFT9O~`scvbV{8C`JV`Xh17+AJmo*WvE6SnvrcZ>!SpfyKa~L(1&YmJfYbDrKmzJnvm5>_D&YmbeauNiYnBi30Y4|_HNk^#i&3A4QNH~ zGujfO4ArPZGqRu6td9~@?y6-!G@=c8y|l<(gmToN9xcc@q}c$as6s88koBBo?~(mb zj0$AXfL7!_uPq_UP>nh?BYV)Sj}lbwx>xo?BifMng0#q8gmToN9xcduQL_O`QH5GG zA?qc{-Y5H^7!}B%0jV)yRHmL>uy6krug&P>veZqXjvy zYBoSAs!)q2WKEL2U-m;WDv&_~T9NyjwuC4{HR{le?AJBxqXd<^9+3Ueh&JTCAuVzj zp&T`+M+8ChtT!e5pzMcYR3L)}v?BK{Z3$6^YSf__*>7vsM+qu-8QBkw zXhYs2Epiv395tv%3v%AkY=BZ!p%zWZdRMX!$$ltC1u|$rD{|k{mJnsAMje`wy=vA+ z2`YCzEc>AmZOD6HTI4Q5IciXk7UX=O*#M=eLM@t*^`T@Rk^NAN3S`iLR^)El5~2*% zs6#WdKhms^5>)PbRQ5w7+K~6Lw8&kAa@3$6Ey(#qvjIv`g<3Qr%W6OO-N$4<6r%ze zG@uo^hiOZQGE}1u&B#7nvpz~tx$AM+4~=L;-VxFwcM-}_gLq*%Ujc7yOand4p5z0}6 zdbA+tc+CbVMHOn%gsc-J`;_d5VpJf52DBpA)0Plrs74){k$s|OeUzYbS10?S5pBpj zNm}GCLOE(sj~3*dtl0pis6s88kadb=pO*blj0$AXfL7$5sx2YPP>nh?Bl|SX`Y1u= zu4iOFG@=c8r%Q|6MJPuN>d}H6U$X&9QH5GGA?pmuJ}dj77!}B%0jkQTX%P>veZqXjuuzXlNPy)P>veZqXjwVYc@bBs!)q2WL+TH=Vd<> zqXHQ;pcT21wuC4{HR{le>e%29)Qv>@kV%?2n%6>8Ch ztXQ%y$bKkB1u|$rD{?QUvHT`$>JWj_?70vR-*6}h>#geXHb>d=hr8#L>q z1eLoc*$<6qL*9+jB6ktWQGwgi+`F|UL>a14hh}8gn)OkF%3W{CerQA+^6rrqxrs(2VT+HS41UmAe+%4~=L;-UHGicM-}_gL_|=6r%zeG@uo^4{1w?GE}1u&B%UOvpz~tx$9lo4~=L;-Xqc? zcM-}_gLSH1hhkJ9g9fxB_i=3rQHE;Np&8jvXx2vwDtE22 z9~#kyyjEJ|E&Ym9Mo)pQdFT9O~`suvhT}&C`JV`Xh17+pVF2PWvE6SnvvaU z)<+2{cYPrHp%HD!ds&YmJfqnFrKmzJnvnIZWIvSsP>c#>(12Ft_SzDn z4ArPZGqMk9)<+2{cWtsC8qtQl=cGmMB9x;B^=LuP^O_A%iYnBi30Z?=Ka%}Wj0$AX zfL7$bpe-TFP>nh?Bl|_o`Y1u=u8(CuG@=c8FG-8sMJPuN>d}InQL_O`QH5GGA?szy zej@v!7!}B%0jTJbTiaQkt6|X6**X6bHpi@wc3S`iLR^+~+Eg{NKjXE?Vd)BOv5>)Q` zg3rD0Q8c0rd2dRK+(jry4eHT?oVPR^pcGZ8MH8~#mh5L_KNO<^88o03xr?@hC_^>s z(2VSNH0z@TmAk%B_Cq7ukoT^%$X$eT)Sw62Kn4wHMefJi5~2*%s6#WdKhdm@5>)Q`QrQoUXhWWL@N@qmcM-}_gLwgi+#|FlL>a14hh}8kn)OkF%3WVB`=JqS$U9P6MeZV$qXzY8LC&$74N!_I)S?Mlu4KPT_Cql$kU;}lk$arBgeXHb>d=hr<2CD} z1eLqKTJ}RD+K_jGw8&kAa@3$6Ey(dS8=w?bs6`X9PL%A|$bKkB1u|$rD{@cLmJnsA zMje`weX?eKl%R6g*UElqL>ux>krug&P>veZqXjvqYBoSAs!)q2WSu72uao^yj0$AX zfL7$5t}P+TP>nh?Biq-kj}lbw`g++9jc7yO8PXzm5z0}6dbA+tOw9%;MHOn%gsih9 z`wg-micx_K8qkW|KwCnTp&E5)M)uj7^-+S#UEe7Cp%HD!J4agNE&YmoU7RY zrKmzJnvfMr_M2os6r%zeG@uo^=V?obGE}1u&B#7qvpz~tx$B!{KQy8Zc^62F+(jry z4eHT?oJg|)N>PPcG$HFk$$pFMhhkJ9g9fxB_abcxQHE;Np&8j1Yt}~zDtCRW?1x6Q zAupB|xrI7$yJbH#q78Z1ON-n^C`S$I(Sn>@vjIv`g<3Qr>juew zkL-tHR3L)}v?BLLZ3$6^YSf__**9s{M+qu-eXs0?MzkTXkQTX%P>veZqXjuPYc@bB zs!)q2WZfd!@00ydj0$AXfL7$*sx2YPP>nh?BfHeBj}lbw`hM9Djc7yOZPFrl5z0}6 zdbA+tcFhJTMHOn%gseLx`vbBcicx_K8qkW|N?Ssdp&E5)M)sYW^-+S#T|X%Mp%HD! zyGvT+E&Ym+^yLFrKmzJnvhjX_J?FY6r%zeG@uo^_h?IqGE}1u&B(r2vpz~t zx$B2zKQy8ZdG|?++(jry4eHT?oJO+&N>PPcG$HGL$^MA!hhkJ9g9fxB_W^AQQHE;N zp&8i^YSu>yDtG;;?1x6QAUvHJt5hj zko{1M3S`iLR^+zY5~2*%s6#Wd4{Fv&2`YE}r0j=Av?1?FX_31K<)}eDT9EUUW&@O> z3bklLRwvn?lKoJO3S`iLR^&ddEg{NKjXE?V`x(vpC_&|}pO*d5h&JRsD=l&tp&T`+ zM+8ChtV5Fh8QBlTs6Yk{XhrUG+7hA+)u=-=vY*$ij}lbw`dQfzjc7yO zAT4qip&T`+M+V z_4BeH8qtQlm!(DSB9x;B^=LuPE1C^ZiYnBi30bd7_7`M76r%zeG@uo^leUB?LpAEq zjO^Dm>!SpfyM9sjLnGRd_qw#mU4(MfpdKyAc|)@SN>PPcG$Cu2>@UfFC`JV`Xh17+ z-_({6WvE6SnvwmMW_^^Pa@Q}*erQA+^4^vfxr49)2xpYRPOp!*$<6qL*6Paau=Z-HK<1ma^BZ$fKpVU z7EQ?dK(fCk`=J;W$e;nO$o)`TLX@Ezb!bNRrdb~)sND7IvL71JhP;oYMeZV$qXzY8 zLC(jT4N!_I)S?MlpGfvMWIq(60vR-*6}i@vpSFZ3LpAEqjO@cS>!SpfyM9ylLnGRd zceu33U4(MfpdKyAIYP4mN>PPcG$G5D>~G0_C`JV`Xh17+kJOeBWvE6Snvs2!W_^^P za@TLmerQA+@{X1kxryDtG;^?1x6QAKq;zFizZ|pFWJw^ekeu-GH5_6 za!=5f5M`)F9h#BtY1T&xDtG-c*$<6qL*9wfB6ktWQGI7$Psn~~L>ux>lNPy)P>veZqXjvqYc@bB zs!)q2WciZ)ld>O*QGpB^(2CqMv?W9ts!@k#WS^;7A0?>V^`~S%G@=c8XGx3PMJPuN z>d}InK(hf#QH5GGA?s|({%P3{#i&3A4QNH~IocAU4ArPZGqTUstd9~@?)o#b9~#ky zyii)?E&YmoTu3UrKmzJnviwAWdE$}hhkJ9g9fxB_X2GRQHE;Np&8kcW_^^P za@U`e{m_UuySh9a!_Cql$kU;}lksE7Eh%!{8 z4$a8EM6*6hP`T?b$bM)<8}crd7P*U1jvCaX1v!^#Hb5z=P>UvHC6fJ%vLA|3feaeZ zirmY!B}5sjQHN$^U!hqaC8*r>mt;RQq78XhN{ie@C`S$I(Sn>*vjIv`g<3Qr>nh3q zW!VqKs6Yk{XhrVT+7hA+)u=-=vaivsj}lbw`YW;@8qtQlOj_hFLOE(sj~3)ytJwgh zs6s88kaeA8|ElbVVpJf52DBpgdTj|&hHBKI8QHmJeUzYb*I$$U(1qABs_d3>wgi+}pGzL>a14hh}8ou2~-? zsND6pWIr^b4S9D+i`+#hM-A%Hf}BdT0ZLJYS~MZ+PRagl*$>62Kn4wHMebeN5~2*% zs6#Wd@7Ao35>)Q`JF*`d(T2QQTI4Q5IciXk7UbNc*#M=eLM@t*b+2UquIz_mR3L)} zv?BLDZ3$6^YSf__*^Op>l%R6g-;@2&h&JTiFD-Hxp&T`+M+V^$%n}G@=c84@-;OMJPuN>d}InM>HFt z6ji826S5wa>_3$KP>c#>(12FtKBg@p%216uG$Z?Q&H5-o<*t7u`=JqS$a_LsL$lq6t|CCHs$MKNO<^88o03xld|Kh%!{84$a7ZO0zynP`T@$$bM)< z8}d47k-G@xs6jnikn^-=1C*i)wP-@tGm`zMvLA|3feaeZiritD%!Xha+GUX>QPi%^al)T0GClV$^yq6)QWLe^`N z{nxS|icx_K8qkW|*R>@?8LCl-W@NviSsx{+-1To{KQy8Zd9$?0U4(MfpdKyAc~i3i zN>PPcG$HFP$^Ki}55=fJ1`TLM?%UcDq72ojLo>1$&H5-o<*t7x`=JqS$a_axM?1y4hAcF?9B6ro65M`)F9h#B-zGi)tpmNuLkp0kz zHspOEEpiv395tv%3vxcxY=BZ!p%zWZ+9dlQWj_?70vR-*6}ca2ONcU5qYll;{#dg< zN>I7$KgoV*L>uxxkrug&P>veZqXjwEQ=eu7l%fi?XhPOulKs!JABs_d3>wgi+{3jc zL>a14hh}6Sp;;d#sND5mWIr^b4SBY-$X$eT)Sw62 zKn4wHMefns5~2*%s6#Wd9nJbELFKOhCi|fgZOA(yEpiv395tv%3v!OpY=BZ!p%zWZ zI##m(UG_sUDv&_~T9NB&ONcU5qYll;K2EbfN>I7$f5?7lL>uysmlnB;P>veZqXju9 zXf{A8s!)q2WOwIxIus!@k#WS^v2A0?>V^}l34G@=c8CrgXm zMJPuN>d}InQ#2c(6ji826S7W~?EjYiP>c#>(12Fto~A7!%216uG$Z?T&H5-o<*xrD z`=JqS$n&K|?jn?<2K8t`&Ka5wP>L$lq6t}NO7{QCekeu-GH5_6a?jG15M`)F9h#9H zXx2vwDtG-q*$<6qL*CiaB6ktWQGI7$4`n|zq78W$ON-n^C`S$I(Sn>k`TSk?e)OwT=qjF+K_jZw8&kA za@3$6Ey%fAvjIv`g<3Qr>l(=(A^V{i7093gt;o%^B}5sjQHN$^U#nRkC8*qG%YJA? z8}hD`7P*U1jvCaX1v%GiHb5z=P>UvH<&r&8_Cql$kU;}lk$Z!-geXHb>d=hr8#U{r z1eLpvlKs$#HsswTEpiv395tv%3vvq01}H@pYSDzOn z)S(&Kw`$f$2`YCvvL71JhP+Z*4P(X5XWRPJ(RKQy8ZdG|_-+(jry4eHT?oclBzpcGZ8 zMH8|b$sQ;Bp%@j&paHGOyPPcG$HFD$(|tlp%@j&paHGOeOOyUl%X1RXh!xUn)OkF%3Yr9heos^?@?)y zy9ni|K|NZK^O$A>l%fi?XhPQGl08xOLoq6lK?7Qm`-HZHC_^>s(2VR>vpz~tx$7j^ z4~=L;-a%=Ry9ni|K|NZK^Q2}2l%fi?XhPOgl08}WLoq6lK?7Qm+i6RPGE}1u&B%UQ zvpz~tx$6|!4~=L;-ZRo7cM-}_gL_C`JV` zXh17+U(}WmWvE6SnvwmIW_^^Pa+fdrp%HD!8>L0=B9x;B^=LuP%bE>PiYnBi30bd5 z_6*q%#i&3A4QNH~tJ)Hx4ArPZGqNYm`Y1u=t}|snG@=c8uStvCMJPuN>d}In*EJiU z6ji826SCfr>{+rOicx_K8qkW|SzAJsp&E5)M)sSU^-+S#U4iU}MzkUCEoqUv2<50j zJz9|Swq^sAq6)QWLe?VLvt>UNqXHQ;pcT3AXiJDPRHF{f$bMI|K1xuz>m1n+jc7yO zd(t9z5z0}6dbA*C)og%LRG}74$a-J0=gNL4Mg=lxKr3=T(3TKos74){k^P}&eUzYb zS19|T5pBrZq($x`l%odqXhF_Lnhj8jD%7G0SszRGJlPM$s6Yk{XhrTP+7hA+)u=-= zvaRmZ7x*Ya<*xH(KQy8Zd51}h+(jry4eHT?oWnI6pcGZ8MH8})kn9DrABs_d3>wgi zTw7a0l%X1RXh!ytn)OkF%3YD{heos^?y`p%HD!J5^fb zE&YmoTk|TrKmzJnviw6WG|EbP>c#>(12Ft`q~nr4ArPZGqTUntd9~@?n-1o zG@=c8XG)9QMJPuN>d}Invosr^6ji826S4xyUM~Bg7!}B%0j!SpfyHeQ?jc7w&BrS3mp&T`+M+M>C`S$I(Sn>SH5;H5 zRj5T1vQo)jEBm1s7093gt;oGfTSAnf8g*z!_SKs8QG&`{*U5fpL>uz1krug&P>veZ zqXjvcW&@O>3bklL*0qwoUiL#VDv&_~T9JF5wuC4{HR{le?CUk_qXd<^a@h}!XhU8u zEpiv395tv%3vzDIY=BZ!p%zWZx>2$>$bKkB1u|$rD{^nrmJnsAMje`wU1-)v2`YEp zDEpxiZOFS>TI4Q5IciXk7UbNb*#M=eLM@t*b*p4=lKoJO3S`iLR^*o25~2*%s6#Wd zZ_})g5>)OgWIr^b4SBaqi`+#hM-A%Hf}A@v8=w?bs6`X9D#_j~`=J;W$e;nO$h}ir zLX@Ezb!bNRU7Gb#g34XD$bM)<8}ja!7P*U1jvCaX1v#~51C*i)wP-@tJ(9gu_Cql$ zkU;}lk$bPUgeXHb>d=hr`!wsL1eLo=*$<6qLtY~-au=Z-HK<1ma_-k`fKpVU7EQ={ zK(e>Vekeu-GH5_6av#)|5M`)F9h#ACH0z@TmAh`2{m_Uu3K55=fJ1`TLM?m=w{QHE;Np&8jvYSu>yDtFx_`=JqS z$a_j!L$lq6t|~OZINr55=fJ1`TLM?lamFq72ojLo>3U)vS*a zRPL%}KQy8ZdA+pAU4(MfpdKyAIi%SDrKmzJnvnIJWbcvvP>c#>(12FtKCdky%216u zG$VV^td9~@?z&g@LnGRd_ky&@U4(MfpdKyAc~P?gN>PPcG$HFH$=)aXp%@j&paHGO z9knGy8LCl-W@NvtSsx{++||f_Xha+GUXd2Li%^al)T0GCuWB|xDXLJ5CS*;Ly!SpfyB?7J(1d=hr z!!_%p1eLoUm;KO)Hsl>4Epiv395tv%3vz7D1}H@pYSDzOBPIKU?1y4hAcF?9BKIh5 z2~mb>)S(&KM{Cwc2`YEBvL71JhCD}FyDtC3V9~#kyypyCw?jn?<2K8t`&dHh$ zP>L$lq6t~2NcL&j55=fJ1`TLM?y1@mq72ojLo>2Z)2xpYRPK64_Cq7ukaxPY$X$eT z)Swwgi+%vT$L>a14hh}7-rCA>(sNB`derQA+ z@&aj*y9ni|K|NZKbGBv!l%fi?XhPOGl078*p%@j&paHGOJy%;ol%X1RXhwFZSsx{+ z-1VI7heos^?>uRdy9ni|K|NZKbG~K+l%fi?XhPNnl6_wGLoq6lK?7Qm8)-|3GE}1u z&B(q`vpz~txoeR9(1&YmB$^FSiYnBi30ap*_9fX5 z#i&3A4QNH~71|P_4ArPZGqSJLtd9~@?iyu3G@=c8skF#lgmToN9xceZO0xkV^@{9=MzkUCT4|BH2<50jJz9`+ zon`}+q6)QWLe}+?eO2~DF)ENj16q-rYfFeSRHF{f$i6|dK1xuzYm)uYh&JTiC@pdq zp&T`+M+n_Q@Df^)q7093gt;oGwTSAnf z8g*z!cCA?-C8*r>mh6W{v?1>vX_31K<)}eDT99+EW&@O>3bklL)_szFTlPaSDv&_~ zT9MmmONcU5qYll;zF)IGN>I6Lk^Rt!Hsn1ZEpiv395tv%3vwRRY=BZ!p%zWZGLn5q z_Cql$kU;}lk^7LggeXHb>d=hrhc)Y?1eLqqmHp6&Hsn1bEpiv395tv%3vwRSY=BZ! zp%zWZdQ7tK$$ltC1u|$rD{>##mJnsAMje`w{e)(Hl%R6gD*K@kZOCh-MeZV$qXzY8 zLC!(V1}H@pYSDzOCnfv7?1y4hAcF?9BKIk62~mb>)S(&Koo0QMpmNs-vL71JhP62Kn4wHMQ*PxA<9sVIy58ukY;_9pmNtH z`=JqS$a_v&2p z)U1yZRPOp%_Cq7ukoS_b$X$eT)Swwgi+*ha14hh}8Is#zZ;=r+;kf8pnS_A$lFijNd0PM_XfsJKCKzv7VM9mRpyK24pixJq%S z;-KO+h4s3;RvvT;icx_K8qkW|H?$>08LCl-W@OKr^-+S#U0?9I_dSY6v?1?JX_31K z<)}eDT9EUWW&@O>3bklL*4vW(jO>SER3L)}v?6!WmJnsAMje`w{f=gRl%R6g7s`HU zL>uznl@_^+P>veZqXjwdX*NJ9s!)q2WUZ3@BH0hcs6Yk{XhrV(+7hA+)u=-=vOmzQ zj}lbw`eNA+jc7yOhteW<5z0}6dbA*C(`u||_ne2yR zR3L)}v?BKiZ3$6^YSf__*|uhVl%R6gm&<-=L>uysloq**P>veZqXjufX*NJ9s!)q2 zWF0NpuaNyvj0$AXfL7!>+7hA+)u=-=vJYt1M+qu-eWmP&MzkUC7-^Ba2<50jJz9`+ ztY!n0q6)QWLY6Dpuaf;xj0$AXfL7!lr!67MP>nh?Bl~#G`Y1u=uCJE;(1L$lq6t~2N%rexKNO<^88o03xuM z5M`)F9h#ASwq|{lpmNtY%6@1>8}iPP7P*U1jvCaX1v%$xHb5z=P>UvHg_8Xy*$>62 zKn4wHMecdp5~2*%s6#Wd&)2Mv5>)Q`X4wyoXhYrw(js>e%29)Qv>+$aY=BZ!p%zWZ zx=^y;BKx5j7093gt;oGdTSAnf8g*z!_Qjg@QG&`{-zxi|5pBqerA6){l%odqXhF^; znhj8jD%7G0S(i%o+hji!qXHQ;pcT27X-kMQRHF{f$WAotqXd<^zFqc1BifL6xwOb# zgmToN9xceZLbCx%QH5GGA?r%XeuwObVpJf52DBnK)s_%ts74){k$shBeUzYb*LTW( zXha+Gu9gL$lq6t~INcQ_=KNO<^ z88o03xwmRdh%!{84$a6eHS41UmAk%Q_Cq7ukawH3$X$eT)Sw8}jaw7P*U1jvCaX1vz(X zHb5z=P>UvH)sp=o*$>62Kn4wHMeaS?5~2*%s6#Wd@71i25>)Q`Vc8FjXhYt8(js>e z%29)Qv>>O^Y=BZ!p%zWZx?i$CBKx5j7093gt;l^qTSAnf8g*z!_Jf-BQG&`{KPvm7 z5pBpb(js>e%29)Qv>@jp%?2n%6>8ChtcNB0W3nHLQGpB^(2Cqgv?W9ts!@k#WIw7| zA0?>V_2aT18qtQl$D~E>B9x;B^=LuPG&^-+S#T|X)Np%HD!ds15DE&YmJf+zHrKmzJnvm5=_NQb&6r%ze zG@uo^PisqvGE}1u&B%U6vpz~tx$CE8KQy8ZdCy9V+(jry4eHT?oL;j5N>PPcG$HGd zWPe8XLoq6lK?7Qm`<%9fC_^>s(2VToHS41UmAigc_Cq7ukT*z++(jry4eHT?oEJ13 zpcGZ8MH8}KlyDtG<7?1x6QA@5~rk-G@x zs6jnikn@UW1C*i)wP-@ttCIZ%*$>62Kn4wHMed|6A<9sVIy58uHO=}cLFKMrl>N|% zHsrl7Epiv395tv%3v%AjY=BZ!p%zWZnkD;7vLA|3feaeZirhD~B}5sjQHN$^zol6p zC8*r>%d#ID(T2RYrA6){l%odqXhF`R*#M=eLM@t*^^RnJMfO86Dv&_~T9Ny%wuC4{ zHR{le?DsV5qXd<^epU8EBifL+N{ie@C`S$I(Sn@!H5;H5Rj5T1vObXPugQKWMg=lx zKr3=T)Rquss74){k-cfwM+qu-{krUjMzkUCBWaPl2<50jJz9|Sv1S95q6)QWLe?je z{SDa<#i&3A4QNHK_3WoDA<9sVIy58uFwOcXLFKOBl>N|%Hsl>HEpiv395tv%3v!Oo zY=BZ!p%zWZvL*XlvLA|3feaeZirgc$B}5sjQHN$^AEj9zC8*r>+p-@T(T2RErA6){ zl%odqXhDvn*#M=eLM@t*bwIMeBm1Ek7093gt;jt_TSAnf8g*z!_OY7vQG&`{zbpHp z5pBqGrA6){l%odqXhF_#nhj8jD%7G0S;tHEv$7wGQGpB^(2D*)5A+=eto*Nk{Oogn zd+)vX-uw4Gd+)vX-g}=ALI^iP2qA>PbgG$HG3$$pjWhhmhY1`TLM?m5~LB7-W_p&8ldYSu>yDt3Lf?1x6QAup5` zxrp)DAm<{@1}H@(YSDzOizWMYvLA|3jv6$e6}hptgvg)@b!bNR zC7Sh7f{I;VFZ-bpZOFS+TI4Q58LCl_7UW!}*#M=eL@k<-l}Pp*WIq(695rY_D{?Q_ zmJk_Kp$^T+zCyD;N>H)u8)ZKs(Sn>*vjIv`iCQ!v>nh29lkA6L zl%oa>XhrVT+7cpzD%7DF+1F^+M+qu+eY5O`MzkT%NQ>M>C_^>s(Sn?7H5;H5m8eA% zvaXZtx5$1dMmcKGfL7#QuPq@ms6ri@k)3JQM+qu+eXHz;MzkUC25FJI2xX{7Jz9`+ zqh!Xh!y3 zn)OkFie29=`=JqS$g8A9?jn?-8ue&F&fS^~P>M>_q6t~|NcMYVKNO=JHE2L9a_`la z5E)dV4$a7}HS41U6}!Gy_Cq7ukawT7$X$doRHGg($hlv$0ZLJcS~MZ+0m*)!?1y5M zqXrFVMQ)=lAu^~!9h#B-pk{rPpkmke%YJA?8}c5K7P*U1hHBKK1vw9EHb5yVQHv&I zJtEm3ko{1Ma@3#!t;l^;TS8<|g*r4N`!UV>C_%-pAC&#jh&JRsE-i8wp$yfiM+R^~16s8qtQlPFmzH zLK&)2j~3)St=Ryjs6;KAkoAmYe?;~}G0IVc2DBpgS#1fCK^5xIjO<>sK1xur>qlij zG@=c8honXBB9x&T^=LuPbD9lMib~X?30coe_QzyD6r&t9Xh17+2W<(FK^5xIjO-UQ z>!Sn}yMA2uLnGRd_oB4OU4$}JqaH2Dc}cSYN>PbgG$Cu0>`%ykC`LJI(12FtzN{@F zGN?iwnvwmAW_^^PV%JZ~erQA+@?Mn|xr49(5#OVRP6d`*$<6qL*6Vcau=Zt)u=}ca^BQzfKpVV7EQ={ zOR_&B`=J=+s6hi-k^8o`gvg)@b!bNRqFEm$sMz(hvL71JhP-#AMeZV$p&IpQLC(9H z4N!_o)S?Ml?@9LOWIq(695rY_D{@zD36Vh+>d=hr_ciOI1Qok}UiL#H+K~5ww8&kA zGE}1;Ey(#$vjIv`iCQ!vYm@9R$bKkBIcm^=R^)!9Eg>?fLLHis{jp|!l%QhQFUo#s zL>uxxkrug&P=;#MqXjuu|7kWrDJoHmCS)BZ*gcapaHGOJzQHtWKe}VG$Z>6 z&H5-o#janL{m_UuO9}ABs_q8Z@94xkqbD zhzzPwhh}6un)OkFie0}d`=JqS$U8<_i`+#hLpAErf}9gI8=w@Gs6`X9 zJjwos?1y5MqXrFVMea%35+Z{t)S(&KCu`P62`YB|rtF7Cv?1>lX_31KWvE6yT99)< zvjIv`iCQ!v>r~19mh6XOl%oa>XhrU6+7cpzD%7DF*{5sPM+qu+{kH6fMzkT%mlnB; zP=;#MqXjuPbgG$HE}$^Mb-hhmhY z1`TLM?xoriB7-W_p&8kiY1T&xDt1}29~#kyyhK{$EgcapaHGOy;563WKe}VG$T9Jtd9~@>^fZbLnGRdca^lrU4$}JqaH2DxmvRU zN>PbgG$HF6$sQs5p%~?;K?7QmYqTXq234p-GqSJMtd9~@?6PG)G@=c8*GY@qMJPix z>d}In>opso6qTq&6S6YN9x3~w80Dxz16q-LgSLdopbB+pM)r-G^-+R~T}R1&Xha+G zZju(ci%^DY)T0GCxn={Dq7t=eLe|ZaJzDldG0IVc2DBpg7HtWUK^5xIjO<%A>!Sn} zyBygMjc7w&AuVzjp$yfiM+`K!M+qu+xw0P`(T2Qxq($x`l%X2+XhF`snhj8jO4OnWS+!)3m;F$T za@3#!t;oGkTS8<|g*r4N`+m*(C_%-p6J$R$q78WuNQ>M>C_^>s(Sn>tvjIv`iCQ!v z>p{t$DEpxp<)}deT9NyZwuH!_3Uz2k_QRU>QG$wHp6rK4v?1>iX_31KWvE6yT9EUo zW&@O>618YT)?<=AN%liA%29&`v?BL$Z3&S<73$E8>{hcrN>H)uWZ4gmXhYr;(js>e z%217Zv>@k6%?2n%C2G-xtfwSXhm+PEg>?fLLHis{j_F%l%QhQ0of0Y zXhYsJ(js>e%217Zv>@kM%?2n%C2G-xtX{IG%6=$DIcm^=R^%SimJk_Kp$^T+eonJK zN>H)uG}#Z0XhYuf(js>e%217Zv><2DY=BZ!q83fadO@?f zLLHis{gP&Vl%QglFZ-bpZO9v?MeZV$p&IpQLC(vX4N!_o)S?MluSoU`*$>4iM-3X# ziriPVB}4{Qs6#WdC(ZgOLB*~!Wj{2c4SBCgi`+#hLpAErf}Gbi8=w@Gs6`X9-jM8B zvLA|3jv6$e6}hvvgvg)@b!bNRo0|1ef{I;%?1x6QA@40|k-G?Gs75_nkn^@?1C*i? zwP-@tBH6QLKNO=JHE2L9a^KOG5E)dV4$a7ZSF=7!P_gSA*$<6qL*9GRB6ktWP>p)D zAZOKVfKpVV7EQ={U$W=QekevcYS4gIM>_q6t|aOZGh355*`)4I0pj+)uP6L3iL!Z9DM+qu+ zoiF>L5pBpjOj_hFLK&)2j~3({uGs*ks6;KAkadJ)FOdCEjB?bV0js(Sn?#H5;H5m8eA%vK+}?DEpxp<)}deT9JE< zwuH!_3Uz2k_OY7vQG$wH7s-BTL>uyslNPy)P=;#MqXjvxW&@O>618YT*71_PSoT9P z%29&`v?BKeZ3&S<73$E8>=QNXqXZSZV%ZOkXhWVSEpiv34ArPd3vy1?fLLHiseL%B5N>H)uQrQoUXhYtq(js>e%217Zv>@j+ z%?2n%C2G-xtkWfXne2yRl%oa>Xhp8CEg>?fLLHiseTHUzl%Qf)BKx5cZOA)QTI4Q5 z8LCl_7UZ0z*#M=eL@k<-6-f4S*$>4iM-3X#irllcB}4{Qs6#Wd&(W-p5>)KELiR%= z+K_jyw8&kAGE}1;EyxKq8=w@Gs6`X9&XeqwvLA|3jv6$e6}jhYONb1rP={t@U!YkZ zC8*ey%6@1>8}cG)k-G?Gs75_nkaMAC1C*i?wP-@tMUuTr_CqnsQG*7wBKKl#36Vh+ z>d=hrShGG#P_gT3*$<6qL*6CQB6ktWP>p)DAm>ue1}H@(YSDzO%Orb^?1y5MqXrFV zMQ)-kAu^~!9h#ASxn_NopkkMi{m_UuhhmhY1`TLM?seJ{B7-W_p&8lNYt}~zDt2YE9~#kyyi8i;EgcapaHGOy-8a_WKe}VG$T9Ltd9~@?7C6*LnGRdceAv} zU4$}JqaH2Dxka-9N>PbgG$HF&$=)RUp%~?;K?7QmTWCv&460CvW@I1Ktd9~@?8;?7 zG@=c8w@HiKMJPix>d}In+cg`Y6qTq&6S7Ll-Yol}80Dxz16q-Lhqi>spbB+pM)sYW z^-+R~UAM@7Xha+G?vfU{i%^DY)T0GCm1YB!q7t=eLe|}qy;b%@G0IVc2DBpg9&HJc zK^5xIjO=?g>!Sn}y9(J4jc7w&EiG~vp$yfiM+NQ;BifMnl(fiQgfdj4 z9xce}G#j84m8eA%vYwXgU9umFQH~lkpcT2#XiJC;s!)e!WIwA}A0?>RRmpy6L>uyY zX_31KWvE6yT99){vjIv`iCQ!v>p98ZE&HJu<)}deT9Ny_wuH!_3Uz2k_MllGC8*eS zkL-s=v?1>WX_31KWvE6yT9EUiW&@O>618YT)=QGTSN20O%29&`v?6!ZmJk_Kp$^T+ zep$0VN>H(@mi^F(Hsrk`Epiv34ArPd3vyo7Y=BZ!q83fank0Ll?1y5MqXrFVMeb|b z5+Z{t)S(&KuWQyv2`YBoFZ-bpZOD5=TI4Q58LCl_7UayD4N!_o)S?MlZ%Xz7*$>4i zM-3X#irlxfB}4{Qs6#Wd-`1>;5>)JJWIr^b4S9>S$X$doRHGg($azPz0ZLJcS~MZ+ zUCBNu`=J=+s6hi-k^7#ugvg)@b!bNRs#zZ;sMz(8?1x6QA@6-@k-G?Gs75_nkn@3N z1C*i?wP-@thmw6*_CqnsQG*7wB6ri45E)dV4$a8^NV7glP_gR~*$<6qL*B>IB6ktW zP>p)DAm$%T<_fgpo#VAJ&8qkW|!?Yzt234p-GqMlYtd9~@?0QW0 zLnGRdcZ9UaU4$}JqaH2Du{9f@6qTq&6S9t!?BlW@icyXlG@uo^M`=rl460CvW@I0& zSsx{+*wxB@Xha+G9BGle2xX{7Jz9`+jAjFrq7t=eLe{a8eM0s_G0IVc2DBpgIBf}$ zK^5xIjBHo4K1xur>q*%Ujc7yO@zNr95z0`FdbA+t1kDC0MI~y{gsc-K`;_d5Vw9r> z4QNHKr!65es6ri@k$sY8eUzYLS10?S5pBpjSz6>SLK&)2j~3*dqS*kYs6;KAkaa+^ zPs@HNMmcKGfL7$5sx2Whs6ri@k$swGeUzYL*E6yo8qtQl)1^i3B9x&T^=Ltkuh{^l zs6;KAkadP+pOyVkjB?bV0jM>C_^>s z(Sn?_H5;H5m8eA%vd)q0A=wYbC`Sz%(2Cr1wIxIbRj5NVvO~@KC_%-p=VU)Lq78ZH zNsHV?C_^>s(Sn@wH5;H5m8eA%vM!M9^Rgd`QH~lkpcT21wuH!_3Uz2k_Jx}DQG$wH zgY1V!v?1>zX_31KWvE6yT99+GW&@O>618YTRxH^UWIq(695rY_D{?QH)uMcEIHXhYs*(js>e%217Zv>+$ZY=BZ!q83fax?Hj^$$ltCIcm^=R^(ox zEg>?fLLHiseWhl7l%QhQDEpxiZOBWdMeZV$p&IpQLC#g04N!_o)S?MlS4;L~*$>4i zM-3X#irj0oB}4{Qs6#Wdjb?q6pkmi6vL71JhP-Q~MeZV$p&IpQLC$rW4N!_o)S?Ml z*Gu+Q*$>4iM-3X#irh?FLS#^dIy58u2F>~?LB*~~_Cq7ukawfB$X$doRHGg($hk?g z0ZLJcS~MXmm+Wh@ABs_q8Z@94xi@P|hzzPwhh}8oqFEm$sMz(o?1x6QA@5dck-G?G zs75_nkW*+jKq)FwizZ|plPbgG$HFz$-XE1 zp%~?;K?7Qm`!Xh!zqn)OkFie0Phheos^uay?Li%^DY)T0GCPiQtkDJoHm zCS*M++4p5X6r&t9Xh17+pVF2P8C0PT&B*RF>!Sn}yFQTp(1!Sn}yEfSmjc7yObJ8Mr z5z0`FdbA+tdCdkWMI~y{gsefbAIW|wMmcKGfL7$bpe-RXs6ri@k^Q1(eUzYL*T=FS z8qtQlm!w7RB9x&T^=LuPsM!Fes6;KAkoB@;Kau@VjB?bV0jdUK)T2E~1fLyC74$GrAw>TJbTiaQifC|*-ough!Y zK?hKba@3#!t;l^tTS8<|g*r4Nd)BOv5>)K^ywASx5j3I=d2dRK+(jruHR{oVoVPR^ zpcIv;MH8~#mh9)tekevcYS4gIe%217Zv>@j=%?2n%C2G-x zELXCBM)pH7%29&`v?BL-Z3&S<73$E8>=QKWqXZSZ{;ceWMzkUCL}`(`2xX{7Jz9|C zX*NJ9Dp89jWSu10KPUU480Dxz16q-LvbKcCpbB+pM)oP1^-+R~U4LHoLnGRdcR*U? zEM5E)dV4$a6u zTeCh&P_gST%YJA?8}iPP7P*U1hHBKK1v%$xHb5yVQHv&Ig_8X%vLA|3jv6$e6}jhW zONb1rP={t@pRZXTC8*f-S7kpmq78W$NQ>M>C_^>s(Sn>vvjIv`iCQ!v>q5!?HQ5iv zC`Sz%(2CrPv?W9aRj5NVvM<)Gj}lbu`s=bE8qtQlSX$&RLK&)2j~3)yqS*kYs6;KA zkaekK|Ay>`Vw9r>4QNH~W!e%VgDTXa8QF3k)2xpYRP6e@ zvL71JhP>;gMeZV$p&IpQK~ARG0HvrzEt-&ZgJl1n?1y5MqXrFVMedE-5+Z{t)S(&K zH)+;K2`YB|ec2C_W3XN>H)uAIg4cL>uxBN{ie@C_^>s(Sn@YG#j84m8eA%vTm2`Ka%}W zjB?bV0j#8qtQlJEcYLB9x&T^=LuPU78J0ib~X? z30ak7|B38}Vw9r>4QNH~-P#f&gDTXa8QJ$})<+2{cKuV?4~=L;-o4TycM-}^je4{o zr`BwMQdFWAO~|@Wvj0r>Lov!xg9fxB_kL{&kwF#e(2VQ{H0z@T6}$eq?1x6QA+M1Z zxrv75cE7=dlC`Sz%(2CqvTS8<|g*r4N z`w7kZC_%-pe=Yl=5pBqOQd;CLLK&)2j~3)SrP%Pbg zG$HFn$^Hk~55*`)4I0pj+?TW^L2R&H5-o#jgJ-`=JqS$a`5@H)u zzsi1SL>uznmKM2-P=;#MqXjvOW&@O>618YT);p5@Z?YeXQH~lkpcT3AYDR_1|SbG@=c8tF*{ngfdj49xcduU$X&9QHfeKA?pLl{twv?#VAJ&8qkW| z549yk234p-GqN|$`Y1uguKy|fp%HD!`$$^kEe%217Zv>@jQ%?2n% zC2G-xEL*bwNA^Q8%29&`v?BLNZ3&S<73$E8?4va6qXZSZ{;%wZMzkUCXlaqV2xX{7 zJz9|CXf{A8Dp89jWE~^f|0nyQ80Dxz16q-LthR*6pbB+pM)q-<^-+R~UH@P9LnGRd z=Sqv*MJPix>d}In<24(g6qTq&6S7W_>}O;@6r&t9Xh17+Pt=wW8C0PT&B*pN>!Sn} zyS`NRLnGRdcapToU4$}JqaH2DIa#v-N>PbgG$HF0$$pvahhmhY1`TLM?g4EHkwF#e z(2VR;HS41U6}!G%_Cq7ukawE2$X$doRHGg($T?lJ0ZLJcS~MZcm+V)_ekevcYS4gI z8}iPQ7P*U1hHBKK1v!Cc1C*i?wP-@t*^>P# z*$>4iM-3X#irjOwB}4{Qs6#Wd&(*At5>)K^YS|BsXhU8oEpiv34ArPd3v$lWY=BZ! zq83faI$yG1Bm1Ek<)}deT9JE!wuH!_3Uz2kcBEM!C8*f-wXz=?(T2PWrA6){l%X2+ zXhF_Jnhj8jO4OnWSr<$8>tsI^qZ~D8Kr3=%Z3&S<73$E8>`OH3qXZSZzFzi2BifL6 zskF#lgfdj49xceZOtS$>QHfeKAuEyWH^_b{MmcKGfL7#Qt}P)ls6ri@k$r_`eUzYL z*Eh<3Xha+Gu9OzJi%^DY)T0GCsb&L|q7t=eLe^E1{U+HD#VAJ&8qkW|tF92kP>gcapaHGO zyQc$ zABs_q8Z@94xw*E4$e;>!Xh!zUn)OkFie29>`=JqS$h$>aOQMeZV$p&IpQ zK~AaJ0HvrzEt-&Zhh)D?_CqnsQG*7wBKJ;h36Vh+>d=hryEN;g1Qol!TlPaE+K^XC zi`+#hLpAErf}FcG8=w@Gs6`X9?vd>G$bKkBIcm^=R^;BREg>?fLLHisU2E1y2`YAd zuk43Lv?1?4X_31KWvE6yT99+UW&@O>618YT)&r9LKG_e&C`Sz%(2CqfTS8<|g*r4N z`$5h6C_%-p@0b11h&JRsBrS3mp$yfiM+Pbg zG$HF5$^MA!hhmhY1`TLM?z7qwB7-W_p&8k|W_^^PV%Lw#erQA+@(xLh+(jruHR{oV zoaZzfpcIv;MH8}~m+X(pekevcYS4gIrB7-W_p&8jPXx2vwDt7(2?1x6QA@4N|%Hsrl3Epiv34ArPd3vwpS1}H@(YSDzO*ChK>vLA|3jv6$e6}hi#ONb1rP={t@ zzoA(lC8*f-)3P5L(T2QPTI4Q58LCl_7UaCC*#M=eL@k<-^_FCRM)pH7%29&`v?BLy zZ3&S<73$E8>_xLaN>H)uXJtP$q78ZPNQ>M>C_^>s(Sn?JH5;H5m8eA%vfh*I&&hr$ zMmcKGfL7$L+7cpzD%7DF+3#!CM+qu+{k-glMzkUC18I@F2xX{7Jz9|Sp=JY=q7t=e zLe?hPUy%J!jB?bV0j(1H)u zS7kpmq78Y+NQ>M>C_^>s(Sn>~H5;H5m8eA%vW}DNugQKWMmcKGfL7$X+7cpzD%7DF z*~e?vM+qu+{krUjMzkUC1Zk1G2xX{7Jz9`+qGkh>q7t=eLY61l-;n)KjB?bV0jP=z`)Bl~2{`Y1uguHTgX(1gcapaHGOJxyCeWKe}VG$Z?T&H5-o#jf9${m_Uu#5+Z{t)S(&K7irc<2`YB| zq3nl7v?1?eX_31KWvE6yT96ZKHb5yVQHv&IT_V{(lKoJOa@3#!t;oGpTS8<|g*r4N z`!db?C_%+8OZGz}+K`t>i`+#hLpAErf}G1W8=w@Gs6`X9u8{0uvLA|3jv6$e6}eYx zONb1rP={t@r<(Oqf{I;-%YJA?8}hD_7P*U1hHBKK1vyu1Hb5yVQHv&IT_f2eWIq(6 z95rY_D{_stgvg)@b!bNRwVL%&f{Ip)DASc&s zfKpVV7EQ>yS+YmVekevcYS4gI<9~#ky zygQ^t?jn?-8ue&F&YhYKP>M>_q6t}dN%lC|55*`)4I0pj+)7(QWKe}VG$Z?N&H5-o z#V%L&LnGRdcaOBlU4$}JqaH2DxmU9RN>PbgG$E^&?D4W6icyXlG@uo^_i0Or460Cv zW@O*5Ssx{+*mZ*Jheos^?*VC%y9i~dMm<`P(`Yt8DJoHmCS*M**%M_y6r&t9Xh17+ zAJUc(8C0PT&B%UOvpz~tvCEVF(1gcapaHGO?X)FC234p-GqRu7td9~@>^dO(p%HD!dq!I1E%o+10880Dxz16q;$sRb*AixMzkUCHEEH%2xX{7Jz9|Sx@H5Eq7t=eLe?9SJxlgOG0IVc2DBn~)|L<% zRG|*d$bM6^K1xurE0F!rh&JTCB`tCnp$yfiM+ zXhrTj+7cpzD%7DF+3#xBM+qu+og@395pBqOPg>+ILK&)2j~3*tnhj8jO4OnWS?^2s zT-guBC`Sz%(2Cp-v?W9aRj5NVvOmto5DC;Ooo<)}deT9NySwuH!_3Uz2kw)NttFYr-gcapaHGOJwaPSWKe}V zG$Z>&&H5-o#jaTPLnGRd=Shp)MJPix>d}InlQbKk6qTq&6S7X0>?N`vicyXlG@uo^ zr)W!v460CvW@I1Gtd9~@?7CF;LnGRdcdE3=U4$}JqaH2DIZd+xN>PbgG$HGB$zCS= zp%~?;K?7Qm>uXDh460CvW@MkCSsx{+*p!Sn}yRMM^(14QNH~`Pvd9gDTXa8QB+T)<+2{cBQf(8qtQlNLu7B zLK&)2j~3)ysM!Fes6;KAkadw{uaf;xjB?bV0jp}QHfeKA?q^9UL*UV80Dxz16q-rXiJC;s!)e!WM8gX zA0?>RWn@1zq78XhNQ>M>C_^>s(Sn>SH5;H5m8eA%vQo)jEBm1s<)}deT9JE|wuH!_ z3Uz2k_SKs8QG$wH*U5fpL>uz1krug&P=;#MqXjuevjIv`iCQ!v>srZPFZ-bw<)}de zT9JF5wuH!_3Uz2k_Vt?eQG$wHne2x~v>`8(7P*U1hHBKK1vxipHb5yVQHv&I-6+`` zWIq(695rY_D{^nrmJk_Kp$^T+&Nb_!1Qok(l>N|%HsswbEpiv34ArPd3vzDJY=BZ! zq83fax>d3_$$ltCIcm^=R^%4i5+Z{t)S(&K2Q}-X1Qok-*$<6qL*8xDB6ktWP>p)D zAm?_?1}H@(YSDzOQnEM8ekevcYS4gI1) z&H5-o#je|AKQy8Zc@Ij9+(jruHR{oVoQE_UpcIv;MH8|fmhA1aABs_q8Z@94xsPZ| zhzzPwhh}6ys#zZ;sMuA?erQA+@*a~GxryDt1+}9~#kyyk1)5EgcapaHGO9knGy234p-GqPXStd9~@?5bryG@=c8 zuSkpBMJPix>d}InS2Y`;6qTq&6S5}B-Y5H^80Dxz16q;$nzn?!Sn}yBgUKjc7yOA}w+kp$yfiM+d=hr!!_%p1Qoj;ll{<$Hsl>4Epiv34ArPd z3vz7D1}H@(YSDzOBPIK|?1y5MqXrFVMeb4B5+Z{t)S(&KM{Cwc2`YBAvL71JhCD}F zl?0ZLJcS~MZ+M9DrS`=J=+s6hi-k?UzohzzPwhh}7- zq*)&&sMyuXerQA+@=lf(xrTMVhhmhY1`TLMZloW_^^PV%H%1p%HD!yGUB(E`SsAicyXlG@uo^S7=L!460CvW@KNfSsx{+ z*fq+2Xha+GQfZO92xX{7Jz9`+m1YB!q7t=eLe|xieOdNHG0IVc2DBpg8f^)YK^5xI zjBKM>A0?>R^@{9=MzkUCT4|BH2xX{7Jz9`+on`}+q7t=eLe}+?eO2~DG0IVc2DBnK z)0Pk!RG|*d$i6|dK1xurYm)uYh&JTiC@pdqp$yfiM+XhrVL+7cpzD%7DF*|%ucM+qu+y)OHq5pBr3Ra)dOLK&)2j~3(XhrUA+7cpzD%7DF*|%%fM+qu+&9WaF(T2QITI4Q58LCl_7UbNa z*#M=eL@k<-b*E(Cl>JbQa@3#!t;oGgTS8<|g*r4NyV9(W5>)JZOZGz}+K_j*w8&kA zGE}1;Ey%e?vjIv`iCQ!v>t4yeE&HJu<)}deT9I38ONb1rP={t@-=|q0C8*f7$bM)< z8}ja#7P*U1hHBKK1vw9BHb5yVQHv&IHIjWt_CqnsQG*7wBKJXU36Vh+>d=hrhcxS> z1Qom9mHp6&Hsn1lEpiv34ArPd3vwROY=BZ!q83fadQ`IS$$ltCIcm^=R^&dWEg>?f zLLHis{kUd*l%QhQD*K@kZOCh-MeZV$p&IpQLCzDJ4N!_o)S?MlPfGTE*$>4iM-3X# zirlBPB}4{Qs6#WdJI(qiLB*~QWIr^b4S7#Xi`+#hLpAErf}CeG8=w@Gs6`X9o|Wu} zvLA|3jv6$e6}i2(gvg)@b!bNRA9mO%PeVRI3ah2i@#S@Cx6xQqVT6xd`6r&t9Xh17+-_Vv2 z8C0PT&B&fL>!Sn}yFTx;?|TG|XhYtc(js>e%217Zv>@j#%?2n%C2G-xthXim`LZ91 zQH~lkpcT1`wuH!_3Uz2k_B)#OQG$wHUm*LT5pBqOS6bvQLK&)2j~3*-r`Z6ds6;KA zkhMzo3uQkPqZ~D8Kr3?J*Om|&RG|*d$o@dHK1xur>x*PRG@=c8A4-edMJPix>d}In zO|t4QNH~$J!DigDTXa8QGs`)<+2{c72KLhyIuc`i=uw z{_{KDeZAG2z17=$w70Lf_uhN7cfI!ZZhO~jZ{Gz$5X26GAP9mW_#y~`Ac!3VK@bE% z5Cr{w^7wsT|2_Zsyx;leJ)#YH*7%YCkh=&ORHGg($T>i>0ZLJcS~MZ+K*@fr?1y5M zqXrFVMeae`5~2)Ms6#WdZO!^9LB+0*ll{<$Hsl>FEpitjgKE^H1v!UkHb5yVQHv&I z9V*$6m;F$Ta@3#!t;lt>B}5sjP={t@AEsF!C8*f-39=s=(T2RkrA6){WKfNIv>@jQ z%?2n%C2G-xELXChDEpxp<)}deT9JFCwuC4{73$E8?4va6qXZSZ{+;ZHMzkUCXlaqV z2pLqP9xcf6G#j84m8eA%vW}7LC&_*&MmcKGfL7!lt1ThQP=z`)Bl|eb`Y1ugu1}Wz z(1gcapaHGOJxNEbC`Bb|(S)p1CHrZzABs_q8Z@94xq-HX zC_@$M(2VTUH0z@T6}vuN_Cq7ukaxPY$X$dCs!@*?4iM-3X#irjOxB}5sjP={t@pQl+LC8*f-S+XA*(T2QOTI4Q52GyuX3v$la zY=BZ!q83fax_oFZN>H)ub7Vg>q78W$NsHV? z$eM>_q6t|y zOZH1-KNO=JHE2L9a!YLqQHCnip&8k?Xx2vwDt3LT?1x6QA@5dck-G>PRHGg($hl3k z0ZLJcS~MZ6lI)ksekevcYS4gI4iM-3X#irl-kB}5sjP={t@-=kR{C8*f-m9ifi z(T2Q6TI4Q52GyuX3v%w&Y=BZ!q83fax=*rSCHtWm<)}deT9JFdwuC4{73$E8><2XK zqXZSZzFPJ}BifMnptQ(cgbb=tj~3)Sq}c$as6;KAkoB-+zee^$G0IVc2DBo#)s_%t zs6ri@k^P8feUzYL*MF4#(1lNHR{oVoM$x~ zpcIv;MH8}~lk7LhekevcYS4gI4iM-3X#irh(CLX@Ejb!bNR%bN93f{I<=Ec>Am zZOD5?TI4Q52GyuX3vyo7Y=BZ!q83fankD-!vLA|3jv6$e6}hizONcU5p$^T+eqFOZ zN>H)uKg)h-L>uznkQTX%kU=%-(Sn>svjIv`iCQ!v>rKgitL%qjl%oa>XhrT@+7hA+ zRj5NVvftLMj}lbu`Zn1Qjc7yODlKvsA%kkvqXjwdXf{A8Dp89jWW6idZR^&PSw8qtQl_oYSdB4kjFdbA+t1I-2~MI~y{gscxG z`<=2MicyXlG@uo^)(anP2~mbB)S(&K2WZwu2`YAdm+Xf|v?1?6X_31K8C0VlEyy`Y zvjIv`iCQ!v%a-hS%YG618YT)?t$UUfB=DC`Sz%(2Cr{wIxIus!)e!WFMhfA0?>R^?kA* z8qtP4S6bvQLI%~SM+280Dxz16q-Lw6=sOLlx@KjBHP{ zK1xur>jz{%G@=c8$4HCZMaZBU^=LuPv6>A~ib~X?30cQU_6KD@6r&t9Xh17+kJpwE zWvD_Onvs2iW_^^PV%HDJerQA+@=lZ%xr>lNHR{oVoRc&gpcIv;MH8}o$^NkHhhmhY z1`TLM?#bE`q6}52Lo>2Z(X5XWRP6c@*$<6qL*A*p)DAm>cY z1}H@(YSDzOvn2cDvLA|3jv6$e6}e|?ONcU5p$^T+jx_6|1Qok}LiR%=+K_jSw8&kA z460F&7UZ0(*#M=eL@k<-b)IB@QuaeJ%29&`v?4dwmJnsALLHiseZFRWl%QhQPsx60 zL>uxhkQTX%kU=%-(Sn={H5;H5m8eA%vJ%PuwCsmsl%oa>XhrTt+7hA+Rj5NVvM<)G zj}lbu`We{|jc7yOCDI~y5i+PoJz9{HYBoSADp89jWL+xRpOyVkjB?bV0jM>_q6t}rWPe%qLov!xg9fxB_eO0AQHCnip&8jXY1T&xDt7&f?1x6QA@62sk-G>P zRHGg($SE}&pcIv;MH8}ak?gO^ekevcYS4gI(B6kros75_nkaN3c1C*i?wP-@t9g_VovLA|3jv6$e6}fk6ONcU5p$^T+t~KkU z1QomftL%qHv?1>mJGey6lHyl%oa>Xhm+LEg{NK zg*r4N`(DlZC_%-p-;n*#h&JTiCoOUpA%kkvqXjwlYc@bBDp89jWIZ6+|0esP80Dxz z16q;$ptgi4Llx@KjO>Rr>!Sn}yM9ylLnGRd_pr3cU4#s(QI8hnw3-c2ib~X?30aRw z_P@)1C`LJI(12FtKB_Gt%20(mG$Z>l&H5-o#jgJ$`=JqS$m^sP*kABs_q8Z@94xld|Kh%!{64$a8!HS41U6}x_0_Cq7ukoT0d$X$dC zs!@*? z8}go$7P*U%K{e{pf}H0y8=w@Gs6`X9M#=u3?1y5MqXrFVMeYmQ5~2)Ms6#WdU(~FR z5>)K^ec2CeGN?v9T97koHb5yVQHv&Iy)4;3ko{1Ma@3#!t;l^vTSAnf z3Uz2k_N$upQG$wHe<=H*5pBqurA6){WKfNIv>@j-%?2n%C2G-xtk)&`N3tJ^QH~lk zpcT1qXiJDPRG|*d$X+z-qXZSZ{#f=yBifMnrnJaigbb=tj~3*-rP%d}In_cR-z z6qTq&6S6kR{+aBDVw9r>4QNH~``Qws3{|K@GqOL>td9~@?E0Uw9~#kyybq;C?jmGR zje4{o$9nOj*#M=eL@k<-b%135m+XgPl%oa>XhrUU+7hA+Rj5NVvJcX%j}lbu`roo2 z8qtP4TUz8ULI%~SM+80Dxz16q-LsJ4VCLlx@KjBH1< zK1xur>n~(KG@=c8he?avMaZBU^=LuP;hGIlib~X?30X%-_W#I!C`LJI(12Fty4n(= z3{|K@GqR7=td9~@?D|XD4~=L;-ciybcM&qEMm<`PbF^jyl%f)~XhN1J+5ap1p%~?; zK?7QmdyKY(C_@$M(2VS3HS41U6}$eQ?1x6QA@4Y8k-G>PRHGg($T?oK0ZLJcS~MZ+ z1j+uD?1y5MqXrFVMed2(5~2)Ms6#WdPtvT95>)K^YuOKtXhWVaEpitjgKE^H1vw{c zHb5yVQHv&Iog&%4k^NANa@3#!t;ju9TSAnf3Uz2kcA!}wC8*f-x3V7^(T2R!q($x` zWKfNIv>@kn%?2n%C2G-xtTQD0cd{RfQH~lkpcT2HwuC4{73$E8>@zj%qXZSZ{$BP& zBifL6mbA!Sgbb=tj~3*dt=Ryjs6;KAkQGVxA7noiqZ~D8Kr3?3(UuTps6ri@k$tXa zeUzYL*FVaBXha+G&XX3oi;zJz>d}InShE32QHfeKA?tj}{*&y7Vw9r>4QNH~1=Rb)f8rMzkUCQfZO92pLqP9xceZOtS$>QHfeKA?tF< z9whsr80Dxz16q-rX-kMQRG|*d$i70eK1xur%a;Anh&JS1DJ^mrA%kkvqXjuvX*NJ9 zDp89jWEsgGEc>At<)}deT9JFTwuC4{73$E8>}xdZqXZSZ4w3!Ph&JS1D=l&tA%kkv zqXjv+W&@O>618YT)^(CSRQ5wL%29&`v?BL)Iu zT=qjF+K_jPw8&kA460F&7UbNj*#M=eL@k<-b(>_5ko{1Ma@3#!t;nskB}5sjP={t@ z->z97C8*ft%6@1>8}jau7P*U%K{e{pf}A@w8=w@Gs6`X9YRMic`=J=+s6hi-k$ac6 zgeXH5>d=hryEW^h1QolElKs$#HsswSEpitjgKE^H1v!mo1C*i?wP-@ty^=jz_Cqns zQG*7wBKJOR2~mbB)S(&K_iNTi2`YAZvL71JhP(%)MeZVGP>p)DAm>5N1}H@(YSDzO zha`K9?1y5MqXrFVMef7e5~2)Ms6#WdTh00?LB+0PWj{2c4SA19i`+%Xpc?gPLC&L^ z4N!_o)S?Mlk4g48*$>4iM-3X#irh|HLX@Ejb!bNRd=hrr#0)N1QokZl>N|% zHsn1cEpitjgKE^H1v!Ie1C*i?wP-@tvyweY_CqnsQG*7wBKJ9M2~mbB)S(&K&ui94 z2`YB^vL71JhP+W)a13hh}8Irdb~)sMrlNHR{oVoHsNZpcIv;MH8|X$(|7y_3QG$wHXUTqOL>uxB zkQTX%kU=%-(Sn=eGN?v9T99+7W&@O>618YTmLu77WIq(695rY_D{>FhmJnsALLHis zeYj?Ql%QhQxw0P`(T2Puq($x`WKfNIv>?aTY=BZ!q83faI#ROd$$ltCIcm^=R^%R~ zEg{NKg*r4N`)JMjC_%-pSoT9B+K}f-i`+%Xpc?gPLC!In4N!_o)S?Ml$4d5m*$>4i zM-3X#irnM0B}5sjP={t@AFo*-C8*eSf$WDyv?1>VX_31K8C0VlEyy`hvjIv`iCQ!v z>mH&Yk^Rt!HsqZmEpitjgKE^H1v#f` zHb5yVQHv&I1(Ll;_CqnsQG*7wBKI_H2~mbB)S(&Kr)$AmZOA)ATI4Q5 z2GyuX3vxou1}H@(YSDzOGbMY8?1y5MqXrFVMebSJ5~2)Ms6#Wd&(^Gu5>)I;Wj{2c z4SA8Y$X$dCs!@*?PRHGg($hknX0ZLJcS~MZ+Ldjk(`=J=+s6hi-k(+2sh%!{6 z4$a8ENV7glP_ZkM{m_UuZC`Bb|(S)okBzu+Y zhhmhY1`TLM?v>gSq6}52Lo>3k(yWgXRO~Xc9~#kyJR>b~7a@ac)T0GCS8FyvDJoHm zCS+YB*{fwg6r&t9Xh17+uho_iWvD_OnvtDr)<+2{c3mU;p%HD!yG~ld}InO0xk!Sn}y9(J4jc7w&EiG~vA%kkvqXjv4X*NJ9Dp89jWZf;<8)ZKfqZ~D8Kr3?Z(UuTp zs6ri@k==5pBr3S6bvQLI%~SM+Rb*t=$MzkUCF=>&z2pLqP9xce}G#j84 zm8eA%vL2W0ZL%MVQH~lkpcT1KXiJDPRG|*d$bM3@K1xurtCIcDh&JT)(js>eGN?v9 zT9EUUW&@O>618YT*3*)`UG_sU%29&`v?BKzZ3$6^D%7DF*@I?%l%QhQ9kL%9(T2Qd zrA6){WKfNIv>@j>%?2n%C2G-xtmh?rr|gGfl%oa>XhrU*Eg{NKg*r4N`vuMVC_%-p zTJ}RD+K~66w8&kA460F&7UaC7*#M=eL@k<-HA(g^*$>4iM-3X#irkmAB}5sjP={t@ zzoJTv?1?RX_31K8C0VlEy$TQ8=w@Gs6`X9UX$!SvLA|3jv6$e6}hi# zONcU5p$^T+enYc9N>H(@k^Rt!HsmeRB6kros75_nkn^Ty1C*i?wP-@tTavw3_Cqns zQG*7wBKK`=2~mbB)S(&Kt7d(apkmj3vL71JhP-#AMeZVGP>p)DAm?4p1}H@(YSDzO z_auA2?1y5MqXrFVMee38A<9sNIy58uea-qPLB*~IWIr^b4S63(i`+%Xpc?gPLC%Mo z4N!_o)S?Ml*7T9@J}CR480Dxz16q-LfVPAvLlx@KjO+t7>!Sn}yB?DL(1R)yaNnL>uysl@_^+kU=%-(Sn@gG#j84m8eA%vW}PRj~Kpjc7yONzx*B5i+PoJz9|CYc@bBDp89jWSuP8 zCuKhrqZ~D8Kr3=j(UuTps6ri@k$tLWeUzYLS1@j+%?2n% zC2G-xtkWg?lXhrTB+7hA+Rj5NVvO~@KC_%-pr)57hq78XxN{ie@$eH)u zIoS`5XhYtG(js>eGN?v9T9A`yHb5yVQHv&IT_oA(Wj_?795rY_D{?Q^mJnsALLHis zeTim$l%QhQDEpxiZOBWdMeZVGP>p)DAm>ue1}H@(YSDzO%Ov}P?1y5MqXrFVMegO= z5~2)Ms6#WdGtK%aLB*~YWj{2c4S82ci`+%Xpc?gPLC%$$4N!_o)S?MlS4s9I*$>4i zM-3X#id>^DA<9sNIy58uYR&p6LB*~~_Cq7ukavx=$X$dCs!@*?a13hh}77uUQ`@sMz(2?1x6QA@2rhk-G>PRHGg($SE`% zpcIv;MH8}ali&H5-o z#jZv6LnGRdcek|2U4#s(QI8hn+@sk5rKm(Lnvm5<_D$Ij#VAJ&8qkW|d$lD*8LCi+ zW@O)|Ssx{+*!7m|heos^?|x~Ky9gOnqaH2Dc|fxPN>PbgG$HFj$-XW7p%~?;K?7Qm z`;fMTC_@$M(2VSdHS41U6}wj14~=L;UMnqf7a@ac)T0GCk7zbPDJoHmCS*M-*>_|= z6r&t9Xh17+AJdi)WvD_OnvvaU)<+2{cD*b6p%HD!dt6%NE^-+R~T_4DPXha+Go|hK6 zi;zJz>d}InQL_O`QHfeKA?pRnekl8)80Dxz16q;$qPB!6Llx@KjO>>*>!SqSDEj9g z^UuEjLB$J-_Z7!XAH6w8akb(u#Z!tm6^Fh2(bQ>*OBJ^$9#OokuwIeZ%7czaG0IVc z2DBpgRc#4ThAPyd8QHUDeUzYL*T4A4`yN0e+K~5}w8&kA460F&7UaCH*#M=eL@k<- z^@e2srR;}dl%oa>XhrU#Eg{NKg*r4N`%TUIC_%-pelNHR{oV98a?WN>Pbg zG$HF4$$paThhmhY1`TLM?y=euq6}52Lo>3E)2xpYRP6d>*$<6qL*DVyB6kros75_n zkaL1&1C*i?wP-@tiIV*k*$>4iM-3X#irka5B}5sjP={t@`H)u z(`7$2q78YcON-n^$eXhrUs+7hA+Rj5NV zvd_}2j}lbu`V83*jc7yO+0r6+5i+PoJz9_xX*NJ9Dp89jWSt|~&y@X8jB?bV0jGB4kjFdbA+te9Z!Sn}yFN$uLnGRdcagNnU4#s(QI8hnT&&purKm(L znvivgWdDQghhmhY1`TLMZmKOI%20(mG$Z>`&H5-o#jekl{m_Uua13hh}77saYQ-sMz)SvL71JhPp)DAjfDnKq)FwizZ}UE!i)S{ZNc@)Sv;a$h}5eLX@Ejb!bNRwVL%&f{I;V zDEpxiZOF@|MeZVGP>p)DAm=*G1}H@(YSDzO>m~a|vLA|3jv6$e6}dNPONcU5p$^T+ zE;Q?-1Qol!SoT9B+K_jnw8&kA460F&7UbNd*#M=eL@k<-b+cr@MD{~5%29&`v?90E zmJnsALLHiseT!y&l%QhQm&$%uyMl@_^+kU=%-(Sn@YG#j84m8eA%vMR}bne2yR zl%oa>XhrVr+7hA+Rj5NVvhUEWj}lbu`f}M1jc7yOozfzA5i+PoJz9`cYc@bBDp89j zWZfm%uaNyvjB?bV0jM>_q6t|KOZIDIKNO=JHE2L9a$9W)QHCnip&8kaXx2vwDt7%x z*$<6qL*Ap(B6kros75_nkn@;k1C*i?wP-?CC)xib`=J=+s6hi-k^8u|geXH5>d=hr zCp7D$1Qol!R`x?9+K~68w8&kA460F&7UcAr4N!_o)S?MlPf7OcWIq(695rY_D{`OK zmJnsALLHis{fuUPl%QhQ*UNrrL>ux3X_31K8C0VlEy#IRvjIv`iCQ!v>p97OgY1W5 zl%oa>XhrVx+7hA+Rj5NVvPaGOC_%-pZR_06&$8qtQlSENPmB4kjFdbA+t zRm}z{MI~y{gsfSz-y-{=80Dxz16q;$nzn=}Llx@KjO^Dn>!Sn}yZ*E6heos^?+s~@ zy9gOnqaH2DSu`7<6qTq&6SCfv?6=B(C`LJI(12FtzNIZ8%20(mG$Z?M&H5-o#jbCY z{m_Uua13hh}7N zn)OkFie29!`=JqS$a`N}eUzYL*LTT&Xha+G4wM$Ti;zJz>d}IngESkU6qTq&6S8c{ez)w0 zVw9r>4QNH~!P*j{3{|K@GqMlStd9~@?D`(r4~=L;-l5VWcM&qEMm<`P<7hTODJoHm zCS)BZ+3%J8P>gcapaHGOJzQHtl%WcBXh!xCn)OkFie29)`=JqS$aAGd?jmGRje4{o z=Sa;4C`Bb|(S)p{B>VlcABs_q8Z@94xkqbDh%!{64$a8+H0z@T6}x^w_Cq7ukavu< z$X$dCs!@*?v?1?AX_31K8C0VlEyy`ZvjIv`iCQ!v%a`mA%YG618YT)@hRcQP~g0C`Sz%(2CsC zwIxIus!)e!WS^l~A0?>R^<%Oh8qtQlP+H_JLI%~SM+nCJCG@=c8=SYj(MaZBU^=LuPxta}7ib~X? z30db!_9taO6r&t9Xh17+V{HjhhAPyd8QJG+)<+2{cKwv>heos^?*eI&y9gOnqaH2D zxlpqKN>PbgG$AXI>`%*nC`LJI(12FtUZgD{%20(mG$Z?B&H5-o#jc-`{m_Uua13hh}77u2~-?sMz&$ zvL71JhP+H#yQnEiU`=J=+s6hi-k$aW4geXH5>d=gA zqgfv%sMz%jvL71JhPp)DAm# zgeXH5>d=hr>on`51Qok}N%lh{+K_j>w8&kA460F&7UbNZ*#M=eL@k<-RY>-iWj_?7 z95rY_D{^ntmJnsALLHiseUoN=l%QhQugHFAL>uyMmKM2-kU=%-(Sn>(vjIv`iCQ!v z>lVrWs_chil%oa>XhrU=+7hA+Rj5NVvTxI@j}lbu`Zd`Pjc7w&B`tCnA%kkvqXjv) zYc@bBDp89jWZfaz|04UL80Dxz16q-Lr?!MBLlx@KjO<#oK1xur>%Yo=Xha+G?vfU{ zi;zJz>d}InyEPl26qTq&6SD4+?61pyC`LJI(12FtHrf)R3{|K@GqUg1td9~@?D`Ga z4~=L;-hI*{cM&qEMm<`PbH8Q-l%f)~XhPNllKpS8ABs_q8Z@94xesbfh%!{64$a7Z zNV7glP_gSbWj{2c4S5esi`+%Xpc?gPK~AgL0HvrzEt-(^h-Ck}?1y5MqXrFVMed{8 z5~2)Ms6#WdAJeRl5>)K^AF>}B(T2QETI4Q52GyuX3vwRUY=BZ!q83fadP1_lCHtWm z<)}deT9NytwuC4{73$E8>|V1zN>H)uw`D&xq78XZNsHV?$eM>_q6t}VOZHD>KNO=JHE2L9a#w8$ zQHCnip&8llXx2vwDt7&;?1x6QA@5yjk-G>PRHGg($azn*0ZLJcS~MYRlkA_#ekevc zYS4gIU&H5-o#jgJ?`=JqS$g`zI?jmGRje4{o z=U~kSC`Bb|(S)o+B>U&GABs_q8Z@94xrb^?h%!{64$a7RH0z@T6}$dI_Cq7ukaw80 z$X$dCs!@*?N|%Hsl>8EpitjgKE^H1vy7+Hb5yVQHv&Id6NCVvLA|3jv6$e6}iV~ONcU5p$^T+ zK320nN>H)u|H*!6L>uyslNPy)kU=%-(Sn@gH5;H5m8eA%vQCifU&($bMmcKGfL7$5 zs4XGNP=z`)Bl{%H`Y1uguD_Q3(1M>_q6t}%WdA|-Lov!xg9fxB_Z)2rQHCnip&8ldYSu>yDt7&&?1x6QA@4kC zk-G>PRHGg($cZ%@pcIv;MH8~lm+U{uekevcYS4gIM>_q6t|SOZEWS55*`)4I0pj+)K12L>a13hh}7_ zn)OkFid_fFerQA+@-CGYxr>lNHR{oVoXa#DpcIv;MH8|vm+V2ZABs_q8Z@94xtX?v zC_@$M(2VRWH0z@T6}xQN4~=L;-j&iKcM&qEMm<`PbCqTTl%f)~XhN2e?7^}hicyXl zG@uo^S8Gd%GE|`s&B(q+vpz~tvFi}o4~=L;-nG&qcM&qEMm<`PlWR6WDJoHmCS+YF z*+XSN6r&t9Xh17+uh*6kWvD_Onvs2jW_^^PVwWTPp%HD!E2Ks4B4kjFdbA+tM$HB& zMI~y{gsht+dzkEpVw9r>4QNH~&Ds*83{|K@GqOv~`Y1uguES+NG@=c8w@8cJMaZBU z^=LuPt(px`ib~X?30b#E_6XSz#VAJ&8qkW|N?Ssdp$c_qM)vKR^-+R~U9RkhMzkUC z4r!6Q2pLqP9xceZQ?mg|QHfeKA*+_`k+L6(QH~lkpcT1yX-kMQRG|*d$i7>%K1xur z>nPa|jc7yOJ<=j~5i+PoJz9{{Xf{A8Dp89jWZf&-qh&u7qZ~D8Kr3?Z)0Plrs6ri@ zk$t~reUzYLmnZw75pBqOKw9K3LI%~SM+Rb-e6{MzkUC32BkL2pLqP9xcduQnLX{QHfeK zA*+|{39=uGQH~lkpcT1KX-kMQRG|*d$bMS0K1xur>qOZPjc7yOGtwe=5i+PoJz9`6 zXf{A8Dp89jWIZd{lVm>>qZ~D8Kr3>e)0Plrs6ri@k^Q`8eUzYLmoNLF5pBpDrA6){ zWKfNIv>@jN%?2n%C2G-xtQRGFvh0Uql%oa>XhrTz+7hA+Rj5NVvM0^@C_%-pQ)E9h zq78X3ON-n^$eH)ublDG$XhYuH(js>eGN?v9T9C79Hb5yVQHv&Iy(8H(WIq(695rY_ zD{|k}mJnsALLHis{hnrhl%Qf)DEpxiZOGfCMeZVGP>p)DAm@F}1}H@(YSDzO4d}In12r3< z6qTq&6S5AH?Afv(icyXlG@uo^wzh;QLlx@KjO>Fo>!Sn}yCT^Sjc7yOA<`mu5i+Po zJz9`+sAdC{q7t=eLY5=hb7VghqZ~D8Kr3<&)0Plrs6ri@k$t#keUzYL*SWGE8qtQl zBcw&{B4kjFdbA+N)og%LRH7D5$U0K8=gEF3MmcKGfL7!lr7a=KP=z`)Bl~F0`Y1ug zu2}X%BifMXNsHV?$eRb%E@MMzkUC1Zk1G2pLqP9xcc@QL_O`QHfeKA?qZ`UMTya80Dxz16q;m zYfFeSRG|*d$Ua%KK1xurE0O)sh&JS%A}w+kA%kkvqXjvqYBoSADp89jWCfDFNcKZ9 z%29&`v?BL3Z3$6^D%7DF*{5sPM+qu+T`c>d5pBpjLt5l6LI%~SM+XhrT>+7hA+Rj5NVvd`A6j}lbuN@YJZq78YGw8&kA460F&7UZ0x z*#M=eL@k<-b*^MDmHkkRa@3#!t;ju3TSAnf3Uz2kcC1++C8*eSne2x~v?1?&X_31K z8C0VlEy%e*vjIv`iCQ!v>q5z1F8iSv<)}deT9KP*ONcU5p$^T+zDTn^N>H&Yll{<$ zHsoC_EpitjgKE^H1v!^!Hb5yVQHv&IrINiu_CqnsQG*7wBKJ~l2~mbB)S(&Kmuc2V z2`YA7Df^)jZOFS^TI4Q52GyuX3vx2e1}H@(YSDzOD)ImvL71JhCCxJau*?kYSg0zIag~oKq)FwizZ}UBiXBEKNO=JHE2L9 zayL9*A% zekevcYS4gI2()U1yZRP4%SKQy8Zc{fRm+(pQs8ue&F&dr()P>M>_ zq6t~0WUrI`P>gcapaHGOy+vC>l%WcBXh!y}n)OkFie1;serQA+@@|tBxr>lNHR{oV zoJz9+N>PbgG$HGD$=)FQp%~?;K?7Qmdxy4!C_@$M(2VRmHS41U6}t-A4~=L;UM($h z7a@ac)T0GCcWE|2DJoHmCS=_$*&Ag)6r&t9Xh17+@6nbJWvD_OnvvaT)<+2{cHJcV zp%HD!yH{G|E# z&H5-o#jaBJLnGRd_mH&6U4#s(QI8hnJgnIOrKm(Lnvm5>_7>R>#VAJ&8qkW|N3}|3iicyXl zG@uo^PiRYsGE|`s&B%UIvpz~tv8$5((14QNH~s4XGNP=z`)Bl`u-`Y1ugu3Gj(BifMnqO{0egbb=t zj~3*-q}c$as6;KAkTps6F4+&oC`Sz%(2CrbwIxIus!)e!WWSRb+_z?MzkUC zRcVpC2pLqP9xce3H5;H5mFWNTK<9A)%m01H+x0%zW9@pb>$!GoyRFxHuIt*Z-FmLq zww~*;-q(6>y@DVJ;tql!2!bF8f*=TjxPu@Ff*=UK2=@Er;q&_M`N!w|&NuH4&B%I9 zviHb-C`JWp(TEIkU)PopWvE6yT9EyQW_^^Pa#t(+p$TosTct(rB9x;B4QNHqo0<(! ziYnBh8Ch>h_FmZ!#i&3n8j(Tn+u9PM4ArPd3$l%7eUzYb*L|`dn$U*4ccew`B9x;B z4QNHqyP6G9iYnBh8Cma1_I}w9#i&3n8j(TnrY#}LP>p)DAp3pI`Y1u=t_Ng4G@%W7 zA4rSbMJPuN8qkWI4>cR06ji80GqSALKK9)QWj_?70<~yF2Dt}lONcU5qaH2DK2Wnh zN>I7$A=wX2XhYsX(js>e%29&`v?9mWY=BZ!p$^T+I#{v~%YG62KrI@P zLGBUS5~2*%s7DL3UCsI^LFKMTWj{2b4S7dOi`+#hM-3X#ikzb~8=w?bs6#Wdj+X3W zvLA|3fm$>ogIrHrLX@Ez^=Lu%F`D&Jg34XJ?1v__A@5jek-G@xs6hi-k#n481C*i) zb!bM`@sfR9_Cql$P>V)nkb8o*geXHb>d}Ji6E*9j1eLpd=g=lO_A4?1y4hpcakDAomn)2~mb>)T0I2r)t(m2`YCDvLBkzhP*&p z^10ZLJYIy58eY{@<&`=J;Ws6`_($c?lmL>a14j}~N~ zqgfv%sN6NmerQ4)^3IhOxrs(Sqy?H0z@TmAjsk{m_IqTMVhhkKq z7LCXt_hM}cQHE;NqXpTQXx2vwDtAq?ADYmHyi{7`Ec%Hq7fP7Ual=6%217Zv>-dvtd9~@?s`%7LlfGNcZIabU4(MfpaHGOxl*$M zN>PP6G$ZRO$-X4}p%@jYMI$oE&9x;&8LCl_7Gz(oSsx{++%?O7XhIwEu8|hGi%^al zG@unZ*J?IEDXLJ1W@HtTeOdNHF)C1tMr4qCowkH1LpAErg6!)x>!SpfyIzs~(1bSR z-5@P;7oi+AXh17+O3el+MHTAMjI0|a`>O1RVpO0OjmRMPCT$5(hHBKK1=%-i)<+2{ zcP+9Xn$U*4N?PPDLOE*CfL7$(qS*kYs6ri@k#(zNUz7b%j0)7E5gFv(rY#}LP>p)D zAiLJAj}lbwdR_KI6WWk>yR^t%gmToN0jVwaR{ILL2h#mKM2-P>vcjpcOgyXf{A8s!)e!WVMogQ}#nK zDo~3?WRQEWwuC4{HR{oV?E5t9qXd<^-je;$gf`^eFD-Hxp&T`6Kr3<{&}@KGRG|*d z$a+w+Z_9otMg?lohzxQc(v}cqs75_nko~Y`eUzYbmy!L@gf`@L(js>e%29&`v?Avb z%?2n%73$E8tVbpLj_ikGRG=1($RPJIZ3$6^YSg0z*}Z0cl%R6gyRsje(1yInrA6){ zl%oa>XhqHwnhj8jD%7DFSx-v#J=qV%s6Z_mkwNaDEg{NKje4{o`zg)(C_&|}P4+_* z+K~6Ow8&kAa@3#!t;l&svjIv`g*r4NYn1H!vLA|3fm$>ogWPAeB}5sjQI8g6Kc`tA zC8*r>f$WDSv?1?#X_31K<)}deT9GqpHb5z=P={t@y&%~SWj_?70<~yF2DvY4ONcU5 zqaH2Deo3=FO3;m>kN?z<`+)})FDTwu95a7(bB^L_#a)W06mKdHd-V)nko&5(geXHb>d}JiMYBFiP`T?Lee8V?pb2frdrey8E3BWIsvvLoq5)i$-LS`;NARC_^>s(Sq!EHS41U zmAgJ!_CpiekoTUn$X$eT)Sv;a$k{X-pcGZ8Lo>48m+Ys=ekeu-YSD-cazD_P5M`)F zJz9|cp=N!QpmNuz%6@1<8}h8zKlUGT7oi+AXh17+4$y3XQdFT1&B!`XvY#gVp%@jY zMI$oEJxE(Zl%X2+XhF8ESsx{+-1X_QADYmHyo04h?jn?<1`TLM&LNr&P>L$lp&40+ zO7=5kKNO<^wP-{JxsJAkC_^>s(Sq#5H0z@TmAgJu_CpiekaxJW$X$eT)Sv;a$T>o@ z0ZLJYIy588mF#E9ekeu-YSD-ca*x!O5M`)FJz9``lxBUDpmNt|%YJA=8}g2p7P*U1 zjv6$e6*-<}1C*i)b!bM`F_QhqvLA|3fm$>ogWO}aB}5sjQI8g6AE#L#C8*r>IkF#` z(1yI@rA6){l%oa>XhqHmnhj8jD%7DFStm;Nb7emiqXM;PLT6WWk>vb4xugmToN0jd=g=OCogWObGLX@Ez^=Lu%rJD6og34WACi|fY zZOFS!TI4Q5Icm^=R^(i+*#M=eLLHisl}Yx?Wj_?70<~yF2Dw*gONcU5qaH2DzEZP3 zN>I7$pUHk`LL2g~k`}p(P>vcjpcOf}W&@O>3Uz2k*42{z3fT|Es6Z_mkwNY?+7hA+ z)u=}cvai*wj}lbw`scDAn$U*4LR#c5LOE*CfL7#Or`Z6ds6ri@k#)Ufzf$%?F)C1t zMr4qCgSLbyLpAErg6vYWK1xuz>#JlxG@%W7H%g1#MJPuN8qkWIn=~7s6ji80GqP@$ z>{rWvC`JWp(TEIkD{To;hHBKK1=+V~)<+2{cYTfQhbFWk?^bD%y9ni|K?7QmbDL%Z zl%fiCXhv2o*{_xTP>c%Hq7fP7-mWbn%217Zv>^Kq&H5-o<*u)j{m_IqOL9KNO<^wP-{Jxp!+zh%!{89xceeN3%XkP`T^tWj{2b z4SB7!$X$eT)Sv;a$hlXu0ZLJYIy58eKFNNA?1y4hpcakDAoqT42~mb>)T0I24`|j$ z2`YE}OW6-iXhYtE(js>e%29&`v?Avr%?2n%73$E8tcNB0uVg_;@~qXd<^zESo=6WWmXsIQH44*BdeF}H_3h|Mg?lo zhzxQc*Om}vs75_nko|;aeUzYb*Eh?4XhIwEo|G23i%^alG@unZgJuJiq6&3rM%Gi3 z{nxS|icx`DG$MoCr?n+S8LCl_7Gyu8Ssx{+-1To{KQy5Yd84$*U4(MfpaHGOc~-Ll zN>PP6G$ZRd$^Ki}55=fJEgF$Q?(^Cbq72ojM+>qi&H5-o<*sj${m_Iqv*au=Z- zHE2L9a$eMIfKpVU4$a7VNwVK6`=J;Ws6`_($epz%L>a14j}~OVtXUr=sND5!vLBkz zhP+p#MeZV$qXrFVMb4|54N!_I)S($!i)6oD_Cql$P>V)nko%gpgeXHb>d}Ji*EQ>- z1eLqKL-s=x+K~5#w8&kAa@3#!t;kt58=w?bs6#Wd-jwXWll@SP3e=(z8RWjDEg{NK zje4{o`)$qoC_&|}@09(}gf`?EX_31K<)}deT9NaPW&@O>3Uz2k*1MAZF4+&os6Z_m zkwNZz+7hA+)u=}cvNz58C_&|}@0R`0gf`^8FD-Hxp&T`6Kr3=S&}@KGRG|*d$of#S z-y{2>7!{~RBQnUf-uS2`L>a14j}~MfpjjU!sND6vvLBkzhP(r%MeZV$qXrFVMb1H* z4N!_I)S($!wq(Cg_Cql$P>V)nkbAJUgeXHb>d}JiLp1B71eLq~z3hi3v?1?MX_31K z<)}deT9M;uHb5z=P={t@9VXfDm;F$T3e=(z8RQXhqJEnhj8jD%7DFSw~6s2V_4KqXM;PLYfFeSRHGg($o4er zqXd<^{-f-NCbS{%7-^Ba2<50j16q-DtY!n0q6&3rM%HnX{Xy9e#i&3n8j(Tn@!Ari z4ArPd3$jnptd9~@?)o9w4^3!8-igv8cM-}_g9fxB=OoPrC`A?O(2Oi!vj0i;Loq5) zi$-LSd$P8KC_^>s(Sqz#H0z@TmAn44?1v__A@5Xak-G@xs6hi-krQY(Kq;zFhh}7* zCfOgB{ZNbw)S?j?49)r|LFKL=k^RtwHspoUB6ktWQG*7wBIiua z1}H@p>d=g=vn2apWIq(60<~yF2DxWzONcU5qaH2Djx_6|1eLq~tL%p+v?1>tX_31K z<)}deT9I?EW&@O>3Uz2k)_IcsQP~g0s6Z_mkwI>(Eg{NKje4{o`+Uv%C_&|}ACvvi zgf`?|AT4qip&T`6Kr3=C)NFuKRG|*d$Vw#pV^%Jrmn$U*4OQc2aB9x;B4QNG9s@VXgs6ri@k#(tLe^T~CF)C1tMr4qCnYM%| zLpAErg6zvR>!SpfyM9XcLlfGNmr0ANIR6ji80GqSFf?0=K}P>c%H zq7fP7UZpJ|%217Zv>-dztd9~@?)quj4^3!8-qq3~cM-}_g9fxB=NiohC`A?O(2T5W zCHph7ABs_dS~Mbq+(KJIl%X2+XhHUMn)OkF%3VJz`=JSK$h%%z62KrI@PLGG>E5~2*%s7DL3Z_})g5>)Q`AF>~s z(1yHPTI4Q5Icm^=R^;5S*#M=eLLHisb%$jCr|gGfRG=1($RPJlZ3$6^YSg0z*^Op> zl%R6gFUWpqLL2h#k`}p(P>vcjpcOfHYc@bBs!)e!WZfg#UzGh&j0)7E5gFvR+7hA+ z)u=}cvhUTbj}lbw`X$*9O=v^jebOR#5z0}62DBpQe$56bMHTAMjI0MF`^&N)icx`D zG$MoC2el3{rC_^>s(Sq#9H0z@TmAn3z?1v__A+MJfxrd=g=XC(U@vLA|3fm$>ogWOSDLX@Ez^=Lu%vzql$g34XLDf^)b zZOD60TI4Q5Icm^=R^&Xd*#M=eLLHisHA(h=%YGvcjpcOf@W&@O>3Uz2k*2|LpZP^dSs6Z_mkwNY&+7hA+ z)u=}cvR~D#j}lbw`W@L1O=v^jA}w+kp&T`6Kr3=y(`V^?R}(n$U*4H>E}HB9x;B4QNHqTbd0}iYnBh8Ch>j z_V;B!6r%#QXha6NMq5IZp&IpQLH0YE^-+S#U4J0^p$TosdskZIE3Uz2k)*+JpKe8W+QGr@CB7@vRwIxIus!@*?WILMm zQG&`{e=7T-32n$bOj_hFLOE*CfL7!juGs*ks6ri@k#&S*|4jBnF)C1tMr4rdYD(6CBG@%W7M@fs^MJPuN8qkWIqct0#6ji80GqOC%{)Oy^VpO0O zjmRMP7;OnrhHBKK1=+`H)<+2{cm1X8hbFWk?>K3Zy9ni|K?7QmbG&8)l%fiCXhzlv zlKm^$55=fJEgF$Q?uptGq72ojM+>q~(yWgXRPOp~*$+)V)nkbA1OgeXHb>d}JiK(jtdP`T^>$$n@;8}d$*7P*U1 zjv6$e6*;GCHb5z=P={t@ogvx3k^NAN3e=(z8RUlA5~2*%s7DL3&(y4s5>)Q`TiFjy zXhYsv(js>e%29&`v?Awh%?2n%73$E8tVptdC;Ooo6{tlcGRQqgTSAnf8ue&F_PLt% zQG&`{e=qx?32n$bPg>+ILOE*CfL7$hnhj8jD%7DFS?5dkA7noiqXM;PLe%29&`v?Avs%?2n%73$E8tcxXkfb552RG=1( z$RPI;Z3$6^YSg0z*{NoIl%R6gfwCW((1yHArA6){l%oa>XhqItnhj8jD%7DFS(i)p zAlVPas6Z_mkwI>zEg{NKje4{o`wGqaC_&{eTlPZ}+K_jpw8&kAa@3#!t;o4bvjIv` zg*r4NE0^rSvLA|3fm$>ogWRjNB}5sjQI8g6U!z$cC8*qWi0p?Zv?1?WX_31K<)}de zT9H#|Hb5z=P={t@T_@Q?Wj_?70<~yF2D#U3ONcU5qaH2DzCp7-N>I7Wk^RtwHsqDk zB6ktWQG*7wBIicU1}H@p>d=g=n)T0I2m1cdEpmNvY zvLBkzhP+#(MeZV$qXrFVMb5374N!_I)S($!w@LO0*$>62KrI@PL2j)rA<9sVdbA+> zcFp=ILFF!2_Cpiekavf)$X$eT)Sv;a$hlLq0ZLJYIy57zk?fJOABs_dS~Mbq+`F_T zL>a14j}~O#tyv!>sN8jw?1v__A@3e(k-G@xs6hi-k<)56Kq;zFhh}8mE7_xEKNO<^ zwP-{Jx%X*Hh%!{89xceeU$Z_+P`S&K{m_Iqqa*Q}2cRPH)n_CpiekoSbN$X$eT z)Sv;a$azw;0ZLJYIy56|kn9PvABs_dS~Mbq+^4i9L>a14j}~MsN8j;?1v__ zA@3P!k-G@xs6hi-kuz#GKq;zFhh}6wE7_A|KNO<^wP-{JxzA}!h%!{89xcdzUb8+* zP`S&O{m_IqL$lp&41PO7>LQ55=fJEgF$Q z?xHOr%217Zv>^L6&H5-o<*q>XLlfGN_qw#mU4(MfpaHGOc|)@SN>PP6G$U)3>}j$e zicx`DG$MoCH?<{18LCl_7G%GrSsx{++;zI_hbFWk?`>(3y9ni|K?7QmV>BC}6ji80 zGqT>1>>08jicx`DG$MoCceN!%8LCl_7G%GtSsx{++!e}xXhIwEHffQ&2<50j16q;u zzGefIq6&3rM%D+CJyZ5WF)C1tMr4rtp|*r5LpAErf^6%}k6z%T1eLqalKs$xHsl>3 zEpiv395rY_D{>ChY=BZ!p$^T+I!Ll-%YG)T0I22W!?x2`YC* zvLBkzhP*?hMeZV$qXrFVMb4p`4N!_I)S($!j%3e~{ZNbw)S?j? zaLxKCLFKM@*$+)d=g= zlO%hg?1y4hpcakDAlKKH5M`)FJz9``vSxjhpmJ9t`=JSK$U8+^q~*Q}2cRPMT1_Cpiekavc($X$eT z)Sv;a$O$zYpcGZ8Lo>3@la14j}~N~tyv!>sN9vxerQ4) z@*-)Gy9ni|K?7QmbB<;Ml%fiCXhzn#lD$;+Loq5)i$-LSd!Dw0C_^>s(Sqz)vpz~t zx$8374^3!8-ucoZcM-}_g9fxB=K{?JC`A?O(2T4LC40H-hhkKq7LCXtH_?_5WvE6y zT9AE_W_^^Pa#tq%p$TosyI5M}Emr4ArPd3$icMtd9~@?z&R;LlfGNce%94U4(MfpaHGO$ut|F6ji80GqSFb>{YTK zicx`DG$MoCE43v=8LCl_7Gz(gSsx{++?C6IXhIwEa%qvf2<50j16q-DwPpj9q6&3r zM%Fcwy;}A|F)C1tMr4qCt+s?HLpAErg6u-GK1xuz>l)b)O=v^jbo3zMXgmToN0jVRmy&7LL2fLX_31K<)}deT9I>?W&@O>3Uz2k*4>i5QT9VIDo~3?WRQE0wuC4{ zHR{oV>{hcrN>I7$CfN^7XhYt;(js>e%29&`v?Av|%?2n%73$E8totQXhqJ$nhj8jD%7DFS)F8W zk^NAN3e=(z8RR~qEg{NKje4{o`%%sMC_&|}TV+2qp$&PDNsHV?C`Sz%(2AU1vjIv` zg*r4N>v756Ci|fn6{tlcGRS>GTSAnf8ue&F_LG|RQG&`{wd{u`v>|Vh7P*U1jv6$e z6**67Hb5z=P={t@JuTVWWj_?70<~yF2D#5@ONcU5qaH2D9yRNu1eLq)kp0kvHsn1k zEpiv395rY_D{`LGY=BZ!p$^T+dS0@3%6=$D1!~cV400!J2~mb>)T0I2FKE_B2`YCr zvLBkzhP)T0MeZV$qXrFVMb1l_4N!_I)S($!vt;j*{ZNbw)S?j? z70vo6LFKNyWj{2b4SBChi`+#hM-3X#ikwBW0ZLJYIy58eHOby1`=J;Ws6`_($bDT~ zLX@Ez^=Lu%8=Cb|g34X3?1v__A#aryxrMrh%!{89xcc=n)OkF%3b%#erQ4)^4^gaxrs(Sq#vHS41UmAf90{m_IqgAC&!2j0)7E5gFtjpe-TFP>p)DAp1bg`Y1u=u7_klG@%W72T6vcjpcOfXX*NJ9s!)e!WF0QqM`S+~qXM;PLXiJDPRHGg($aXdB zqXd<^9+myjgf`?IDJ^mrp&T`6Kr3>N(rkcIRG|*d$U0iGkI8;0Mg?lohzxQ)Z3$6^ zYSg0z*~e(sM+qu-^|BwD(1yHYrA6){l%oa>XhqI(nhj8jD%7DFS;tHEaoG>Ws6Z_m zkwNYW+7hA+)u=}cvQN~kj}lbwdP4R?6WWk>lC;QOgmToN0jO*QGr@CB7@vhv?W9ts!@*?WS^>8A0?>VHOPKwLL2e|X_31K<)}deT9I>_W&@O> z3Uz2k*6EUcO7=rBDo~3?WRQD?wuC4{HR{oV>`=2lN>I7$Y1t1=XhYta(js>e%29&` zv?Av$%?2n%73$E8tg|KijO>SERG=1($RIb;mJnsAMm<`PeU4^*l%R6gDEpxaZOA)U zTI4Q5Icm^=R^*(g*#M=eLLHis6-)M6*$>62KrI@PLGJn55~2*%s7DL3FVL)y5>)Pb zPWD3++K_jlw8&kAa@3#!t;k6<8=w?bs6#WdE|To?vLA|3fm$>ogWQX?B}5sjQI8g6 zU!qwbC8*pr$$n@;8}d?Vk-G@xs6hi-k#nhL1C*i)b!bM`Ws-eC_Cql$P>V)nkbAkd zgeXHb>d}JiOtU^pP`T?x*$+)d=g=t0eo9?1y4h zpcakDAUD^R5M`)FJz9``wPt;kpmNtN`=JSK$h$^bsA*Q}2cRPK63_CpiekavT$$X$eT)Sv;a$SE}& zpcGZ8Lo>2&la14j}~O#tXUr=sNA*4erQ4)@+xVOy9ni| zK?7QmbBksJl%fiCXhznpl6_6~Loq5)i$-LSdz-d|C_^>s(Sqz+vpz~tx$AY=4^3!8 z-tE#NcM-}_g9fxB=MK#VC`A?O(2T4*CHsc#hhkKq7LCXtx6zgmWvE6yT9AF0W_^^P za@Q*Rp$TosyIWf1EPP6G$ZRl$-XW7p%@jYMI$oE zeMnnEl%X2+XhHVFn)OkF%3VhGLlfGN*GY@qMJPuN8qkWIM>HFt6ji80GqN6)>^rg_ zicx`DG$MoC$FwCx8LCl_7G(FD^-+S#UGK_%XhIwE9+wumi%^alG@unZPiQtkDXLJ1 zW@J4n+4p2W6r%#QXha6NgSLbyLpAErg6yX>>!SpfyEfSmO=v^j)6yb$5z0}62DBpQ z8O;VLMHTAMjI2?z@5_EDMg?lohzxR{)s_%ts75_nko}xyeUzYb*9Wp6n$U*4=cPsN zB9x;B4QNHqq}c$as6ri@k@bRPKa~AYj0)7E5gFvZs4XGNP>p)DAp0fF`Y1s+ia!3+ zKJEt|RJ@>gUvbR*(akxEs}*-Co>IK2IPB$*Ql}{{RotR@MDeo1dPQC<4>}&js6Z_m zkwNaO+7hA+)u=}cvKP(zC_&|}fAq2UJ%A>(A@4P5k-G@xs6hi-k@LD{1C*i)b!bM` z862KrI@PLGG$8A<9sVdbA+>P0ji!LFKMbl>N|zHsrk}Epiv395rY_D{|h} zY=BZ!p$^T+GLroy*$>62KrI@PLGC-+5~2*%s7DL3-_@*-5>)Q`WZ4f*XhYt6(js>e z%29&`v?6EIY=BZ!p$^T+dS9}iBKx5j6{tlcGRXZvTSAnf8ue&F_J^AFQG&`{pDO#I z32n%;-u~Es$X$eT)Sv;a$T>i>0ZLJYIy58eK*@fZ?1y4hpcakDAon0`2~mb>)T0I2 zwq|{lpmNuz%YJA=8}bg87P*U1jv6$e6*-4!Hb5z=P={t@9V*$+ko{1M3e=(z8RR)Q`OxX`jXhYuN(js>e%29&`v?AvS%?2n%73$E8ELXChCHtWm z6{tlcGRQqrTSAnf8ue&F_EDPkQG&`{pDp{L32n$bT3X~TLOE*CfL7#qnhj8jD%7DF zS;t8BAIp9yMg?lohzxR%)s_%ts75_nkbRtHeUzYb*XPK7XhIwEj+Yj>i%^alG@unZ zCulZ6DXLJ1W@Mcx+0T{zP>c%Hq7fP7o}?`y%217Zv>@Bptd9~@?)p604^3!8-pSG; zcM-}_g9fxB=M>EbC`A?O(2T58CHwiZABs_dS~Mbq+(27Gl%X2+XhHUAn)OkF%3c3N z_CpiekaxPY$X$eT)Sv;a$T>r^0ZLJYIy56IlogWPkq zB}5sjQI8g6pQl+LC8*r>MY127(1yHNTI4Q5Icm^=R^*(o*#M=eLLHisb%A8RSoT9P zDo~3?WRQEIwuC4{HR{oV>_oFZN>I7$OJqMZp$&N#NsHV?C`Sz%(2AUkH5;H5Rj5NV zvM!PAm&$%9Mg?lohzxR5Z3$6^YSg0z*_Ue8M+qu-eVOcsCbS{%GHH>!2<50j16q-D zxn={Dq6&3rMph=-FPHsLj0)7E5gFuOp)DcGP>p)DAp1(q`Y1u=u74)`p$TosyGmN* zEq` z&H5-o<*u)i{m_Iqa14j}~O#qFEm$sND56vLBkzhP+#)MeZV$qXrFVMb2%S4N!_I)S($!wPe3m_Cql$ zP>V)nkbAqfgeXHb>d}JiJ2dN~1eLqKPWD3++K_jrw8&kAa@3#!t;lIK8=w?bs6#Wd z?vm`kko{1M3e=(z8RXurEg{NKje4{o`yS2uC_&|}ub2JMgf`^0(js>e%29&`v?AwT z%?2n%73$E8totPU4YD7KQGr@CB7@xfwIxIus!@*?WIv!;A0?>V^)F>VG@%W74@!&N zMJPuN8qkWIhcp|Y6ji80GqN6*?7x!zP>c%Hq7fP7cG?o64ArPd3$h>4td9~@?)paA z4^3!8-lNhYcM-}_g9fxB=P}I&C`A?O(2T5Jvfm{8p%@jYMI$oEeOy~Yl%X2+XhHT9 zn)OkF%3a?q`=JSK$a_*+L$lp&40EN%mjMekeu-YSD-ca-Y_g z5M`)FJz9|cjAnh5pmNv0k^RtwHsp=cB6ktWQG*7wBIjAn1}H@p>d=g==Op`YWj_?7 z0<~yF2D#5`ONcU5qaH2Do;2&D1eLqKMfO7z+K~5xw8&kAa@3#!t;l&%vjIv`g*r4N z>m|v4tL%qjRG=1($RKytmJnsAMm<`P{jz3#l%R6gx5<8JLL2g4krug&P>vcjpcOf< zYBoSAs!)e!WG#~YcG(Zbs6Z_mkwNZj+7hA+)u=}cvR~J%j}lbw`VQF-O=v^j8`2_o z5z0}62DBn))og%LRG|*d$a+(<|4#NpF)C1tMr4rtmbQc_LpAErg6y|7>!SpfyS`KQ zLlfGNXQV~$B9x;B4QNHqJDLqpiYnBh8Cma2_Pb<16r%#QXha6N?`cbjGE}1;Ey&(9 z>!SpfyS`iYLlfGN_rA2qU4(MfpaHGO`9QM)N>PP6G$ZRn$$pRQhhkKq7LCXt*D@cq zgeXHb>d}Ji12pTS1eLqKSN1~_+K_jkw8&kAa@3#!t;jh@vjIv`g*r4N%a-i-$$ltC z1!~cV3~~?FmJnsAMm<`PeTZg#l%R6gznA^cgf`?IDlKvsp&T`6Kr3<_%?2n%73$E8 ztivSx{jwj5QGr@CB7@w+wIxIus!@*?WFMhfA0?>V^&ezEG@%W7uC&NqgmToN0jekeu-YSD-ca!=Nl5M`)FJz9`` zie`P3pmNuLmi^F#HsqZuEpiv395rY_D{=zO1}H@p>d=g=(ogWS`# zB}5sjQI8g6pP^YFC8*r>BeEZw(1yHFTI4Q5Icm^=R^*(i*#M=eLLHisb(UoRi|mJD zRG=1($RPJ@Z3$6^YSg0z*^y>_l%R6gf0g~vgf`@zBQ0_lp&T`6Kr3?2)og%LRG|*d z$U0B5KPvm77!{~RBQnU1wIxIus!@*?WS_5DA0?>V^<%Ohn$U*43#3KvB9x;B4QNHq zg_;deiYnBh8Ci*Be_ZxMF)C1tMr4qCk+y^=LpAErg6xYm>!SpfyM99ULlfGNcZsyf zU4(MfpaHGONi`dw6ji80GqNs~>`%&mC`JWp(TEIkFVmI~WvE6yT9AFYW_^^Pa@SAE zerQ4)@-k_Wy9ni|K?7QmbA@IDl%fiCXhznRlKpS8ABs_dS~Mbq+^e)DL>a14j}~O- zn)OkF%3VJ#`=JSK$h%rv^j_Cql$P>V)nkXvX= zh%!{89xceePP0BrP`T@8Wj{2b4SCl~i`+#hM-3X#ikurX8=w?bs6#WdO3D75?1y4h zpcakDAooUX2~mb>)T0I2H)+;K2`YE}yzGZ2v?1?iX_31K<)}deT9H#}Hb5z=P={t@ z-6GllF8iSv6{tlcGRVDETSAnf8ue&F_HCN=QG&`{|3mge6WWkhON-n^C`Sz%(2AVf zH5;H5Rj5NVvhI-V|CIeuj0)7E5gFv(sVyPOP>p)DAiL45j}lbw`UTk!O=v^jUD6_V z5z0}62DBpQZp{WLMHTAMjI4Vk`-`$4icx`DG$MoCR$D@pp&IpQLH50x^-+S#UB4vz zp$TosyH8r=Es(Sq!U zH0z@TmAigL_CpiekoT~($X$eT)Sv;a$muj2pcGZ8Lo>1-k?gO^ekeu-YSD-cav#-} z5M`)FJz9|cm}Y&HpmNv$lKs$xHstlvB6ktWQG*7wBIj|<1}H@p>d=g=CnWo8vLA|3 zfm$>ogWM;zB}5sjQI8g651RE+g34XLF8iSgZOD5{TI4Q5Icm^=R^&Xb*#M=eLLHis z^^9bHL-s>4Do~3?WRN>*ONcU5qaH2Depa(SN>I7$H)TIGp$&P@NsHV?C`Sz%(2AVr zH5;H5Rj5NVvL?y?Z`lvUs6Z_mkwNYY+7hA+)u=}cvR~A!j}lbw`YqWHO=v^jOVT2D z5z0}62DBn))@*=MRG|*d$a-0_zb*Tr7!{~RBQnT+MO#9Yp&IpQLH4Vf^-+S#UB4sy zp$TosTckzqB9x;B4QNHqYnlyEiYnBh8CkDO_IG7J6r%#QXha6NZ)i)1GE}1;Ey!Lq z>!SpfyM9mhLlfGN_olSSU4(MfpaHGOc}ueaN>PP6G$ZS6$^O3VhhkKq7LCXt*Jw+K zGE}1;Ey#XHvpz~tx$6&PKQy5YdGAV#+(jry4I0pjocA;vpcGZ8Lo>2A$^N12hhkKq z7LCXt_kC>%QHE;NqXpR?Xx2vwDtG;n?1v__A@4(Jk-G@xs6hi-kz>8{Q8qv+s!)e! zWE~*cKbHMaj0)7E5gFtjs4XGNP>p)DAp0QA`Y1u=u0N6e(1bSR+0r6+5z0}62DBpQ zV9f?7MHTAMjI2W>`+sCV6r%#QXha6NhiXfRGE}1;Ey#8>>!SpfyZ%)6LlfGNcbK%u zU4(MfpaHGOIb5>=N>PP6G$ZQ>$^Mz_hhkKq7LCXt*VUE~WvE6yT9AFDW_^^Pa@U{B zerQ4)@{W=gxrr# z)vS*aRPOpq*$+)d=g=6D0drvLA|3fm$>ogWMCf zB}5sjQI8g6pQKqIC8*r>*Rmg)(1tu;TI4Q5Icm^=R^*(l*#M=eLLHisb&6#Fuk43n zRG=1($RPJrZ3$6^YSg0z*@0$#l%R6g|C9aDgf`@zCM|Lop&T`6Kr3=i*KB}NRG|*d z$T~x^eV^|!Jgn$U*4v!q4tB9x;B4QNHq z*_sVdiYnBh8Cj8J|4#NpF)C1tMr4qCj<$p-LpAErg6wlO>!SpfyZ&DGLlfGNcb>G! zU4(MfpaHGOi8ULb6ji80GqTQ?>_5nUC`JWp(TEIkFVL0{WvE6yT9AFAW_^^Pa+f9h zp$TosOQc2aB9x;B4QNHqMVbvziYnBh8Ce%g_5j%r#i&3n8j(TnCE60A4ArPd3$jzq z`Y1u=t^;L1G@%W7mr9G=MJPuN8qkWI%QPFH6ji80GqNt1>_M_0icx`DG$MoCOj|;f zp&IpQLG~4z^-+S#UAF9pCbS{%N@k!!wO=v^jwbCMY5z0}62DBol&}@KGRG|*d$huCl zhsu5^Mg?lohzxSC*Om}vs75_nkbQ$@eUzYbmm~Y332n$LrA6){l%oa>XhqJAnhj8j zD%7DFSvN`cFxd~qs6Z_mkwNaw+7hA+)u=}cvMbH{C_&|}!(~4-p$&PrNQ>M>C`Sz% z(2AT}H5;H5Rj5NVvTl>?5wahOQGr@CB7@voTSAnf8ue&F_U)SWQG&`{uIz^f zX_31K<)}deT9I?7W&@O>3Uz2kRwLOXWj_?70<~yF2Dx`>ONcU5qaH2DzFV_CN>I7$ zDA^B9XhYsT(js>e%29&`v?8a~Y=BZ!p$^T+x>vGC%YG)OwR`x>^+K~5%w8&kAa@3#!t;l&)vjIv`g*r4N>oLh5C;Ooo z6{tlcGRW<aX_31K<)}deT9NalW&@O>3Uz2k z)*#svWIq(60<~yF2DwjZOZfkJpzk;U#kTF^@3Y7K?7jEid$0T1d++Dnd+$9%2q8O! z5JCtSLI@#*><~f-A%qZKXCLS9zwaOCaddScgDTXa8QD*3)<+2{cAY5up%HD!dq!I1 zEk6234p-GqRu8td9~@?DAzl zG@=c8qqN9fgfdj49xcduL9+o$QHfeKA?roSo-F&J80Dxz16q;$lD34%pbB+pM)ssx zA0?>Rb&BkVMzkUCWoePS2xX{7Jz9|Sie>|pq7t=eLe{I2JyrHYG0IVc2DBn~)|L<% zRG|*d$bL<;K1xurE0F!rh&JTCE-i8wp$yfiM+ zXhrUu+7cpzD%7DF*>7pqM+qu+oi6*K5pBqOTUz8ULK&)2j~3*tnhj8jO4OnWS?@^p z4A~FGC`Sz%(2Cr5wIxIbRj5NVvftCJj}lbu3S~buq78YQw8&kAGE}1;Ey#IavjIv` ziCQ!v>jTN2Df^)q<)}deT9NyqwuH!_3Uz2kw)O7EFYr-PerQA+@(z#|xrgcapaHGOJxW_bWKe}V zG$Z?H&H5-o#jaTPLnGRd=Shp)MJPix>d}InV>BC}6qTq&6S9t#?D?`EicyXlG@uo^ z$7xH5460CvW@I0)Ssx{+*mZ&Iheos^?*wU)y9i~dMm<`PbE0Mgl%f)~XhPOWlD$y& zLov!xg9fxB*VmR18C0PT&B#7kvpz~tu`7}N(14QNH~Y1$GZgDTXa8QG_6)<+2{c3mv{p%HD!J40IJE`G-nG@=c8k+jHN zgfdj49xcc@N3#J+QHfeKA?sYpUMl;c80Dxz16q-Lp0Rb(!pk zMzkUCd})!p2xX{7Jz9`+fo21gq7t=eLe_uxhmKM2-P=;#MqXjvaXf{A8Dp89jWTle5LiR&3%29&`v?BLXZ3&S< z73$E8?8`LkqXZSZu9W@Ih&JS1E-i8wp$yfiM+618YT))kVyO7=rB%29&` zv?BLPZ3&S<73$E8?5i~EqXZSZGT9G}XhU8mEpiv34ArPd3v#a3Y=BZ!q83fax<;~B z%YG?fLLHisoom)d2`YA7Bm1EdZOFS$TI4Q58LCl_7UW#7*#M=e zL@k<-b%SKDmHkkRa@3#!t;j93B}4{Qs6#WdZ`7=h5>)KUWj{2c4S6?7i`+#hLpAEr zf}EQ*8=w@Gs6`X9O37X)`=J=+s6hi-k$a1_gvg)@b!bNRt(x^wf{I<&%YJA?8}e?G z7P*U1hHBKK1v!;w1C*i?wP-@t?UKDg_CqnsQG*7wBKHn$36Vh+>d=hrJ2mU01Qojq z*$<6qLtZT{au=Zt)u=}ca_-V>fKpVV7EQ>yTe3IGekevcYS4gIM>_q6t~gOZHCL55*`)4I0pj+)-OXWKe}VG$Z>3&H5-o#jaZRLnGRd z_oB4OU4$}JqaH2Dc}cSYN>PbgG$Ct}>|L@SicyXlG@uo^FKbJP460CvW@NvjSsx{+ z*mbw;heos^?^S7$y9i~dMm<`PGix?LDJoHmCS<)P*?VL^6r&t9Xh17+U)Pop8C0PT z&B%U3vpz~tv8$2&(14QNH~ z+u9N$gDTXa8QH65eUzYL*L|`d8qtQlccew`B9x&T^=LuPyP6G9ib~X?30dz+_I}w9 z#VAJ&8qkW|Od}In4>cR06qTq& z6SA!LKKky1vLA|3jv6$e6}bm!ONb1rP={t@AE;R$C8*f-knD#>v?1>xX_31KWvE6y zT99LFHb5yVQHv&I9W2?0Wj_?795rY_D{>FfmJk_Kp$^T+K2)H(@mHp6&Hsm?d zB6ktWP>p)DAm=d61}H@(YSDzO!zKHO?1y5MqXrFVMeY&W5+Z{t)S(&Ku4a9dpkmjf zvL71JhP)%CMeZV$p&IpQLC#T{4N!_o)S?MlM@#lG*$>4iM-3X#id;`yLS#^dIy58u z7|r@9LB+04_Cq7ukaw)K$X$doRHGg($T?240ZLJcS~MZ+c*#C4`=J=+s6hi-k$Zx+ zgvg)@b!bNRiJJ9Mf{I;F$bM)<8}d$)7P*U1hHBKK1v$QE1C*i?wP-@t$&!6i_Cqns zQG*7wBKH(+36Vh+>d=hrQ#I?O1Qok_*$<6qLtY>)au=Zt)u=}ca!%81fKpVV7EQ=H zU9wNfekevcYS4gIyDt0|B`=JqS$U9S73^(X5XWRO}jLKQy8ZdFM)t+(jru zHR{oVobxmrpcIv;MH8}O$v!Llp%~?;K?7Qmd%m`W$e;>!Xh!x0n)OkFie1mierQA+ z@-CDXxr!Sn}yIz$2(1d}InLbCx%QHfeK zA?rrTzAF2n80Dxz16q-LleUD&pbB+pM)u8`^-+R~U9;?mMzkTXloq**P=;#MqXjv) zXf{A8Dp89jWZf#+*JM8wqZ~D8Kr3=@)0Pk!RG|*d$gVW&qXZSZUYGsQh&JTiE-i8w zp$yfiM+`EyM+qu+EwUdP z(T2RcrA6){l%X2+XhF_Bnhj8jO4OnWS&d}hl>JbQa@3#!t;oGsTS8<|g*r4N`##P3 zC_%-pw`4ywq78ZXON-n^C_^>s(Sn=@G#j84m8eA%vL2M|+p-^uQH~lkpcT0fX-kL< zs!)e!WIwD~A0?>RwaR{IL>uy2X_31KWvE6yT9EUIW&@O>618YT)}xYrNA^Q8%29&` zv?BL0Z3&S<73$E8>`t>jN>H)uUD*$fXhYuP(js>e%217Zv>@jR%?2n%C2G-xtS2S= zp6rKWl%oa>Xhm+XEg>?fLLHis{gh^Xl%QhQCi|fgZOD6CTI4Q58LCl_7UVpm*#M=e zL@k<-HAwb-*$>4iM-3X#iri)K^K=wl;+K~6Ww8&kAGE}1; zEyx))8=w@Gs6`X9UXbjEvLA|3jv6$e6}c~JONb1rP={t@zoc0oCFn-cr+n_;`s9O( z7ZmR+j+s8bIY)7|;x5HgiZ>O9z5H?NG{vQgTNIBdURGGI$ZO?6$Dd}In*EJiU6qTq&6SCfr?5D|o zC`LJI(12FtF4__zgDTXa8QE`Y)<+2{c73|+heos^?=5MOy9i~dMm<`P^R{LKl%f)~ zXhPO1+0T&uP>gcapaHGOeMehDWKe}VG$Z?6&H5-o#jekk{m_Uu^?au=Zt)u=}c zayHEdC`Bb|(S)q`CHq;jABs_q8Z@94xgTgthzzPwhh}7ds97H+sMz({vL71JhCFNg z=s)BxLK&)2j~3({pxFSWs6;KAkaeJBKS%aMG0IVc2DBpgAZ-beK^5xIjBH!8K1xur z>vLs4G@=c82TP0GMJPix>d}InLo^$p6qTq&6S5AK>?dSD6r&t9Xh17+9c>AbK^5xI zjO@cS>!Sn}yFO3$LnGRdceu33U4$}JqaH2DIYP4mN>PbgG$G5C?B~mVC`LJI(12Ft z9;q!MGN?iwnvs2!W_^^PV%HbQerQA+@{X1kxr3E)2xpYRP6d9*$<6qL*DVyB6ktWP>p)DAm;?l1}H@( zYSDzO6D9k_vLA|3jv6$e6}cyAONb1rP={t@`H)u%Va+^q78Yc zON-n^C_^>s(Sn>aG#j84m8eA%vO>vzx$K8xl%oa>XhrUs+7cpzD%7DF*=K3iM+qu+ zeTD3YMzkUCY-y3Z2xX{7Jz9_xX*NJ9Dp89jWSt|~uax~zjB?bV0j4iM-3X#irgEtB}4{Qs6#Wd3(fi{LB+0b zk^Rt!HsswXEpiv34ArPd3vzDKY=BZ!q83fax>>T{D*K@r<)}deT9I37ONb1rP={t@ z-=bL`C8*f-ZL%L4(T2QRrA6){l%X2+XhF_xnhj8jO4OnWS(RkJUG_sU%29&`v?BL* zZ3&S<73$E8>^n5;qXZSZzC-pyBifL6r?kjjgfdj49xceJH5;H5m8eA%vhI@XcglV! zMmcKGfL7$*tt}xks6ri@k$sP5eUzYL*LTT&Xha+G8flTc2xX{7Jz9`+uVw?3q7t=e zLe_nf{chP0#VAJ&8qkW|`?V!R234p-GqNAhtd9~@?D`(r4~=L;-h!Xh!xUn)OkFie29)`=JqS$a_>; zv>|Vh7P*U1hHBKK1v$@ZHb5yVQHv&IJtx^8mi)K^5!nxoXhYr$(js>e%217Zv>@k2%?2n%C2G-xtd}JFqp}~0 zQH~lkpcT23wuH!_3Uz2k_RE^}QG$wHKPLO35pBqOMOx%8LK&)2j~3*-s@VXgs6;KA zkTpy8$7MehqZ~D8Kr3=z)0Pk!RG|*d$bMb3K1xur>nCJCG@=c8Z%B*WMJPix>d}In zMY91)QHfeKA?r=a{-o@OVw9r>4QNH~TiOyLgDTXa8QE`Z)<+2{cKwv>heos^ZgcapaHGOeNS6LWKe}VG$VV{td9~@?D`qm z4~=L;-uu!bcM-}^je4{o=L5|KC`Bb|(S)oICHu3oABs_q8Z@94xz_t1w}i-`3Uz2k z_5qspQG$wHKPUU45pBpjP+H_JLK&)2j~3({q}c$as6;KAkY!8u=Vd<>qZ~D8Kr3<& z)|L<%RG|*d$Ua1~K1xur>lb7{G@=c8hf0gwMJPix>d}H6N3#J+QHfeKA?q;7{-W%M zVw9r>4QNH~;o1@+gDTXa8QDi@)<+2{cKwp2Z(5#OVRP6dy*$<6qL*9wf zB6ktWP>p)DAm=2_1}H@(YSDx&U$Va@`=J=+s6hi-k$bYXgvg)@b!bNRDVp_Bf{IH)uH)TIGq78YWw8&kAGE}1;Eyy`jvjIv`iCQ!v>nzFsmh6XOl%oa>XhrVX z+7cpzD%7DF*^y>_l%QhQZ_9pYL>uzXkrug&P=;#MqXjwVYBoSADp89jWSuA3-;w=L zjB?bV0j{_!vN>H)uuVp_pq78X>NsHV?C_^>s(Sn@2 zH5;H5m8eA%vhI=W-^hL_MmcKGfL7!-+7cpzD%7DF+4pMJM+qu+{cYI~jc7yOebOR# z5z0`FdbA+te$56bMI~y{gscZ7`*&nN6r&t9Xh17+AJmo*8C0PT&B%U8vpz~tvFq>3 zerQA+@*b8Jxr`l%f)~XhPN_lKp$KABs_q8Z@94xsPf~hzzPwhh}6y zrdb~)sMz)QWj{2c4SAik$X$doRHGg($a!3|0ZLJcS~MZ+3CaEg*$>4iM-3X#irgo) zB}4{Qs6#Wdd(HYNLB+0rDEpxiZOD5{TI4Q58LCl_7UVpw*#M=eL@k<-^^9cyk?eXhrUzEg>?fLLHis{j6qvl%QhQKbHN_h&JRsCoOUpp$yfiM+w7qZ~D8Kr3=z(3TJxRG|*d$bM0?K1xur>z~SgXha+GUXm8Mi%^DY)T0GC zlV$^yq7t=eLe|TY{b#ZticyXlG@uo^uV_n%460CvW@NvrSsx{+*!9n4KQy8Zd9$?0 zU4$}JqaH2Dc}=qcN>PbgG$HGC$^Hx355*`)4I0pj+&8o(L1$&H5-o#jbxT z`=JqS$a_;-H)u-^zYyL>uxxloq**P=;#MqXjwE2Onnxl%f)~XhPNjlKpqG zABs_q8Z@94xd&=XhzzPwhh}6Sq*)&&sMz)IWj{2c4SBY-$X$doRHGg($T?WE0ZLJc zS~MZ+5Xt@r*$>4iM-3X#irhoBB}4{Qs6#Wd9nJbELB+2BDEpxiZOA)JTI4Q58LCl_ z7UUeR*#M=eL@k<-b%bR9lkA6Ll%oa>Xhp88Eg>?fLLHiseWYf6l%QhQf0q5wh&JRM zB`tCnp$yfiM+O(UuSyRG|*d$UauHK1xur z>%Yo=Xha+Gj*}L-i%^DY)T0GC$7?n~DJoHmCS;u;+5aZ{p%~?;K?7Qmd!n|4$e;>! zXh!x)n)OkFie3L*_Cq7ukmpN_+(jruHR{oVoRc*hpcIv;MH8}4k?jAF{ZNc@)Sv;a z$URkCLS#^dIy56Y(5#OVRP6envL71JhP>0HMeZV$p&IpQLC)!#4N!_o)S?MlXGr#c z$$ltCIcm^=R^*1-5+Z{t)S(&KXKL0*2`YB|Z`luxXhYsv(js>e%217Zv>@kf%?2n% zC2G-xtVpu|NA^Q8%29&`v?BK$Z3&S<73$E8>~l5iqXZSZ{;%wZMzkUCJZX`;2xX{7 zJz9_xYc@bBDp89jWSuYB|0nyQ80Dxz16q-LfwqLmpbB+pM)rl8^-+R~U6$;JMzkR> zkrug&P=;#MqXjt^X*NJ9Dp89jWL+%T17trGqZ~D8Kr3=D(UuSyRG|*d$WAruqXZSZ z4wU`Sh&JS1DlKvsp$yfiM+?<_uqXZSZY}pTuXhYtW(js>e%217Zv>@jy%?2n%C2G-xtW2^8%YG?fLLHiseT`;)l%QhQA+jGD(T2QhrA6){l%X2+XhBY{*#M=eL@k<-b)94nmHkkR za@3#!t;oGzTS8<|g*r4N`v%SWC_%+8NA^P_+K^XBi`+#hLpAErf}9&Q8=w@Gs6`X9 zZj$U_vLA|3jv6$e6}dNSONb1rP={t@mzwoaf{I;-%YJA?8}e?E7P*U1hHBKK1v$5B zHb5yVQHv&I-6q*1WIq(695rY_D{?Ds36Vh+>d=hr+coQ>1Qokn*$<6qL*5p)DAm>ia1}H@(YSDzOTCzvVekevcYS4gIEMeZV$p&IpQK~AID0HvrzEt-&ZuVjyw{ZNc@)Sv;a$h}WnLS#^dIy58ue$DzQ zLB%dl_Cq7ukoSPJ$X$doRHGg($azq+0ZLJcS~MZ+A;}&i`=J=+s6hi-k^8W=gvg)@ zb!bL*t63ip)DAm>TV1}H@(YSDzOUa}|1 zekevcYS4gIAu^~!9h#B-v}S#jpkmjFvL71JhP-E_MeZV$p&IpQLC&Dr0Hvrz zEt-(^tYlA;{ZNc@)Sv;a$bC**LS#^dIy58udCmGLLB%d#_Cq7ukT*(;+(jruHR{oV zoEJ13pcIv;MH8}KlgcapaHGOeOFsT zWKe}VG$Z>x&H5-o#ja5HLnGRdw@HiKMJPix>d}In_ca@!6qTq&6S6*#?3uD3icyXl zG@uo^A8Jd8460CvW@K9*e*6L-C8*eSmh6W{v?1>RX_31KWvE6yT99*~W&@O>618YT z)H&YlKs$#Hsl>5Epiv34ArPd3vv$C zY=BZ!q83faawL0>?1y5MqXrFVMebqR5+Z{t)S(&KhileH2`YA-EBm1lZOA)9TI4Q5 z8LCl_7UZ~^4N!_o)S?MlM@sfQ*$>4iM-3X#irk~LB}4{Qs6#WdkJhY@5>)JpWj{2c z4SAll$X$doRHGg($T>!{0ZLJcS~MZ+SjnC*`=J=+s6hi-k$arBgvg)@b!bNR@tXBf zf{I-i$bM)<8}d$&7P*U1hHBKK1vw{bHb5yVQHv&Iog~={Wj_?795rY_D{_5p36Vh+ z>d=hrlQrw31Qojy*$<6qL*6OUB6ktWP>p)DAm>!g1}H@(YSDzOK(ZIfekevcYS4gI zvL71JhP*SRMeZV$p&IpQK~AXI0HvrzEt-&ZrerUX z{ZNc@)Sv;a$URG2LS#^dIy58uY|Z*8LB+0A_Cq7ukQYgd+(jruHR{oVoO3iApcIv; zMH8~lmF%UmABs_q8Z@94x#ww1hzzPwhh}8Qn)OkFid~n4QNH~wb~LQ zgDTXa8QHmJeUzYL*EO;q8qtQl>!d~QB9x&T^=LuP^_mS(ib~X?30XHt_FCBw#VAJ& z8qkW|LR&&)P=z`)Bl||p`Y1ugu3Yv*BifL6leEZPgfdj49xceZS+fC3QHfeKA*+<^ zb+R9dQH~lkpcT2dXiJC;s!)e!WZ$Y;A0?>Rb-nC|MzkUCHffQ&2xX{7Jz9`cX*NJ9 zDp89jWZf>=8)QEeqZ~D8Kr3?Z(3TJxRG|*d$i7pvK1xurtC0QBh&JTa(js>e%217Z zv>@j$%?2n%C2G-xth*(9qwI%bl%oa>XhrTl+7cpzD%7DF*^Op>l%QhQO|l;v(T2Qx zrA6){l%X2+XhF_>nhj8jO4OnWS@%o!X4wzLC`Sz%(2Cp#v?W9aRj5NVvLDo}j}lbu zDrG-3q78WuNsHV?C_^>s(Sn?ZH5;H5m8eA%vRcXBBKx5j<)}deT9NyRwuH!_3Uz2k z_M@8hQG$wHx5|EKL>uxRlNPy)P=;#MqXjvgW&@O>618YT*5i`BP4+`E%29&`v?BKj zZ3&S<73$E8>?bwrqXZSZD%lT>XhU8vEpiv34ArPd3v!;)Y=BZ!q83fadRnr#%YG?fLLHisJ!sZP2`YBoA^V{bZOD68TI4Q58LCl_7UVpq*#M=eL@k<- z^}J;7l>JbQa@3#!t;ij)J}Wj{2c4S6q0i`+#hLpAErf}EE$ z8=w@Gs6`X9Cdu9<`=J=+s6hi-k^8c?gvg)@b!bNRE1LCDf{I;t%YJA?8}eS27P*U1 zhHBKK1v#^31C*i?wP-@tYm&W3_CqnsQG*7wBKLJ|36Vh+>d=hrH#F;`1Qoj)*$<6q zL*61Sau=Zt)u=}ca^BQzfKpVV7EQ={OS1RMekevcYS4gIy zDt6r``=JqS$a_ax49*Q}2cRP1^{_Cq7ukoSSK$X$doRHGg($oWvS0ZLJcS~MZcvOeV#pZcKehhmhY z1`TLM?g82oB7-W_p&8i+YSu>yDt0|2`=JqS$U8_{M>_q6t|C zOZH*e55*`)4I0pj+(Wb_L1u)vS*aRP1VHKQy8Zd5*NmU4$}JqaH2DIZU$w zN>PbgG$HG7$vz_cp%~?;K?7QmdxW-x$e;>!XhycHSsx{+*!8IFheos^??`Epy9i~d zMm<`PbChNSl%f)~XhPP}l6_3}Lov!xg9fxB*VC2|8C0PT&B#7Rvpz~tv8$8)(1gcapaHGOJw;nWWKe}V zG$Z>|&H5-o#jalVLnGRd7f6fTMJPix>d}In(=;2P6qTq&6S7X1>{GHIicyXlG@uo^ zXJ|`^460CvW@Lw&^-+R~T~Et?Xha+G&Xg9pi%^DY)T0GCXK6M-DJoHmCS;v0*=J-w z6r&t9Xh17+BW($hK^5xIjO=qX>!Sn}y9U`0jc7yOxzZwc5z0`FdbA+tJk16uMI~y{ zgsfPy&&qx%MmcKGfL7$5uPq@ms6ri@k$r(?eUzYL*K@KT8qtQl3#CQwB9x&T^=Ls( zqS*kYs6;KAkadw{pO^hmjB?bV0js(Sn>yH5;H5m8eA%vM!VC3$h=IQH~lkpcT27YfFd>s!)e!WE;);C_%-p7iB** zq78XhNQ>M>C_^>s(Sn>SH5;H5m8eA%vaXWsOR^t|QH~lkpcT29wuH!_3Uz2k_SKs8 zQG$wHlkA5^v?1>rX_31KWvE6yT99+CW&@O>618YTRxa6>Wj_?795rY_D{`;XmJk_K zp$^T+zFxCFN>H)u71e%217Zv>>O@Y=BZ!q83fax>2&P%6=$DIcm^= zR^;BKEg>?fLLHiseY0kLl%QhQEc>AmZOAL7MeZV$p&IpQLC!6j4N!_o)S?Mlw@UUk z*$>4iM-3X#irm|@B}4{Qs6#WdE6w^SLB+1uWj{2c4SBaqi`+#hLpAErf}A@v8=w@G zs6`X9?v(5svLA|3jv6$e6}h#xgvg)@b!bNRU7Gb#f{I;>?1x6QA@6Q!k-G?Gs75_n zkaLe_1C*i?wP-?CBiT1)KNO=JHE2L9a_`la5E)dV4$a8EPqRKsP_gSR*$<6qL*D(; zB6ktWP>p)DAm;(i1}H@(YSDzO2PONq?1y5MqXrFVMeak|5+Z{t)S(&K4{O#(2`YB2 zvL71JhP+l<$X$doRHGg($azAu0ZLJcS~MZ+Ny)w^`=J=+s6hi-k=tua zhzzPwhh}6yrCA>(sMxj1erQA+@}8C!xrSQ4hhmhY1`TLM?u*(IB7-W_p&8jPY1T&xx>58gpZHs!d{FU%;(f(2)5kaGD6UrA zrFcs5rsA-dKTe&dxKweA;t|Em3hNbltvu*>6r&t9Xh17+U)7cn8C0PT&B&fL>!Sn} zyFT@!_dS3{v?1>`X_31KWvE6yT9EU)W&@O>618YT)*F)jG}#ZuC`Sz%(2CqeTS8<| zg*r4N`%TUIC_%-pPnZ4Bh&JTCB`tCnp$yfiM+R^_j9C8qtQl_oPMcB9x&T^=LuPrr7|cs6;KAkoCS~ zKTGyQG0IVc2DBpg18oVBK^5xIjO-6J>!Sn}yFOd?LnGRdXC3g-f5=^gGE}1;Eyy`Q zvjIv`iCQ!v>p;nVj_ikGl%oa>XhrTp+7cpzD%7DF*|uhVl%QhQ=gNL)L>uxBmKM2- zP=;#MqXjvKXf{A8Dp89jWF0EmPsn~KMmcKGfL7!>+7cpzD%7DF*@tP?M+qu+eV*)x zMzkUCaA}dd2xX{7Jz9`+gk}Sjq7t=eLY6Dp&zJpBjB?bV0je~P=z`)Bl{@L z`Y1ugt}l@N(1M>_q6t|iO7@FoKNO=J zHE2L9a!=Bh5E)dV4$a8+HS41U6}!Gf_Cq7ukax1Q$X$doRHGg($T>x`0ZLJcS~MZ+ zRLOp+?1y5MqXrFVMQ)%iAu^~!9h#ASnr3~JpkmjT$$n@=8}d$<7P*U1hHBKK1vzJE zHb5yVQHv&Ig_8Yp*$>4iM-3X#irh1`B}4{Qs6#Wd&(f@q5>)K^3fT{hXhYuF(js>e z%217Zv>+$aY=BZ!q83faI!Cf!Df^)q<)}deT9JFMwuH!_3Uz2k_IaB1QG$wHUnTpY z5pBqerA6){l%X2+XhF{Tnhj8jO4OnWSrVw9r>4QNGfsx2Wh zs6ri@k$tIVeUzYL*VoB@Xha+GE|V6yi%^DY)T0GCmuogaDJoHmCS)1Oe!c96Vw9r> z4QNH~71|OagDTXa8QE8A)<+2{c722Fheos^?<#4Ly9i~dMm<`PlW8_UDJoHmCS+YL z*>9BnP>gcapaHGOy+&I?WKe}VG$Z?3&H5-o#jbCX{m_Uu zC`Bb|(S)q)CHu{?ABs_q8Z@94xi@G_hzzPwhh}6Kn)OkFie29#`=JqS$h%QmJbQa@3#!t;oGwTS8<| zg*r4N`yS2uC_%-p?~?t{h&JRk(js>e%217Zv>@kR%?2n%C2G-xtotPU-LfBwQH~lk zpcT3IYfFd>s!)e!WIv!;A0?>R^*yp58qtQl2c<>sB9x&T^=LuPLz)dxib~X?30V(I z_IqVN6r&t9Xh17+TWtxEK^5xIjO<4=>!Sn}yS`8MLnGRd_o%eUU4$}JqaH2Dc}%kb zN>PbgG$E^#?DxxlC`LJI(12FtKCUexGN?iwnvwm4W_^^PV%HDIerQA+@}86yxr3U(X5XWRP6d8*$<6q zL*5`Qau=Zt)u=}ca-P*}fKpVV7EQ={PO?8N`=J=+s6hi-k^8*1gvg)@b!bNRs97H+ zsMz%*vL71JhP)S~MeZV$p&IpQLC%Ys4N!_o)S?MlFG==CWj_?795rY_D{?1o36Vh+ z>d=hrmo@971Qok}O!h+~+K~5(w8&kAGE}1;Ey#IQvjIv`iCQ!vYnJSf%YGEg>?fLLHis{kmp-l%QhQPsn~~L>uznkQTX%P=;#MqXjvOW&@O>618YT)|-<3 zN!bs@C`Sz%(2Cr*v?W9aRj5NVvftLMj}lbu`YG8Djc7yODlKvsp$yfiM+R^)s>`8qtQl_oYSdB9x&T z^=LuP2bv8~ib~X?30WUX_Ge{36r&t9Xh17+tph)936Vh+>d=hr12pTS1Qok}PWD41 z+K_jkw8&kAGE}1;Eyy`YvjIv`iCQ!v%a-iV%YG?fLLHiseTZg# zl%QhQFUWpqL>uxBl@_^+P=;#MqXjvRW&@O>618YT)?t$UMcEIzJLhP-2>MeZV$p&IpQLC&$74N!_o)S?Ml z$4T~AKKkzQC`LJI(12Ft9^B>L2Z(X5XWRP6e7*$<6qL*A*< zB6ktWP>p)DAScjlfKpVV7EQ=HO|ris`=J=+s6hi-k$bwfgvg)@b!bNR8JhJ`f{IpaQ+j_ikGl%oa>Xhm+U zEg>?fLLHiseZFRWl%QhQ@5+8?L>uxhkQTX%P=;#MqXjt^YBoSADp89jWF?aQJ=qV% zC`Sz%(2CrPv?W9aRj5NVvM<)Gj}lbu`hD3Cjc7yOCDI~y5z0`FdbA)X)og%LRH7D5 z$huUrfAEQq_CqnsQG*7wBKId=hr%Qfqx1Qomf@T2!VfJU?-&q#~hMJPix z>d}InD>NIR6qTq&6SA(9>>tT~C`LJI(12FtUZpJ|GN?iwnvtDp)<+2{cKxyJheos^ z?`mn0y9i~dMm<`PbB$&Ll%f)~XhPPtlKm6e55*`)4I0pj++15iWKe}VG$Z>u&H5-o z#jZb<{m_UuQKwABs_q8Z@94xi@M{hzzPw zhh}8oq*)&&sMz)AvL71JhP<1lMeZV$p&IpQK~AaJ0HvrzEt-&Zi)8;o_CqnsQG*7w zBKKBp36Vh+>d=hr+cfK=1QomfQuae5+K^XCi`+#hLpAErf}Gnm8=w@Gs6`X9?vU(X z$$ltCIcm^=R^;BPEg>?fLLHisU2E1y2`YB|wd{vRv?1> z618YT);*H_8`%%VC`Sz%(2CqfTS8<|g*r4N`(DlZC_%-p|IY(`#{nzH?H+&TdG_9W zoW1v+&)IwL^X$F%p5cdXLbwq^2qA30vJ2<50j16q;uh_(bMMHTAM zjLf5&^-zq8T|X%Mp%HD!eN0;9E<_osQI8g6x0>})f=bk)30aRz_J?FY6rmh7Xh17+ zp3s&6rKmz3nvr=@vmT03vFnFrKQy8Zxt+AgU5GMNqaH2DeoC`GN>GVfG$HG0$^MA! zha!}t1`TLM&NJE)pcGZ8Lo+hHW<3<6V%Lw#erQA+a-WqJxeHN-YSg0z+0SX#M+quX zizZ|}FWDcH{ZNE*)Sv;a$QiUHKq;zFhh}76(5#1IRP6e3*$<6qL+*>xB6lImP>p)D zAp0fF`Y1sqYSDzOQL;ZF`=JQss6hi-k@K>)1Smxn>d=hLE1LCCjEY@9Df^)jZODC9 zTI4Q78LCl_7GzJF^-+RK)S?MluSxc&WIq(495rY_D{@}fmH?%wLLHisc|)@viczua zr@!pe{m_UuOX;e)k}XP>vcjpcOf9YfFGq zRG|*d$Sj)mP>hOQKl|zX4xtfk$bCmz0Hvrx9h#AOU$Y*HQL*diWj{2c4Y?mki`<1MLpAErg6t19>!Spfs6`X9 zHp%{i?1v(hqXrFVMb1as5}*`Ss6#U{A8Xb_F)DWbqU?u8v?2EsX_31SWvE6yT99oW z@mbbK2`W*GCS)BZ*SpaHGOIb2%;l%fiCXh!A;&3Y(C#janL{m_Uup)DAo~Q(`Y1sqYSDx&SF*n$`=JQss6hi-k#nN9 z1Smxn>d=hLNt*RgjEY^qDf^)jZOA=YTI4Q78LCl_7GxjPtd9~@q83faIz_U-CHtWW z<)}deT9I?Awgf0e73$E8%xRkSP>hOQzb*Tr5pBrzq($yRl%X2+XhHVrn)OkFO4OnW zS!YQ0cVs^lp&T`6Kr3?2)Rq9Hs6ri@k?}R_p%@jrepmKGBifLAmbA!Sh%!{89xcc| zTeCh&P>EVJA?qB;{+{fIB9x;B4QNG9pe+GPQH44*BXh21Jrtv2*YC@IXha)w&yyCp z3sHt@)T0I2=WEtS2`W*GCS-+@{R7z#MJPuN8qkWI3$!IbDXLJ1W@IkZtcPM$?D|95 z4~=L;?nTlfcOlA9je4{oJJPI=5>%oVO~|@fvVSD|p$O%uK?7QmbBVSDC`A?O(2UHb zn)OhOid~lMheos^H!BDGyAGHA(1%oVO~|@hvPZ~%C_*`E z(12Ftq}mdo6ji80Gcwm`)I?ehhK_zO@gse=m zN6LOELOE*CfL7#OuPp&eQH44*BXfghJrtv2*HN+`8qtQ_8>L0=LX@Ez^=LtMu2~-? zs6;KAkad$}kCy#VgmToN0jq6&3rM&=gHdMHN4E?f3PBifK#NQ>NsC_^>s z(Sqz-HS41Um8eA%vTl>?0oe~lC`Sz%(2AVfwIx6)s!)e!WJ=9?C`QGuV`M)xq7Aus zNQ>NsC_^>s(SqzdHS41Um8eA%vhI@Xv9ceEP>vcjpcOflwgf0e73$E8%-x#xP>hOQ zj_iju%217Zv>?0Dtd9~@q83fadQh?_$bKk7Icm^=R^&XS zEdfeVg*r4N^RQ+;6r*C7EBm1lZOA<&Epiv44ArPd3$h>4td9~@q83fadQ`F}%6=$9 zIcm^=R^&XUEdfeVg*r4N(`wd3F)DVQB>SNeZODCGTI4Q78LCl_7Gyu6Ssx{+L@k<- z^`vA^mi!Spfs6`X9UXbi*vLA|2jv6$e6*(_zOMp^Tp$^T+yrfwV#i-cj$$n@= z8*)c!k-HFOs75_nko~e|eUzXQwP-@tE0R53_CpcMQG*7wBIi|Y2~dhE)S(%fNwXe` zQL*a`*$<6qL+)$RB6lImP>p)DAp3RA`Y1sqYSDzOHza$e?1v(hqXrFVMb4}(0ZLJY zIy58mre-}9qhgmY`=JqS$bCy%L$lp&1#=eD(ql#i-bIp6rK4v?2E}X_31SWvE6y zT9AFXW_^^P618YT))A6DU-m;0%29&`v?9l7OMp^Tp$^T+9I06k#i-a7%6@1>8*-15 z7P$*ihHBKK1=&Yy)<+2{QHv&I*^<3L_CpcMQG*7wBIkg%1Smxn>d=hLF`D&IjEY?s z%6@1>8*-187P$*ihHBKK1=)^feUzXQwP-@tagx1A_CpcMQG*7wBIkH*2~dhE)S(%f z6Ey3g7!|uB*$<6qL#`_=au=cu)u=}cvQN~kj}la(7EQ=HNwOEqekejYYS4gIp)DAp2C!`Y1sqYSDzO(L$lp&6M-vmT03vFj??4~=L; z?#0p~cOlA9je4{o`x4FiC_yD^(S)o^C405(ha!}t1`TLMPOL2fN>PP6G$V7FW<3<6 zVpl5rp%HD!y~*pqicpRkG@unZ z*J?|EQdFT1&B$D*Sr5gi*pqEyjv2mjc7yeP0}KFA<9sVdbA+>X3hF2K_zO@ zgsfX6d!y`!B9x;B4QNG9p)CPQQH44*BXg@}Jrtv2S1$XZ5pBr5Oa14j}~O# zu2~-?s6;KAkX1_dCfN@~C`Sz%(2ATpv?V|(s!)e!WbV|ghhkLhx>@!^BifLAm$b-T zh%!{89xceOH0z@Tm8eA%vhJ4bEwUeqP>vcjpcOgyXiI=nRG|*d$lR-055=h1Rmgs5 zL>qEzX_31SWvE6yT9AF8W_^^P618YT*8P&bRrW&>%29&`v?AvLZ3$3{D%7DFnMSi7 ziczuaHrWr2XhZIU(js>u%217Zv>^K-&H5-oC2G-xtcN9gyX=P|l%oa>XhqH;Z3$3{ zD%7DFnMXA1p%@jrO4$#MXhZI!(js>u%217Zv>^L2&H5-oC2G-xtX8sj$bKk7Icm^= zR^&XcEdfeVg*r4N^MqzS6r*C-ow6Sq(T3b7rA6*Sl%X2+XhC+TSsx{+L@k<-^^|1q zlKoJGa@3#!t;l&=TLP4#3Uz2k<{8a;C`QGuO7=q|+K}5zi`<1MLpAErg6wBC>!Spf zs6`X9o|Ej|vLA|2jv6$e6*p)DAp2F#`Y1sqYSDzONwW9JekejYYS4gI~}QlqXdL$lp&6NvH0z-l6}t|}erQA+azB<9xeHN-YSg0z*`H|EM+quXizZ}Q zM}GRrvScjc7ye5z-=eA<9sVdbA+h zXx2vwDp89jWF0Bl$7DYgp&T`6Kr3>N(v|?Fs6ri@kvUqk9*R-1tCjuGh&JTf(js>u z%217Zv>^L{W_^^P618YT)-jTOT=qi|%29&`v?AwNZ3$3{D%7DF8Ar1oiczua3E2;g zXhZIC(js>u%217Zv>^L<&H5-oC2G-xtP>>rr0jXhn{zEdfeVg*r4NbE0NF z6r*BSC;OohZOA=ITI4Q78LCl_7G$5SSsx{+L@k<-bx^WT$$lt8Icm^=R^*(bEdfeV zg*r4NbE;-N6r*C-)3P5L(T3d9q($yRl%X2+XhF88Ssx{+L@k<-b-HAqk^NAFa@3#! zt;jh;TLP4#3Uz2k=1k3cC`QGuUiL#H+K}r@i`<1MLpAErg6y+2>!Spfs6`X9&X(-6 zvLA|2jv6$e6*=cp)D zAp0WC`Y1sqYSDzONU|@;ekejYYS4gIbM#ZjC z_Cq7ukef)0+=VDZHR{oV>?<|vqXdL$lp&6O$HS3`m6}u+c4~=L;?hVo+cOlA9je4{o`$oPP6G$V7fW<3<6V%O`k9~#ky+*_nY?n0EI8ue&FcA;4xC8$I#nviv? zWZ#heP=s>SpaHGOxlLOFl%fiCXh!CC&3Y(C#jaWQLnGRdTS|-Eg(yQc>d}JiJ2dN~ z1eK^o6SD4!BDGyB66Gjc7ye z{n8?LA<9sVdbA+>0nPd-K_zO@gseug@5p{ALOE*CfL7!@s4W3XQH44*BlD1EJrtv2 z*SoSG8qtQ_howdCLX@Ez^=Lu%A8qtQ_R$AmPL>a14j}~MEVJA?q2*ekl8) z2<50j16q;OYfFGqRG|*d$ULiA55=h1waI>HL>qFSlNPxPQHE;NqXpT|Yt}~zDp89j zWDS!2NcKY!%29&`v?AvPZ3$3{D%7DFnHM$dp%@jrK9>E^h&JTDBrS3mq72ojM+>q? z&H5-oC2G-xtd}MGiR_0Wl%oa>XhqH|+7h4?Rj5NVGOudZLovEl^toUDIp6n);$_80 ziW8^LZZ1$p)DAbZoS zj}la(7EQ?dNU~of`=JQss6hi-k@K;(1Smxn>d=hLCz|z8jEY@fEc>AmZOFBb`t(2K zE<_osQI8g6AEsF!C8$I#nviw4WWPlALlMeRg9fxB=Ll^HP>L$lp&1#YSr5gi*!88d z9~#ky+#{t$?n0EI8ue&F_EDPkQG!a;q6t|?OZLlTKNO)HHE2L9a%^o0P>L$lp&6M2 zn)OhOid|nW`=JqS$UR0{r}~pjqHaal%oa>XhqIx+7h4?Rj5NVGM;8V6r*C-*UElqL>qEXmlnATQHE;NqXpS# zXx2vwDp89jWSuG5uao^ygmToN0j9L@SDK_zO@gseca-yr*;2<50j16q-DuC@dyMHTAMjLdnO^-zq8UEe7C zp%HD!JzrYnE<_osQI8g6hnn?Kf=bk)30W6N_M2os6rmh7Xh17+F4UF)rKmz3nvuCk zvmT03vFn>GVfG$HE}$$pFMha!}t1`TLM&ZXKC zpcGZ8Lo+h5W<3<6V%N9IerQA+axaq>xeHN-YSg0z*_Uh9M+quXizZ}UA=z(}{ZNE* z)Sv;a$Vs#%Kq;zFhh}81)U1bMRP6e8*$<6qL+(}5B6lImP>p)DAp2^~`Y1sqYSDzO zRI=Y8`=JQss6hi-k#mi<1Smxn>d=hLwVL%%jEY^~Df^)jZOFY&TI4Q78LCl_7G!6d z^-+RK)S?Ml*Gu-hWIq(495rY_D{^komH?%wLLHisxlywoiczuayJbH#q7AvZw8&kE zGE}1;Ey%t}vpz~tiCQ!v>t@M*kL-scl%oa>XhqH~+7h4?Rj5NVGKFS66r*C-_sV`~ zL>qE%l@_@RQHE;NqXpTwY1T&xDp89jWZf>=KQ8;B2<50j16q+&YD<7pRG|*d$lRe> z55=h1^(SOMG@=c;cS?)gg(yQc>d}JiyEN;g1eK^o6S6AF{z=&nMJPuN8qkWIyR{`i zDXLJ1W@PTstcPM$?D|u(9~#ky+oLjxdD#y|C`Sz%(2AT^TLP4#3Uz2k=5ft>C`QGuzaaae5pBqQLR#c5 zL>a14j}~MLOE*CfL7!@r7ZzUQH44*BlEOoJrtv2*I$zT z(14 zvmT03vFoqMerQA+atCRVyAWllMm<`P{eotFl%Nu|XhPPDlKrc)ABs?p8Z@94IWK8T zfKpVU4$a7nn)OhOid}zA_Cq7uko&T<$X$psRHGg($bLn$K1xuDS~MZ+RmuK!*$+i1 zM-3X#ikwMX0+gZ(b!bNBHO+b`M#ZkbA^V{bZODCHTI4Q78LCl_7G%GnSsx{+L@k<- zHB0ty%6=$9Icm^=R^+^?EdfeVg*r4N^Oj~k6r*C--;({%h&JTDEiG~vq72ojM+>qS z&H5-oC2G-xtal{)w`D&Rp&T`6Kr3?I)s_IIs6ri@k$F$E9*R-1>+i^ZXha)wS80*E z5M`)FJz9|czGi)tpc1ucLe>Y8{kyUsicpRkG@unZA8Jd0QdFT1&B$z;^-zq8U4KvZ zLnGRd`;oNBU5GMNqaH2D{#dgGVfG$HE~$^L!W4@D?P4I0pj9P8-MS^|`!3Uz2k z<}l5AC`QGue<1sz5pBplTw3HVL>a14j}~Mfp;;d#s6;KAkYyzM4`n|Tp&T`6Kr3>N z)Rq9Hs6ri@kvU4U9*R-1>mSK}Xha)wkCqm>3sHt@)T0I2wq|{lpc1ucLe>Gv{$tq> zMJPuN8qkWIW3(keDXLJ1W@L`ltcPM$?D{9N9~#kyTt`~uE<_osQI8g6AE#L#C8$I# znviw8WWP`LLlMeRg9fxB=LBsDP>L$lp&1!hvmT03vFo48erQA+a!-^NxeHN-YSg0z z*(Yh%M+quXizZ~9EZKi1`=JQss6hi-k#kU60+gZ(b!bNB6wP`lM#ZjwF8iSoZOA=U zTI4Q78LCl_7G$5MSsx{+L@k<-rj&H5-oC2G-xtg|HhuVgtD-$Xha)w18I@F5M`)FJz9``u4a9dpc1ucLe_bb{Wr27icpRkG@unZ z=W9!VQdFT1&B%nB^-zq8UH?}0LnGRddx5mbU5GMNqaH2DzEHD1N>GVfG$HFE$^JXp z4@D?P4I0pjoJd;&l%fiCXh!B@&3Y(C#jbxZ`=JqS$h|~bN|%HsoF*Epiv44ArPd z3$hc<`Y1sqYSDzOD<%7%WIq(495rY_D{`*VmH?%wLLHisxmvRxiczuaKg)h-L>qEb zX_31SWvE6yT9AE>W_^^P618YT*0qxTFR~wsP>vcjpcOgSX-j}oRG|*d$Yh%JP>hOQ z|5f%wBifLAy|l<(h%!{89xceeL9;$eP>EVJA?rrT{x{hVMJPuN8qkWITw4N^q6&3r zM&>5XdMHN4uKzCkp%HD!y;)l1E<_osQI8g6-=bL`C8$I#nvhjU_J7EJC_*`E(12Ft z+^Q`BN>PP6G$V7HW<3<6V%Pta{m_UuTT) zKNO)HHE2L9a_-cY0Hvrx9h#B3OS2w|QL*cP%YJA?8*(dYk-HFOs75_nkbSpieUzXQ zwP-@tJ(B%DvLA|2jv6$e6*>26OMp^Tp$^T+)SC5BjEY_VSN20A+K_vnw8&kEGE}1; zEy%uKvpz~tiCQ!v>jBCBKiLmOC`Sz%(2AT!TLP4#3Uz2k=0VMRC`QGu@0b11h&JRt zBrS3mq72ojM+>qa)~t^bRH7D5$T}q1ACUb}gmToN0jL$lp&6N8vmT03vFk@=KQy8Zxz9?A+=VDZHR{oV?B_J=qXdN|%Hsro4Epiv44ArPd z3$iE8`Y1sqYSDzO*ChK>vLA|2jv6$e6*;eKOMp^Tp$^T+yrEeS#i-cz)3P5L(T3bv zTI4Q78LCl_7G%GvSsx{+L@k<-^_FCRM)pGy%29&`v?AwiZ3$3{D%7DFnMJc6iczua zXJtP$q7Aw4NQ>NsC_^>s(Sq!EHS41Um8eA%vfh*I&&hr$LOE*CfL7$J+7h4?Rj5NV zGVg2FLoq6L{k-glMzkUK18I@F5M`)FJz9|cp=N!Qpc1ucLe?hPUy%J!gmToN0j(1qj}la(7EQ=HOtQZu z`=JQss6hi-k#o4V1Smxn>d=hL5t{W-jEY^qEc>AmZOAp!B6lImP>p)DAp1zo`Y1sq zYSDzOqa^z)vLA|2jv6$e6*)(1OMp^Tp$^T+*qZfFjEY^qD*K@kZOA#`pj(T3dP zrA6*Sl%X2+XhHS~n)OkFO4OnWS*~P%L-s=v%29&`v?Aw3Z3$3{D%7DFnUgf@p%@jr zepB{CBifLAvb4xuh%!{89xcc|s97H+s6;KAkadb=e@pg55z0}62DBpQRBZ`RiYnBh z8JW{G>!BDGyM9~tLnGRd>q(2;g(yQc>d}Ji(>3d(1eK^o6SB^b?C;2aC_*`E(12Ft zoT)7VN>PP6G$Z3{)9_CpcMQG*7wBIgoq2~dhE)S(%fOEv4E7!|uL*$<6qLvAcB zau=cu)u=}cvMyT(XDBekejYYS4gISpaHGOxn5fW zl%fiCXh!A+&3Y(C#jc}dKQy8Zxi?CS+=VDZHR{oV>|C=xN>GVfG$HFI$sR5Hp$O%u zK?7QmbF;PtC`A?O(2UG2n)OhOie0wsheos^w~!XO3sHt@)T0I2w`$f$2`W*GCS=_v z*#oj4icpRkG@unZw`)s)QdFT1&B&CR^-zq8UB}3NXha)w?~oR`3sHt@)T0I2cWTy0 z2`W*GCS=_u*<)ot6rmh7Xh17+Ds2f+iYnBh8JW8^>!BDGyBygMjc7yeJ<=j~A<9sV zdbA+>Ud{R_K_zO@gsfV!$H{&uLOE*CfL7$(r!4_WQH44*BXhrIJrtv2*YUC+8qtQ_ z2c$*rLX@Ez^=LtMqgfv%s6;KAkoBNsPmujkgmToN0ja14j}~MEVJA?r!Wo-F&J2<50j16q;O zX-j}oRG|*d$ULQ455=h1bx`(0BifMrw6w@wh%!{89xcdzMzcOjP>EVJA*+|{DY74m zP>vcjpcOgKYD<7pRG|*d$ULW655=h1b*k)#MzkUKd1;Zm5M`)FJz9`GXx2vwDp89j zWW6BS(_}vsp&T`6Kr3=y)Rq9Hs6ri@k$Fk89*R-1%ai@kh&JSo(js>u%217Zv>^Ls z&H5-oC2G-xtXCv^y6lG{l%oa>XhqJe+7h4?Rj5NVGLvRK6r*C-8L}T5(T3dDq($yR zl%X2+XhHVtn)OkFO4OnWS#L=8OxX`bC`Sz%(2AT{TLP4#3Uz2k=1t9dC`QFDU-m;I z+K~H}w8&kEGE}1;Ey#Xbvpz~tiCQ!vYmw|(vLA|2jv6$e6*=!{OMp^Tp$^T+ysKFc z#i-bIw(N&Sv?2FBX_31SWvE6yT9CbJ)<+2{QHv&Iy)W5wWIq(495rY_D{?;2mH?%w zLLHis`B1YSiczsEkp0kzHso&7B6lImP>p)DAp0ZD`Y1sqYSDzOk0pDq?1v(hqXrFV zMb0PM5}*`Ss6#U{)`8Dn;Gq~5yUvsS(1%oVO~^Vz zvggZwC_*`E(12Ft7;OnqiYnBh8JQzB>!BDGyF%Fyjc7yeQPLuJA<9sVdbA+>XwCX4 zK_zO@ge+UK7s!4nLOE*CfL7!j(3SwDs6ri@kvT@Q9*R-1>q6NNjc7yevC<-UA<9sV zdbA+h(X5XWRH7D5$U0847s-AoLOE*CfL7!juPp&eQH44*BXfdgJrtv2S0wwP5pBqI zrA6*Sl%X2+XhHUgn)OkFO4OnWStm*MV%ZNxC`Sz%(2AUswIx6)s!)e!WDaW9Loq6L zT_XFT5pBplMOx%8L>a14j}~N~s#zZ;s6;KAkae15FO~gJgmToN0jNsC_^>s(SqzVHS41Um8eA%vV6&2Ci|fX<)}deT9I>> zwgf0e73$E8%-NdtP>hOQm&<-=L>qF?krufNQHE;NqXpT4W_^^P618YT*13|sLiR%u z%29&`v?Av`Z3$3{D%7DFne#R4p%@jr64?)pXhUu&Epiv44ArPd3$icJtd9~@q83fa zx=^xL%6=$9Icm^=R^(iyEdfeVg*r4N6KU2%F)DUlCHtWfZOFY?TI4Q78LCl_7Gz(d zSsx{+L@k<-b*W^pmi!Spfs6`X963Jd8`=JQss6hi-k#nWC1Smxn>d=hLRhsosjEY^?%6@1> z8*;Cf7P$*ihHBKK1=*=)eUzXQwP-@tHIltf_CpcMQG*7wBIjCd2~dhE)S(%f>on`3 z7!|uR*$<6qLvAK5au=cu)u=}cvai>yj}la(7EQ>yL9*A&ekejYYS4gIL$lp&6NbHS3`m6}t-A4~=L;ZY?cx7orT+s7DL3 z@6)W05>%oVO~|@mvbV~9C_*`E(12FtJfJNBN>PP6G$Ye!)SpaHGOIixKCN>PP6G$ZqfW<3<6Vpl2q zp%HD!eN_72$(MJPuN8qkWI$F(IuDXLJ1W@Mhw ztcPM$?7CC-LnGRd`=qqUU5GMNqaH2D?lkM81eK^o6SAI?>|L@SicpRkG@unZPisqn zQdFT1&B#2XSr5gi*j34XXha)wdufro5M`)FJz9|ctY&?bpc1ucLe_JVy<7G}5z0}6 z2DBpQd2I<$iYnBh8JR(|9*R-1>mJz;jc7ye3(_KYA<9sVdbA+>Ma}vsK_zO@gshh& zd#~(=B9x;B4QNHqs4W3XQH44*BlEImJrtv2S1tRY5pBqQMOx%8L>a14j}~OVs#zZ; zs6;KAkTps6KG_dNC`Sz%(2AVbv?V|(s!)e!WM0>-hhkLhx?lD~BifMrhP23Ch%!{8 z9xce8HS41Um8eA%vfh;J1F|2AP>vcjpcOf9X-j}oRG|*d$h@st55=h1)yRHmL>qD! zX_31SWvE6yT9EyYW_^^P618YT*1M8@Q1(L+%29&`v?Av{Z3$3{D%7DFnN_nMiczua zA=wX&XhZJ%(js>u%217Zv>^Kf&H5-oC2G-xtPdsouXhqJZEdfeVg*r4N z^O0sf6r*C-A=wX&XhZJD(js>u%217Zv>^Kv&H5-oC2G-xEbEw0zx#;nha!}t1`TLM z&SBaTpcGZ8Lo+gmYt}%oV zO~^V%vX9GtC_*`E(12Ft9IGt>N>PP6G$Z3^)SpaHGOakV8tDXLJ1W@Jv(tcPM$?CNAcG@=c;CrOLk zg(yQc>d}JilQrw31eK^o6S59U_9@v9MJPuN8qkWIQ?w;ODXLJ1W@Jv)tcPM$?0Q=E zLnGRddz!S!U5GMNqaH2D_B89G1eK^o6S7X1>@%_-icpRkG@unZXJ|`+QdFT1&B&ao zSr5gi*wxE^Xha)weQA-q5M`)FJz9``mS%mFpc1ucLe|-meOC5E5z0}62DBpQ9Bm0u ziYnBh8JR${9*R-1>p9sEjc7yexzZwcA<9sVdbA+>Jk9zjK_zO@gsk%=`@HOjB9x;B z4QNG9s4W3XQH44*BXfafJrtv2*C6|$5pBr5P+H_JL>a14j}~NKq*)&&s6;KAkQGVx z1=$ZpC`Sz%(2AUkwIx6)s!)e!WG>OHhhkLhdQtX6BifLAskF#lh%!{89xcd@HS41U zm8eA%vM!VCOR^t|P>vcjpcOfnYfFGqRG|*d$XuaW55=h1HOhWyL>qDwX_31SWvE6y zT9AFEW_^^P618YT)>V>yS@uH_%29&`v?AwfZ3$3{D%7DFnN+hLiczua71u%217Zv>^Lh&H5-oC2G-xtm`EEs_cg%l%oa>Xhlw@EdfeVg*r4NbG>Fg6r*C- zB>SNeZOFYrTI4Q78LCl_7G&S3Ssx{+L@k<-l}q+D*$+i1M-3X#ikzFYB|s^vP={t@ zZq}@aVpQyUUG_sG+K_vTw8&kEGE}1;Eyyl3>!Spfs6`X9Zk6mCvLA|2jv6$e6*;$Q zOMp^Tp$^T++^$&<#i-ad%YJA?8*)o&k-HFOs75_nkbQ?{eUzXQwP-@tosxZ1_CpcM zQG*7wBIhn`2~dhE)S(%fO0yn{QL*bS*$<6qL+;(uB6lImP>p)DAp0K8`Y1sqYSDzO zdnNm}?1v(hqXrFVMNX|P0ZLJYIy575pJqK2qhi-0`=JqS$h}`$L$l zp&6NHHS3`m6}vXs4~=L;?sL*2cOlA9je4{o`+3d!C_yD^(S)o)vLDHQC_*`E(12Ft zyr3-sN>PP6G$Zq(W<3<6V%NvA9~#ky+?S+9?n0EI8ue&F_NZAOC8$I#nvnIfWIvJp zP=s>SpaHGOc|}_Sl%fiCXh!B$&3Y(Cw~9XZD?aD@9#Ook_(*Z$^x4e?it82kDV|ll zqd4%|XQ{IkS1RsMJg#_6VZAP|l?NR}5z0}62DBpQ4Q&ZfiYnBh8JStL9*R-1>+?Q+ z-yt-j4Y_Yhi`<1MLpAErg6y|6>!Spfs6`X9-j?j=%YGJbIa@3#!t;l&_ zTLP4#3Uz2k<^#=oC`QGuKPLO35pBr*P+H_JL>a14j}~Nan)OkFO4OnWSszLEi)23( zp&T`6Kr3=S)|LRJs6ri@k@-Zk9*R-1>x*SSG@=c;*0G=dhunoILpAErg6zXI>!Spf zs6`X94wvkg$bKk7Icm^=R^%L^EdfeVg*r4NV>Iib7!|v|RQ5w7+K_vsw8&kEGE}1; zEyzAfvpz~tiCQ!v>uAY-ne2xml%oa>Xhn{#EdfeVg*r4Nb3n5miczua%Vj?_q7Avn zNQ>NsC_^>s(Sqz_HS41Um8eA%vK+~Nh3tnSl%oa>XhqI(+7h4?Rj5NVGRJGyLoq6L zeWmP&MzkUK1Zk1G5M`)FJz9|MYSu>yDp89jWSuD4uaf;xgmToN0jSpaHGO zIZayvl%fiCXhz1`W= z7P$*ihHBKK1=$yC)<+2{QHv&IT_V|Uk^NAFa@3#!t;o4lTLP4#3Uz2kCf2NnVpQz< zR@o1YXhZI0(js>u%217Zv>^L(&H5-oC2G-xtScn@ZL%MVP>vcjpcOfZwgf0e73$E8 z%$1t;P>hOQ-!A*15pBr5N?PPDL>a14j}~NKtyv!>s6;KAkd;dIJ7hl;p&T`6Kr3>t z(Ut(Es6ri@k-1j09*R-1>pNvXG@=c;*GY@qg(yQc>d}JiOtU^pP>EVJA?td{ewXZr zB9x;B4QNHq4cZc*6ji80Gcq@7)SpaHGOxkXz7l%fiCXhx>ctcPM$?D}5W4~=L;?yb@ycOlA9je7L| zd7#fYaK*6gM@nABs_d3>wgi+)7(Ql%X1RXh!y}n)OkF%3Yr* z`=JqS$h%Ei)S(&K_iENh2`YDes_chGv?0$(i`+#hM-A%Hf}Hy_8=w?bs6`X9?w9PR$$ltC z1u|$rD{>#umJnsAMje`w{h(%jl%R6gr^|k5L>uxRk`}p(P>veZqXjt+Yc@bBs!)q2 zWIZC;&yf94j0$AXfL7$T+7hA+)u=-=vLDr~j}lbw`b^mmjc7yOW6~mb5z0}6dbA+t zam@xOMHOn%gse`opC$XD7!}B%0j&Ym^qLJ&iYnBi30Y4|_H$%E6r%zeG@uo^&uB}CGE}1u&B%UMvpz~tx$ARf zKQy8Zd4sgbU4(MfpdKyAc}}wdN>PPcG$HGG$$p;fhhkJ9g9fxB_XTYUQHE;Np&8ku zW_^^Pa@Xg}erQA+@?Mk{xr2p(X5XWRPOph*$<6qL*A>>B6ktWQGAmZOD65TI4Q5IciXk7UV3N4N!_I)S?Ml zZ%Ot`WIq(60vR-*6}fL~ONcU5qYll;en+!DN>I7$OJzSaq78Ygw8&kAa@3$6Ey#IS zvjIv`g<3Qr>pjVSne2yRR3L)}v?BL?Z3$6^YSf__*_&p4l%R6gm&<-=L>uxxkQTX% zP>veZqXju1YBoSAs!)q2WPK#ruaNyvj0$AXfL7#M?#C@5%216uG$Z>U&H5-o<*u)k z{m_UuqCHqyfABs_d3>wgi+(We`L>a14hh}6S zrdb~)sND6{vL71JhP=b2MeZV$qXzY8L5`!@0HvrxEt-&Zgk--)_Cql$kU;}lk$a@J zgeXHb>d=hrqcrQI1eLqKR`x?9+K}f;i`+#hM-A%Hf}Eo@8=w?bs6`X9j*;xw$$ltC z1u|$rD{_z3mJnsAMje`w?P=CW2`YDez3hiZv?1?+w8&kAa@3$6Eyy`evjIv`g<3Qr z>v+k2gY1W5R3L)}v?BKeZ3$6^YSf__*(Yk&M+qu-eWUD$MzkUCBx#Ym2<50jJz9`+ zvStI6q6)QWLY6PtZ<75`j0$AXfL7$5qAelHP>nh?Bl}d%`Y1u=u5Xt8(1&YmoTb?SrKmzJnviw2WWP=JLoq6lK?7Qmdyck*C_^>s(2VRz zvpz~tx$E0yKQy8ZdFM)t+(jry4eHT?obxmrpcGZ8MH8~lm+W`Qekeu-GH5_6a${`? zQHE;Np&8j1Xx2vwDtCRS?1x6QA@4$Ik-G@xs6jnikaLk{1C*i)wP-?CBH8bf{ZNbw zWYBy|Nz~(T2QCTI4Q5IciXk7UW#1 z*#M=eLM@t*b(LhlPxeDGDv&_~T9JFTwuC4{HR{le>|C=xN>I7$`(-~gq78Z1NQ>M> zC`S$I(Sn?7H5;H5Rj5T1vaXZt56FHfMg=lxKr3nh?Bl~8} z`Y1u=t{;~D(1&Ym+@aY3rKmzJnviv;WPeQdLoq6l zK?7QmdzZF^C_^>s(2VRxvpz~tx$DPeKQy8Zd3Q^T+(jry4eHT?oO?7IpcGZ8MH8~_ zmF!Q*ekeu-GH5_6a*eixC_^>s(2VT+H0z@TmAigY_Cq7ukaxed$X$eT)Sw)S(&K4{O#(2`YE}wCsmQv?1>iX_31K z<)}eDT9DIfHb5z=P>UvHJu2Csk^NAN3S`iLR^&dWEg{NKjXE?V`*F?sC_&|}pOyX4 zh&JSP(js>e%29)Qv>@jR%?2n%6>8ChtS2S=bFv?bQGpB^(2Crrv?W9ts!@k#WcQl& zQG&`{KQH^C5pBqOT3X~TLOE(sj~3)SquBtZs6s88koBx&e?j&`F)ENj16q+gXiJDP zRHF{f$bL?lbA|G@=c8&r6HkMJPuN>d}In7c?876ji826S79h{*vs6VpJf5 z2DBpgMQsUDhHBKI8QCvs)<+2{cm1;Lheos^?`3I`y9ni|K|NZKGif$JDXLJ5CS<)L z*c#>(12FtzN#%D%216uG$Z>p&H5-o<*r|q{m_UuQW!ABs_d3>wgi+&8r)L>a14hh}6in)OkF%3Z%M`=JqS$a_m#)S(&KA8OV| z2`YE}w(N&Sv?1>!X_31K<)}eDT99KM{c$!xDXLJ5CS)BX+24`

    M%jABs?p8Z@94xrw#}C`A?O(2VR$HEU3eid|nQ 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

    c#>(12Ft9;_`P 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

    !-4-?$~Odmik$24XgNGUjZOR> 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
    heZZ7z=3?e%>fNh)@l@v8=#|;m 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¥wtx|6#jv8v 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°5SQB*H4xXxu+CD|0#`97v+ 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 z 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 F{{c6qk!=6~ diff --git a/internal/dwn/gen/init.pkl.go b/internal/dwn/gen/init.pkl.go deleted file mode 100644 index 9cea869d9..000000000 --- a/internal/dwn/gen/init.pkl.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated from Pkl module `dwngen`. DO NOT EDIT. -package gen - -import "github.com/apple/pkl-go/pkl" - -func init() { - pkl.RegisterMapping("dwngen", Dwngen{}) - pkl.RegisterMapping("dwngen#Config", Config{}) - pkl.RegisterMapping("dwngen#Schema", Schema{}) -} diff --git a/internal/dwn/wasm/main.go b/internal/dwn/wasm/main.go deleted file mode 100644 index 32f6b8a68..000000000 --- a/internal/dwn/wasm/main.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build js && wasm -// +build js,wasm - -package main - -import ( - "encoding/json" - "os" - - "github.com/labstack/echo/v4" - "github.com/onsonr/sonr/internal/ctx" - "github.com/onsonr/sonr/internal/dwn/fetch" - dwngen "github.com/onsonr/sonr/internal/dwn/gen" - "github.com/onsonr/sonr/pkg/workers/routes" -) - -const FileNameConfigJSON = "dwn.json" - -var config *dwngen.Config - -func main() { - // Load dwn config - if err := loadDwnConfig(); err != nil { - panic(err) - } - - // Setup HTTP server - e := echo.New() - e.Use(ctx.DWNSessionMiddleware(config)) - routes.RegisterWebNodeAPI(e) - routes.RegisterWebNodeViews(e) - fetch.Serve(e) -} - -func loadDwnConfig() error { - // Read dwn.json config - dwnBz, err := os.ReadFile(FileNameConfigJSON) - if err != nil { - return err - } - dwnConfig := new(dwngen.Config) - err = json.Unmarshal(dwnBz, dwnConfig) - if err != nil { - return err - } - config = dwnConfig - return nil -} diff --git a/internal/orm/transactions/Msg.pkl.go b/internal/orm/transactions/Msg.pkl.go deleted file mode 100644 index fe8ffcc9a..000000000 --- a/internal/orm/transactions/Msg.pkl.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -type Msg interface { - GetTypeUrl() string -} diff --git a/internal/orm/transactions/MsgDidAllocateVault.pkl.go b/internal/orm/transactions/MsgDidAllocateVault.pkl.go deleted file mode 100644 index 0e691f461..000000000 --- a/internal/orm/transactions/MsgDidAllocateVault.pkl.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgDidAllocateVault interface { - Msg - - GetAuthority() string - - GetSubject() string - - GetToken() *pkl.Object -} - -var _ MsgDidAllocateVault = (*MsgDidAllocateVaultImpl)(nil) - -type MsgDidAllocateVaultImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Authority string `pkl:"authority"` - - Subject string `pkl:"subject"` - - Token *pkl.Object `pkl:"token"` -} - -// The type URL for the message -func (rcv *MsgDidAllocateVaultImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgDidAllocateVaultImpl) GetAuthority() string { - return rcv.Authority -} - -func (rcv *MsgDidAllocateVaultImpl) GetSubject() string { - return rcv.Subject -} - -func (rcv *MsgDidAllocateVaultImpl) GetToken() *pkl.Object { - return rcv.Token -} diff --git a/internal/orm/transactions/MsgDidAuthorize.pkl.go b/internal/orm/transactions/MsgDidAuthorize.pkl.go deleted file mode 100644 index b12fc046d..000000000 --- a/internal/orm/transactions/MsgDidAuthorize.pkl.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgDidAuthorize interface { - Msg - - GetAuthority() string - - GetController() string - - GetAddress() string - - GetOrigin() string - - GetToken() *pkl.Object -} - -var _ MsgDidAuthorize = (*MsgDidAuthorizeImpl)(nil) - -type MsgDidAuthorizeImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Authority string `pkl:"authority"` - - Controller string `pkl:"controller"` - - Address string `pkl:"address"` - - Origin string `pkl:"origin"` - - Token *pkl.Object `pkl:"token"` -} - -// The type URL for the message -func (rcv *MsgDidAuthorizeImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgDidAuthorizeImpl) GetAuthority() string { - return rcv.Authority -} - -func (rcv *MsgDidAuthorizeImpl) GetController() string { - return rcv.Controller -} - -func (rcv *MsgDidAuthorizeImpl) GetAddress() string { - return rcv.Address -} - -func (rcv *MsgDidAuthorizeImpl) GetOrigin() string { - return rcv.Origin -} - -func (rcv *MsgDidAuthorizeImpl) GetToken() *pkl.Object { - return rcv.Token -} diff --git a/internal/orm/transactions/MsgDidProveWitness.pkl.go b/internal/orm/transactions/MsgDidProveWitness.pkl.go deleted file mode 100644 index 8bb849194..000000000 --- a/internal/orm/transactions/MsgDidProveWitness.pkl.go +++ /dev/null @@ -1,52 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgDidProveWitness interface { - Msg - - GetAuthority() string - - GetProperty() string - - GetWitness() []int - - GetToken() *pkl.Object -} - -var _ MsgDidProveWitness = (*MsgDidProveWitnessImpl)(nil) - -type MsgDidProveWitnessImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Authority string `pkl:"authority"` - - Property string `pkl:"property"` - - Witness []int `pkl:"witness"` - - Token *pkl.Object `pkl:"token"` -} - -// The type URL for the message -func (rcv *MsgDidProveWitnessImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgDidProveWitnessImpl) GetAuthority() string { - return rcv.Authority -} - -func (rcv *MsgDidProveWitnessImpl) GetProperty() string { - return rcv.Property -} - -func (rcv *MsgDidProveWitnessImpl) GetWitness() []int { - return rcv.Witness -} - -func (rcv *MsgDidProveWitnessImpl) GetToken() *pkl.Object { - return rcv.Token -} diff --git a/internal/orm/transactions/MsgDidRegisterController.pkl.go b/internal/orm/transactions/MsgDidRegisterController.pkl.go deleted file mode 100644 index 99907f455..000000000 --- a/internal/orm/transactions/MsgDidRegisterController.pkl.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgDidRegisterController interface { - Msg - - GetAuthority() string - - GetCid() string - - GetOrigin() string - - GetAuthentication() []*pkl.Object - - GetToken() *pkl.Object -} - -var _ MsgDidRegisterController = (*MsgDidRegisterControllerImpl)(nil) - -type MsgDidRegisterControllerImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Authority string `pkl:"authority"` - - Cid string `pkl:"cid"` - - Origin string `pkl:"origin"` - - Authentication []*pkl.Object `pkl:"authentication"` - - Token *pkl.Object `pkl:"token"` -} - -// The type URL for the message -func (rcv *MsgDidRegisterControllerImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgDidRegisterControllerImpl) GetAuthority() string { - return rcv.Authority -} - -func (rcv *MsgDidRegisterControllerImpl) GetCid() string { - return rcv.Cid -} - -func (rcv *MsgDidRegisterControllerImpl) GetOrigin() string { - return rcv.Origin -} - -func (rcv *MsgDidRegisterControllerImpl) GetAuthentication() []*pkl.Object { - return rcv.Authentication -} - -func (rcv *MsgDidRegisterControllerImpl) GetToken() *pkl.Object { - return rcv.Token -} diff --git a/internal/orm/transactions/MsgDidRegisterService.pkl.go b/internal/orm/transactions/MsgDidRegisterService.pkl.go deleted file mode 100644 index d234865da..000000000 --- a/internal/orm/transactions/MsgDidRegisterService.pkl.go +++ /dev/null @@ -1,76 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgDidRegisterService interface { - Msg - - GetController() string - - GetOriginUri() string - - GetScopes() *pkl.Object - - GetDescription() string - - GetServiceEndpoints() map[string]string - - GetMetadata() *pkl.Object - - GetToken() *pkl.Object -} - -var _ MsgDidRegisterService = (*MsgDidRegisterServiceImpl)(nil) - -type MsgDidRegisterServiceImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Controller string `pkl:"controller"` - - OriginUri string `pkl:"originUri"` - - Scopes *pkl.Object `pkl:"scopes"` - - Description string `pkl:"description"` - - ServiceEndpoints map[string]string `pkl:"serviceEndpoints"` - - Metadata *pkl.Object `pkl:"metadata"` - - Token *pkl.Object `pkl:"token"` -} - -// The type URL for the message -func (rcv *MsgDidRegisterServiceImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgDidRegisterServiceImpl) GetController() string { - return rcv.Controller -} - -func (rcv *MsgDidRegisterServiceImpl) GetOriginUri() string { - return rcv.OriginUri -} - -func (rcv *MsgDidRegisterServiceImpl) GetScopes() *pkl.Object { - return rcv.Scopes -} - -func (rcv *MsgDidRegisterServiceImpl) GetDescription() string { - return rcv.Description -} - -func (rcv *MsgDidRegisterServiceImpl) GetServiceEndpoints() map[string]string { - return rcv.ServiceEndpoints -} - -func (rcv *MsgDidRegisterServiceImpl) GetMetadata() *pkl.Object { - return rcv.Metadata -} - -func (rcv *MsgDidRegisterServiceImpl) GetToken() *pkl.Object { - return rcv.Token -} diff --git a/internal/orm/transactions/MsgDidSyncVault.pkl.go b/internal/orm/transactions/MsgDidSyncVault.pkl.go deleted file mode 100644 index c4de4ba64..000000000 --- a/internal/orm/transactions/MsgDidSyncVault.pkl.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgDidSyncVault interface { - Msg - - GetController() string - - GetToken() *pkl.Object -} - -var _ MsgDidSyncVault = (*MsgDidSyncVaultImpl)(nil) - -type MsgDidSyncVaultImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Controller string `pkl:"controller"` - - Token *pkl.Object `pkl:"token"` -} - -// The type URL for the message -func (rcv *MsgDidSyncVaultImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgDidSyncVaultImpl) GetController() string { - return rcv.Controller -} - -func (rcv *MsgDidSyncVaultImpl) GetToken() *pkl.Object { - return rcv.Token -} diff --git a/internal/orm/transactions/MsgDidUpdateParams.pkl.go b/internal/orm/transactions/MsgDidUpdateParams.pkl.go deleted file mode 100644 index a3e227ab8..000000000 --- a/internal/orm/transactions/MsgDidUpdateParams.pkl.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgDidUpdateParams interface { - Msg - - GetAuthority() string - - GetParams() *pkl.Object - - GetToken() *pkl.Object -} - -var _ MsgDidUpdateParams = (*MsgDidUpdateParamsImpl)(nil) - -type MsgDidUpdateParamsImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Authority string `pkl:"authority"` - - Params *pkl.Object `pkl:"params"` - - Token *pkl.Object `pkl:"token"` -} - -// The type URL for the message -func (rcv *MsgDidUpdateParamsImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgDidUpdateParamsImpl) GetAuthority() string { - return rcv.Authority -} - -func (rcv *MsgDidUpdateParamsImpl) GetParams() *pkl.Object { - return rcv.Params -} - -func (rcv *MsgDidUpdateParamsImpl) GetToken() *pkl.Object { - return rcv.Token -} diff --git a/internal/orm/transactions/MsgGovDeposit.pkl.go b/internal/orm/transactions/MsgGovDeposit.pkl.go deleted file mode 100644 index 556d1df7f..000000000 --- a/internal/orm/transactions/MsgGovDeposit.pkl.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgGovDeposit interface { - Msg - - GetProposalId() int - - GetDepositor() string - - GetAmount() []*pkl.Object -} - -var _ MsgGovDeposit = (*MsgGovDepositImpl)(nil) - -type MsgGovDepositImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - ProposalId int `pkl:"proposalId"` - - Depositor string `pkl:"depositor"` - - Amount []*pkl.Object `pkl:"amount"` -} - -// The type URL for the message -func (rcv *MsgGovDepositImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgGovDepositImpl) GetProposalId() int { - return rcv.ProposalId -} - -func (rcv *MsgGovDepositImpl) GetDepositor() string { - return rcv.Depositor -} - -func (rcv *MsgGovDepositImpl) GetAmount() []*pkl.Object { - return rcv.Amount -} diff --git a/internal/orm/transactions/MsgGovSubmitProposal.pkl.go b/internal/orm/transactions/MsgGovSubmitProposal.pkl.go deleted file mode 100644 index c33b589b6..000000000 --- a/internal/orm/transactions/MsgGovSubmitProposal.pkl.go +++ /dev/null @@ -1,45 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgGovSubmitProposal interface { - Msg - - GetContent() *Proposal - - GetInitialDeposit() []*pkl.Object - - GetProposer() string -} - -var _ MsgGovSubmitProposal = (*MsgGovSubmitProposalImpl)(nil) - -// Gov module messages -type MsgGovSubmitProposalImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Content *Proposal `pkl:"content"` - - InitialDeposit []*pkl.Object `pkl:"initialDeposit"` - - Proposer string `pkl:"proposer"` -} - -// The type URL for the message -func (rcv *MsgGovSubmitProposalImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgGovSubmitProposalImpl) GetContent() *Proposal { - return rcv.Content -} - -func (rcv *MsgGovSubmitProposalImpl) GetInitialDeposit() []*pkl.Object { - return rcv.InitialDeposit -} - -func (rcv *MsgGovSubmitProposalImpl) GetProposer() string { - return rcv.Proposer -} diff --git a/internal/orm/transactions/MsgGovVote.pkl.go b/internal/orm/transactions/MsgGovVote.pkl.go deleted file mode 100644 index 303cf1eee..000000000 --- a/internal/orm/transactions/MsgGovVote.pkl.go +++ /dev/null @@ -1,42 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -type MsgGovVote interface { - Msg - - GetProposalId() int - - GetVoter() string - - GetOption() int -} - -var _ MsgGovVote = (*MsgGovVoteImpl)(nil) - -type MsgGovVoteImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - ProposalId int `pkl:"proposalId"` - - Voter string `pkl:"voter"` - - Option int `pkl:"option"` -} - -// The type URL for the message -func (rcv *MsgGovVoteImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgGovVoteImpl) GetProposalId() int { - return rcv.ProposalId -} - -func (rcv *MsgGovVoteImpl) GetVoter() string { - return rcv.Voter -} - -func (rcv *MsgGovVoteImpl) GetOption() int { - return rcv.Option -} diff --git a/internal/orm/transactions/MsgGroupCreateGroup.pkl.go b/internal/orm/transactions/MsgGroupCreateGroup.pkl.go deleted file mode 100644 index c5dafd6bd..000000000 --- a/internal/orm/transactions/MsgGroupCreateGroup.pkl.go +++ /dev/null @@ -1,45 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgGroupCreateGroup interface { - Msg - - GetAdmin() string - - GetMembers() []*pkl.Object - - GetMetadata() string -} - -var _ MsgGroupCreateGroup = (*MsgGroupCreateGroupImpl)(nil) - -// Group module messages -type MsgGroupCreateGroupImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Admin string `pkl:"admin"` - - Members []*pkl.Object `pkl:"members"` - - Metadata string `pkl:"metadata"` -} - -// The type URL for the message -func (rcv *MsgGroupCreateGroupImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgGroupCreateGroupImpl) GetAdmin() string { - return rcv.Admin -} - -func (rcv *MsgGroupCreateGroupImpl) GetMembers() []*pkl.Object { - return rcv.Members -} - -func (rcv *MsgGroupCreateGroupImpl) GetMetadata() string { - return rcv.Metadata -} diff --git a/internal/orm/transactions/MsgGroupSubmitProposal.pkl.go b/internal/orm/transactions/MsgGroupSubmitProposal.pkl.go deleted file mode 100644 index c23f15391..000000000 --- a/internal/orm/transactions/MsgGroupSubmitProposal.pkl.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgGroupSubmitProposal interface { - Msg - - GetGroupPolicyAddress() string - - GetProposers() []string - - GetMetadata() string - - GetMessages() []*pkl.Object - - GetExec() int -} - -var _ MsgGroupSubmitProposal = (*MsgGroupSubmitProposalImpl)(nil) - -type MsgGroupSubmitProposalImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - GroupPolicyAddress string `pkl:"groupPolicyAddress"` - - Proposers []string `pkl:"proposers"` - - Metadata string `pkl:"metadata"` - - Messages []*pkl.Object `pkl:"messages"` - - Exec int `pkl:"exec"` -} - -// The type URL for the message -func (rcv *MsgGroupSubmitProposalImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgGroupSubmitProposalImpl) GetGroupPolicyAddress() string { - return rcv.GroupPolicyAddress -} - -func (rcv *MsgGroupSubmitProposalImpl) GetProposers() []string { - return rcv.Proposers -} - -func (rcv *MsgGroupSubmitProposalImpl) GetMetadata() string { - return rcv.Metadata -} - -func (rcv *MsgGroupSubmitProposalImpl) GetMessages() []*pkl.Object { - return rcv.Messages -} - -func (rcv *MsgGroupSubmitProposalImpl) GetExec() int { - return rcv.Exec -} diff --git a/internal/orm/transactions/MsgGroupVote.pkl.go b/internal/orm/transactions/MsgGroupVote.pkl.go deleted file mode 100644 index a79ce6899..000000000 --- a/internal/orm/transactions/MsgGroupVote.pkl.go +++ /dev/null @@ -1,58 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -type MsgGroupVote interface { - Msg - - GetProposalId() int - - GetVoter() string - - GetOption() int - - GetMetadata() string - - GetExec() int -} - -var _ MsgGroupVote = (*MsgGroupVoteImpl)(nil) - -type MsgGroupVoteImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - ProposalId int `pkl:"proposalId"` - - Voter string `pkl:"voter"` - - Option int `pkl:"option"` - - Metadata string `pkl:"metadata"` - - Exec int `pkl:"exec"` -} - -// The type URL for the message -func (rcv *MsgGroupVoteImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgGroupVoteImpl) GetProposalId() int { - return rcv.ProposalId -} - -func (rcv *MsgGroupVoteImpl) GetVoter() string { - return rcv.Voter -} - -func (rcv *MsgGroupVoteImpl) GetOption() int { - return rcv.Option -} - -func (rcv *MsgGroupVoteImpl) GetMetadata() string { - return rcv.Metadata -} - -func (rcv *MsgGroupVoteImpl) GetExec() int { - return rcv.Exec -} diff --git a/internal/orm/transactions/MsgStakingBeginRedelegate.pkl.go b/internal/orm/transactions/MsgStakingBeginRedelegate.pkl.go deleted file mode 100644 index 44a019af4..000000000 --- a/internal/orm/transactions/MsgStakingBeginRedelegate.pkl.go +++ /dev/null @@ -1,52 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgStakingBeginRedelegate interface { - Msg - - GetDelegatorAddress() string - - GetValidatorSrcAddress() string - - GetValidatorDstAddress() string - - GetAmount() *pkl.Object -} - -var _ MsgStakingBeginRedelegate = (*MsgStakingBeginRedelegateImpl)(nil) - -type MsgStakingBeginRedelegateImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - DelegatorAddress string `pkl:"delegatorAddress"` - - ValidatorSrcAddress string `pkl:"validatorSrcAddress"` - - ValidatorDstAddress string `pkl:"validatorDstAddress"` - - Amount *pkl.Object `pkl:"amount"` -} - -// The type URL for the message -func (rcv *MsgStakingBeginRedelegateImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgStakingBeginRedelegateImpl) GetDelegatorAddress() string { - return rcv.DelegatorAddress -} - -func (rcv *MsgStakingBeginRedelegateImpl) GetValidatorSrcAddress() string { - return rcv.ValidatorSrcAddress -} - -func (rcv *MsgStakingBeginRedelegateImpl) GetValidatorDstAddress() string { - return rcv.ValidatorDstAddress -} - -func (rcv *MsgStakingBeginRedelegateImpl) GetAmount() *pkl.Object { - return rcv.Amount -} diff --git a/internal/orm/transactions/MsgStakingCreateValidator.pkl.go b/internal/orm/transactions/MsgStakingCreateValidator.pkl.go deleted file mode 100644 index d904a71c6..000000000 --- a/internal/orm/transactions/MsgStakingCreateValidator.pkl.go +++ /dev/null @@ -1,77 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgStakingCreateValidator interface { - Msg - - GetDescription() *pkl.Object - - GetCommission() *pkl.Object - - GetMinSelfDelegation() string - - GetDelegatorAddress() string - - GetValidatorAddress() string - - GetPubkey() *pkl.Object - - GetValue() *pkl.Object -} - -var _ MsgStakingCreateValidator = (*MsgStakingCreateValidatorImpl)(nil) - -// Staking module messages -type MsgStakingCreateValidatorImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - Description *pkl.Object `pkl:"description"` - - Commission *pkl.Object `pkl:"commission"` - - MinSelfDelegation string `pkl:"minSelfDelegation"` - - DelegatorAddress string `pkl:"delegatorAddress"` - - ValidatorAddress string `pkl:"validatorAddress"` - - Pubkey *pkl.Object `pkl:"pubkey"` - - Value *pkl.Object `pkl:"value"` -} - -// The type URL for the message -func (rcv *MsgStakingCreateValidatorImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgStakingCreateValidatorImpl) GetDescription() *pkl.Object { - return rcv.Description -} - -func (rcv *MsgStakingCreateValidatorImpl) GetCommission() *pkl.Object { - return rcv.Commission -} - -func (rcv *MsgStakingCreateValidatorImpl) GetMinSelfDelegation() string { - return rcv.MinSelfDelegation -} - -func (rcv *MsgStakingCreateValidatorImpl) GetDelegatorAddress() string { - return rcv.DelegatorAddress -} - -func (rcv *MsgStakingCreateValidatorImpl) GetValidatorAddress() string { - return rcv.ValidatorAddress -} - -func (rcv *MsgStakingCreateValidatorImpl) GetPubkey() *pkl.Object { - return rcv.Pubkey -} - -func (rcv *MsgStakingCreateValidatorImpl) GetValue() *pkl.Object { - return rcv.Value -} diff --git a/internal/orm/transactions/MsgStakingDelegate.pkl.go b/internal/orm/transactions/MsgStakingDelegate.pkl.go deleted file mode 100644 index 9dd6fa824..000000000 --- a/internal/orm/transactions/MsgStakingDelegate.pkl.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgStakingDelegate interface { - Msg - - GetDelegatorAddress() string - - GetValidatorAddress() string - - GetAmount() *pkl.Object -} - -var _ MsgStakingDelegate = (*MsgStakingDelegateImpl)(nil) - -type MsgStakingDelegateImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - DelegatorAddress string `pkl:"delegatorAddress"` - - ValidatorAddress string `pkl:"validatorAddress"` - - Amount *pkl.Object `pkl:"amount"` -} - -// The type URL for the message -func (rcv *MsgStakingDelegateImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgStakingDelegateImpl) GetDelegatorAddress() string { - return rcv.DelegatorAddress -} - -func (rcv *MsgStakingDelegateImpl) GetValidatorAddress() string { - return rcv.ValidatorAddress -} - -func (rcv *MsgStakingDelegateImpl) GetAmount() *pkl.Object { - return rcv.Amount -} diff --git a/internal/orm/transactions/MsgStakingUndelegate.pkl.go b/internal/orm/transactions/MsgStakingUndelegate.pkl.go deleted file mode 100644 index ffc2395e6..000000000 --- a/internal/orm/transactions/MsgStakingUndelegate.pkl.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -type MsgStakingUndelegate interface { - Msg - - GetDelegatorAddress() string - - GetValidatorAddress() string - - GetAmount() *pkl.Object -} - -var _ MsgStakingUndelegate = (*MsgStakingUndelegateImpl)(nil) - -type MsgStakingUndelegateImpl struct { - // The type URL for the message - TypeUrl string `pkl:"typeUrl"` - - DelegatorAddress string `pkl:"delegatorAddress"` - - ValidatorAddress string `pkl:"validatorAddress"` - - Amount *pkl.Object `pkl:"amount"` -} - -// The type URL for the message -func (rcv *MsgStakingUndelegateImpl) GetTypeUrl() string { - return rcv.TypeUrl -} - -func (rcv *MsgStakingUndelegateImpl) GetDelegatorAddress() string { - return rcv.DelegatorAddress -} - -func (rcv *MsgStakingUndelegateImpl) GetValidatorAddress() string { - return rcv.ValidatorAddress -} - -func (rcv *MsgStakingUndelegateImpl) GetAmount() *pkl.Object { - return rcv.Amount -} diff --git a/internal/orm/transactions/Proposal.pkl.go b/internal/orm/transactions/Proposal.pkl.go deleted file mode 100644 index 4a3e8bd62..000000000 --- a/internal/orm/transactions/Proposal.pkl.go +++ /dev/null @@ -1,11 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -// Base class for all proposals -type Proposal struct { - // The title of the proposal - Title string `pkl:"title"` - - // The description of the proposal - Description string `pkl:"description"` -} diff --git a/internal/orm/transactions/Transactions.pkl.go b/internal/orm/transactions/Transactions.pkl.go deleted file mode 100644 index 5a551b8c4..000000000 --- a/internal/orm/transactions/Transactions.pkl.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import ( - "context" - - "github.com/apple/pkl-go/pkl" -) - -type Transactions struct { -} - -// LoadFromPath loads the pkl module at the given path and evaluates it into a Transactions -func LoadFromPath(ctx context.Context, path string) (ret *Transactions, err error) { - evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions) - if err != nil { - return nil, err - } - defer func() { - cerr := evaluator.Close() - if err == nil { - err = cerr - } - }() - ret, err = Load(ctx, evaluator, pkl.FileSource(path)) - return ret, err -} - -// Load loads the pkl module at the given source and evaluates it with the given evaluator into a Transactions -func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*Transactions, error) { - var ret Transactions - if err := evaluator.EvaluateModule(ctx, source, &ret); err != nil { - return nil, err - } - return &ret, nil -} diff --git a/internal/orm/transactions/TxBody.pkl.go b/internal/orm/transactions/TxBody.pkl.go deleted file mode 100644 index 8a8c23263..000000000 --- a/internal/orm/transactions/TxBody.pkl.go +++ /dev/null @@ -1,17 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -// Represents a transaction body -type TxBody struct { - Messages []Msg `pkl:"messages"` - - Memo *string `pkl:"memo"` - - TimeoutHeight *int `pkl:"timeoutHeight"` - - ExtensionOptions *[]*pkl.Object `pkl:"extensionOptions"` - - NonCriticalExtensionOptions *[]*pkl.Object `pkl:"nonCriticalExtensionOptions"` -} diff --git a/internal/orm/transactions/init.pkl.go b/internal/orm/transactions/init.pkl.go deleted file mode 100644 index 211bc2e21..000000000 --- a/internal/orm/transactions/init.pkl.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated from Pkl module `transactions`. DO NOT EDIT. -package transactions - -import "github.com/apple/pkl-go/pkl" - -func init() { - pkl.RegisterMapping("transactions", Transactions{}) - pkl.RegisterMapping("transactions#Proposal", Proposal{}) - pkl.RegisterMapping("transactions#MsgGovSubmitProposal", MsgGovSubmitProposalImpl{}) - pkl.RegisterMapping("transactions#MsgGovVote", MsgGovVoteImpl{}) - pkl.RegisterMapping("transactions#MsgGovDeposit", MsgGovDepositImpl{}) - pkl.RegisterMapping("transactions#MsgGroupCreateGroup", MsgGroupCreateGroupImpl{}) - pkl.RegisterMapping("transactions#MsgGroupSubmitProposal", MsgGroupSubmitProposalImpl{}) - pkl.RegisterMapping("transactions#MsgGroupVote", MsgGroupVoteImpl{}) - pkl.RegisterMapping("transactions#MsgStakingCreateValidator", MsgStakingCreateValidatorImpl{}) - pkl.RegisterMapping("transactions#MsgStakingDelegate", MsgStakingDelegateImpl{}) - pkl.RegisterMapping("transactions#MsgStakingUndelegate", MsgStakingUndelegateImpl{}) - pkl.RegisterMapping("transactions#MsgStakingBeginRedelegate", MsgStakingBeginRedelegateImpl{}) - pkl.RegisterMapping("transactions#MsgDidUpdateParams", MsgDidUpdateParamsImpl{}) - pkl.RegisterMapping("transactions#MsgDidAllocateVault", MsgDidAllocateVaultImpl{}) - pkl.RegisterMapping("transactions#MsgDidProveWitness", MsgDidProveWitnessImpl{}) - pkl.RegisterMapping("transactions#MsgDidSyncVault", MsgDidSyncVaultImpl{}) - pkl.RegisterMapping("transactions#MsgDidRegisterController", MsgDidRegisterControllerImpl{}) - pkl.RegisterMapping("transactions#MsgDidAuthorize", MsgDidAuthorizeImpl{}) - pkl.RegisterMapping("transactions#MsgDidRegisterService", MsgDidRegisterServiceImpl{}) - pkl.RegisterMapping("transactions#TxBody", TxBody{}) -} diff --git a/pkg/common/README.md b/pkg/common/README.md new file mode 100644 index 000000000..019b25ff1 --- /dev/null +++ b/pkg/common/README.md @@ -0,0 +1 @@ +# Common diff --git a/internal/ctx/cookies.go b/pkg/common/ctx/cookies.go similarity index 100% rename from internal/ctx/cookies.go rename to pkg/common/ctx/cookies.go diff --git a/internal/ctx/ctx_dwn.go b/pkg/common/ctx/ctx_dwn.go similarity index 92% rename from internal/ctx/ctx_dwn.go rename to pkg/common/ctx/ctx_dwn.go index 41556f555..a616ff1da 100644 --- a/internal/ctx/ctx_dwn.go +++ b/pkg/common/ctx/ctx_dwn.go @@ -5,7 +5,8 @@ import ( "net/http" "github.com/labstack/echo/v4" - dwngen "github.com/onsonr/sonr/internal/dwn/gen" + + "github.com/onsonr/sonr/pkg/motr/config" ) // ╭───────────────────────────────────────────────────────────╮ @@ -51,12 +52,12 @@ func (s *DWNContext) ChainID() string { } // Schema returns the vault schema from the cookies. -func (s *DWNContext) Schema() *dwngen.Schema { +func (s *DWNContext) Schema() *config.Schema { v, err := ReadCookie(s.Context, CookieKeyVaultSchema) if err != nil { return nil } - var schema dwngen.Schema + var schema config.Schema err = json.Unmarshal([]byte(v), &schema) if err != nil { return nil @@ -74,7 +75,7 @@ func GetDWNContext(c echo.Context) (*DWNContext, error) { } // HighwaySessionMiddleware establishes a Session Cookie. -func DWNSessionMiddleware(config *dwngen.Config) echo.MiddlewareFunc { +func DWNSessionMiddleware(config *config.Config) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { sessionID := GetSessionID(c) diff --git a/internal/ctx/ctx_hway.go b/pkg/common/ctx/ctx_hway.go similarity index 100% rename from internal/ctx/ctx_hway.go rename to pkg/common/ctx/ctx_hway.go diff --git a/internal/ctx/headers.go b/pkg/common/ctx/headers.go similarity index 94% rename from internal/ctx/headers.go rename to pkg/common/ctx/headers.go index 26258e138..004b52252 100644 --- a/internal/ctx/headers.go +++ b/pkg/common/ctx/headers.go @@ -4,7 +4,8 @@ import ( "encoding/json" "github.com/labstack/echo/v4" - dwngen "github.com/onsonr/sonr/internal/dwn/gen" + + dwngen "github.com/onsonr/sonr/pkg/motr/config" ) type HeaderKey string diff --git a/internal/ctx/request.go b/pkg/common/ctx/request.go similarity index 100% rename from internal/ctx/request.go rename to pkg/common/ctx/request.go diff --git a/internal/ctx/response.go b/pkg/common/ctx/response.go similarity index 100% rename from internal/ctx/response.go rename to pkg/common/ctx/response.go diff --git a/internal/ctx/utils.go b/pkg/common/ctx/utils.go similarity index 100% rename from internal/ctx/utils.go rename to pkg/common/ctx/utils.go diff --git a/pkg/common/types/ipfs.pb.go b/pkg/common/types/ipfs.pb.go new file mode 100644 index 000000000..ca688b554 --- /dev/null +++ b/pkg/common/types/ipfs.pb.go @@ -0,0 +1,64 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: common/v1/ipfs.proto + +package commonv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_common_v1_ipfs_proto protoreflect.FileDescriptor + +var file_common_v1_ipfs_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x70, 0x66, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_common_v1_ipfs_proto_goTypes = []interface{}{} +var file_common_v1_ipfs_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_common_v1_ipfs_proto_init() } +func file_common_v1_ipfs_proto_init() { + if File_common_v1_ipfs_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_v1_ipfs_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_v1_ipfs_proto_goTypes, + DependencyIndexes: file_common_v1_ipfs_proto_depIdxs, + }.Build() + File_common_v1_ipfs_proto = out.File + file_common_v1_ipfs_proto_rawDesc = nil + file_common_v1_ipfs_proto_goTypes = nil + file_common_v1_ipfs_proto_depIdxs = nil +} diff --git a/pkg/common/types/keys.pb.go b/pkg/common/types/keys.pb.go new file mode 100644 index 000000000..f0c0237fc --- /dev/null +++ b/pkg/common/types/keys.pb.go @@ -0,0 +1,377 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: common/v1/keys.proto + +package commonv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// PubKey defines a public key for a did +type PubKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` + KeyType string `protobuf:"bytes,2,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` + RawKey *RawKey `protobuf:"bytes,3,opt,name=raw_key,json=rawKey,proto3" json:"raw_key,omitempty"` + Jwk *JSONWebKey `protobuf:"bytes,4,opt,name=jwk,proto3" json:"jwk,omitempty"` +} + +func (x *PubKey) Reset() { + *x = PubKey{} + if protoimpl.UnsafeEnabled { + mi := &file_common_v1_keys_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PubKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PubKey) ProtoMessage() {} + +func (x *PubKey) ProtoReflect() protoreflect.Message { + mi := &file_common_v1_keys_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PubKey.ProtoReflect.Descriptor instead. +func (*PubKey) Descriptor() ([]byte, []int) { + return file_common_v1_keys_proto_rawDescGZIP(), []int{0} +} + +func (x *PubKey) GetRole() string { + if x != nil { + return x.Role + } + return "" +} + +func (x *PubKey) GetKeyType() string { + if x != nil { + return x.KeyType + } + return "" +} + +func (x *PubKey) GetRawKey() *RawKey { + if x != nil { + return x.RawKey + } + return nil +} + +func (x *PubKey) GetJwk() *JSONWebKey { + if x != nil { + return x.Jwk + } + return nil +} + +// JWK represents a JSON Web Key +type JSONWebKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Kty string `protobuf:"bytes,1,opt,name=kty,proto3" json:"kty,omitempty"` // Key Type + Crv string `protobuf:"bytes,2,opt,name=crv,proto3" json:"crv,omitempty"` // Curve (for EC and OKP keys) + X string `protobuf:"bytes,3,opt,name=x,proto3" json:"x,omitempty"` // X coordinate (for EC and OKP keys) + Y string `protobuf:"bytes,4,opt,name=y,proto3" json:"y,omitempty"` // Y coordinate (for EC keys) + N string `protobuf:"bytes,5,opt,name=n,proto3" json:"n,omitempty"` // Modulus (for RSA keys) + E string `protobuf:"bytes,6,opt,name=e,proto3" json:"e,omitempty"` // Exponent (for RSA keys) +} + +func (x *JSONWebKey) Reset() { + *x = JSONWebKey{} + if protoimpl.UnsafeEnabled { + mi := &file_common_v1_keys_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *JSONWebKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JSONWebKey) ProtoMessage() {} + +func (x *JSONWebKey) ProtoReflect() protoreflect.Message { + mi := &file_common_v1_keys_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JSONWebKey.ProtoReflect.Descriptor instead. +func (*JSONWebKey) Descriptor() ([]byte, []int) { + return file_common_v1_keys_proto_rawDescGZIP(), []int{1} +} + +func (x *JSONWebKey) GetKty() string { + if x != nil { + return x.Kty + } + return "" +} + +func (x *JSONWebKey) GetCrv() string { + if x != nil { + return x.Crv + } + return "" +} + +func (x *JSONWebKey) GetX() string { + if x != nil { + return x.X + } + return "" +} + +func (x *JSONWebKey) GetY() string { + if x != nil { + return x.Y + } + return "" +} + +func (x *JSONWebKey) GetN() string { + if x != nil { + return x.N + } + return "" +} + +func (x *JSONWebKey) GetE() string { + if x != nil { + return x.E + } + return "" +} + +type RawKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Algorithm string `protobuf:"bytes,1,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + Encoding string `protobuf:"bytes,2,opt,name=encoding,proto3" json:"encoding,omitempty"` + Curve string `protobuf:"bytes,3,opt,name=curve,proto3" json:"curve,omitempty"` + Key []byte `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *RawKey) Reset() { + *x = RawKey{} + if protoimpl.UnsafeEnabled { + mi := &file_common_v1_keys_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RawKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RawKey) ProtoMessage() {} + +func (x *RawKey) ProtoReflect() protoreflect.Message { + mi := &file_common_v1_keys_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RawKey.ProtoReflect.Descriptor instead. +func (*RawKey) Descriptor() ([]byte, []int) { + return file_common_v1_keys_proto_rawDescGZIP(), []int{2} +} + +func (x *RawKey) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + +func (x *RawKey) GetEncoding() string { + if x != nil { + return x.Encoding + } + return "" +} + +func (x *RawKey) GetCurve() string { + if x != nil { + return x.Curve + } + return "" +} + +func (x *RawKey) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +var File_common_v1_keys_proto protoreflect.FileDescriptor + +var file_common_v1_keys_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6b, 0x65, 0x79, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x22, 0x8c, 0x01, 0x0a, 0x06, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, + 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x72, + 0x61, 0x77, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x4b, 0x65, 0x79, 0x52, + 0x06, 0x72, 0x61, 0x77, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x03, 0x6a, 0x77, 0x6b, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6a, 0x77, 0x6b, + 0x22, 0x68, 0x0a, 0x0a, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x74, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x63, 0x72, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, + 0x72, 0x76, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x78, + 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x79, 0x12, 0x0c, + 0x0a, 0x01, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x6e, 0x12, 0x0c, 0x0a, 0x01, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x65, 0x22, 0x6a, 0x0a, 0x06, 0x52, 0x61, + 0x77, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, + 0x68, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x14, + 0x0a, 0x05, 0x63, 0x75, 0x72, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, + 0x75, 0x72, 0x76, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, + 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_common_v1_keys_proto_rawDescOnce sync.Once + file_common_v1_keys_proto_rawDescData = file_common_v1_keys_proto_rawDesc +) + +func file_common_v1_keys_proto_rawDescGZIP() []byte { + file_common_v1_keys_proto_rawDescOnce.Do(func() { + file_common_v1_keys_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_v1_keys_proto_rawDescData) + }) + return file_common_v1_keys_proto_rawDescData +} + +var file_common_v1_keys_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_common_v1_keys_proto_goTypes = []interface{}{ + (*PubKey)(nil), // 0: common.v1.PubKey + (*JSONWebKey)(nil), // 1: common.v1.JSONWebKey + (*RawKey)(nil), // 2: common.v1.RawKey +} +var file_common_v1_keys_proto_depIdxs = []int32{ + 2, // 0: common.v1.PubKey.raw_key:type_name -> common.v1.RawKey + 1, // 1: common.v1.PubKey.jwk:type_name -> common.v1.JSONWebKey + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_common_v1_keys_proto_init() } +func file_common_v1_keys_proto_init() { + if File_common_v1_keys_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_v1_keys_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PubKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_v1_keys_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*JSONWebKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_v1_keys_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RawKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_v1_keys_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_v1_keys_proto_goTypes, + DependencyIndexes: file_common_v1_keys_proto_depIdxs, + MessageInfos: file_common_v1_keys_proto_msgTypes, + }.Build() + File_common_v1_keys_proto = out.File + file_common_v1_keys_proto_rawDesc = nil + file_common_v1_keys_proto_goTypes = nil + file_common_v1_keys_proto_depIdxs = nil +} diff --git a/pkg/common/types/uri.pb.go b/pkg/common/types/uri.pb.go new file mode 100644 index 000000000..c73ea70ec --- /dev/null +++ b/pkg/common/types/uri.pb.go @@ -0,0 +1,215 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: common/v1/uri.proto + +package commonv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type URI_URIProtocol int32 + +const ( + URI_HTTPS URI_URIProtocol = 0 + URI_IPFS URI_URIProtocol = 1 + URI_IPNS URI_URIProtocol = 2 + URI_DID URI_URIProtocol = 3 +) + +// Enum value maps for URI_URIProtocol. +var ( + URI_URIProtocol_name = map[int32]string{ + 0: "HTTPS", + 1: "IPFS", + 2: "IPNS", + 3: "DID", + } + URI_URIProtocol_value = map[string]int32{ + "HTTPS": 0, + "IPFS": 1, + "IPNS": 2, + "DID": 3, + } +) + +func (x URI_URIProtocol) Enum() *URI_URIProtocol { + p := new(URI_URIProtocol) + *p = x + return p +} + +func (x URI_URIProtocol) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (URI_URIProtocol) Descriptor() protoreflect.EnumDescriptor { + return file_common_v1_uri_proto_enumTypes[0].Descriptor() +} + +func (URI_URIProtocol) Type() protoreflect.EnumType { + return &file_common_v1_uri_proto_enumTypes[0] +} + +func (x URI_URIProtocol) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use URI_URIProtocol.Descriptor instead. +func (URI_URIProtocol) EnumDescriptor() ([]byte, []int) { + return file_common_v1_uri_proto_rawDescGZIP(), []int{0, 0} +} + +type URI struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Protocol URI_URIProtocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=common.v1.URI_URIProtocol" json:"protocol,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *URI) Reset() { + *x = URI{} + if protoimpl.UnsafeEnabled { + mi := &file_common_v1_uri_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *URI) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*URI) ProtoMessage() {} + +func (x *URI) ProtoReflect() protoreflect.Message { + mi := &file_common_v1_uri_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use URI.ProtoReflect.Descriptor instead. +func (*URI) Descriptor() ([]byte, []int) { + return file_common_v1_uri_proto_rawDescGZIP(), []int{0} +} + +func (x *URI) GetProtocol() URI_URIProtocol { + if x != nil { + return x.Protocol + } + return URI_HTTPS +} + +func (x *URI) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +var File_common_v1_uri_proto protoreflect.FileDescriptor + +var file_common_v1_uri_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x72, 0x69, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x22, 0x8a, 0x01, 0x0a, 0x03, 0x55, 0x52, 0x49, 0x12, 0x36, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x52, 0x49, 0x2e, 0x55, 0x52, 0x49, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x35, 0x0a, 0x0b, 0x55, 0x52, 0x49, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x00, + 0x12, 0x08, 0x0a, 0x04, 0x49, 0x50, 0x46, 0x53, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x50, + 0x4e, 0x53, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x49, 0x44, 0x10, 0x03, 0x42, 0x32, 0x5a, + 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, + 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x76, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_v1_uri_proto_rawDescOnce sync.Once + file_common_v1_uri_proto_rawDescData = file_common_v1_uri_proto_rawDesc +) + +func file_common_v1_uri_proto_rawDescGZIP() []byte { + file_common_v1_uri_proto_rawDescOnce.Do(func() { + file_common_v1_uri_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_v1_uri_proto_rawDescData) + }) + return file_common_v1_uri_proto_rawDescData +} + +var file_common_v1_uri_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_common_v1_uri_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_common_v1_uri_proto_goTypes = []interface{}{ + (URI_URIProtocol)(0), // 0: common.v1.URI.URIProtocol + (*URI)(nil), // 1: common.v1.URI +} +var file_common_v1_uri_proto_depIdxs = []int32{ + 0, // 0: common.v1.URI.protocol:type_name -> common.v1.URI.URIProtocol + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_common_v1_uri_proto_init() } +func file_common_v1_uri_proto_init() { + if File_common_v1_uri_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_v1_uri_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*URI); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_v1_uri_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_v1_uri_proto_goTypes, + DependencyIndexes: file_common_v1_uri_proto_depIdxs, + EnumInfos: file_common_v1_uri_proto_enumTypes, + MessageInfos: file_common_v1_uri_proto_msgTypes, + }.Build() + File_common_v1_uri_proto = out.File + file_common_v1_uri_proto_rawDesc = nil + file_common_v1_uri_proto_goTypes = nil + file_common_v1_uri_proto_depIdxs = nil +} diff --git a/pkg/core/README.md b/pkg/core/README.md new file mode 100644 index 000000000..3b616f93d --- /dev/null +++ b/pkg/core/README.md @@ -0,0 +1 @@ +# Core diff --git a/pkg/core/appmodule/environment.go b/pkg/core/appmodule/environment.go new file mode 100644 index 000000000..187daaeca --- /dev/null +++ b/pkg/core/appmodule/environment.go @@ -0,0 +1,30 @@ +package appmodule + +import ( + "cosmossdk.io/core/event" + "cosmossdk.io/core/gas" + "cosmossdk.io/core/header" + "cosmossdk.io/core/store" + + "github.com/onsonr/sonr/pkg/core/branch" + "github.com/onsonr/sonr/pkg/core/log" + "github.com/onsonr/sonr/pkg/core/router" + "github.com/onsonr/sonr/pkg/core/transaction" +) + +// Environment is used to get all services to their respective module. +// Contract: All fields of environment are always populated by runtime. +type Environment struct { + Logger log.Logger + + BranchService branch.Service + EventService event.Service + GasService gas.Service + HeaderService header.Service + QueryRouterService router.Service + MsgRouterService router.Service + TransactionService transaction.Service + + KVStoreService store.KVStoreService + MemStoreService store.MemoryStoreService +} diff --git a/pkg/core/branch/branch.go b/pkg/core/branch/branch.go new file mode 100644 index 000000000..79634cf43 --- /dev/null +++ b/pkg/core/branch/branch.go @@ -0,0 +1,34 @@ +// Package branch contains the core branch service interface. +package branch + +import ( + "context" + "errors" +) + +// ErrGasLimitExceeded is returned when the gas limit is exceeded in a +// Service.ExecuteWithGasLimit call. +var ErrGasLimitExceeded = errors.New("branch: gas limit exceeded") + +// Service is the branch service interface. It can be used to execute +// code paths in an isolated execution context that can be reverted. +// A revert typically means a rollback on events and state changes. +type Service interface { + // Execute executes the given function in an isolated context. If the + // `f` function returns an error, the execution is considered failed, + // and every change made affecting the execution context is rolled back. + // If the function returns nil, the execution is considered successful, and + // committed. + // The context.Context passed to the `f` function is a child of the context + // passed to the Execute function, and is what should be used with other + // core services in order to ensure the execution remains isolated. + Execute(ctx context.Context, f func(ctx context.Context) error) error + // ExecuteWithGasLimit executes the given function `f` in an isolated context, + // with the provided gas limit, this is advanced usage and is used to disallow + // an execution path to consume an indefinite amount of gas. + // If the execution fails or succeeds the gas limit is still applied to the + // parent context, the function returns a gasUsed value which is the amount + // of gas used by the execution path. If the execution path exceeds the gas + // ErrGasLimitExceeded is returned. + ExecuteWithGasLimit(ctx context.Context, gasLimit uint64, f func(ctx context.Context) error) (gasUsed uint64, err error) +} diff --git a/pkg/core/log/logger.go b/pkg/core/log/logger.go new file mode 100644 index 000000000..6065e8173 --- /dev/null +++ b/pkg/core/log/logger.go @@ -0,0 +1,29 @@ +package log + +const ModuleKey = "module" + +// Logger defines basic logger functionality that all previous versions of the Logger interface should +// support. Library users should prefer to use this interface when possible, then type case to Logger +// to see if WithContext is supported. +type Logger interface { + // Info takes a message and a set of key/value pairs and logs with level INFO. + // The key of the tuple must be a string. + Info(msg string, keyVals ...any) + + // Warn takes a message and a set of key/value pairs and logs with level WARN. + // The key of the tuple must be a string. + Warn(msg string, keyVals ...any) + + // Error takes a message and a set of key/value pairs and logs with level ERR. + // The key of the tuple must be a string. + Error(msg string, keyVals ...any) + + // Debug takes a message and a set of key/value pairs and logs with level DEBUG. + // The key of the tuple must be a string. + Debug(msg string, keyVals ...any) + + // Impl returns the underlying logger implementation. + // It is used to access the full functionalities of the underlying logger. + // Advanced users can type cast the returned value to the actual logger. + Impl() any +} diff --git a/pkg/core/router/service.go b/pkg/core/router/service.go new file mode 100644 index 000000000..ead11bfbe --- /dev/null +++ b/pkg/core/router/service.go @@ -0,0 +1,16 @@ +package router + +import ( + "context" + + "github.com/onsonr/sonr/pkg/core/transaction" +) + +// Service is the interface that wraps the basic methods for a router. +// A router can be a query router or a message router. +type Service interface { + // CanInvoke returns an error if the given request cannot be invoked. + CanInvoke(ctx context.Context, typeURL string) error + // Invoke execute a message or query. The response should be type casted by the caller to the expected response. + Invoke(ctx context.Context, req transaction.Msg) (res transaction.Msg, err error) +} diff --git a/pkg/core/transaction/service.go b/pkg/core/transaction/service.go new file mode 100644 index 000000000..57ec9c7be --- /dev/null +++ b/pkg/core/transaction/service.go @@ -0,0 +1,25 @@ +package transaction + +import "context" + +// ExecMode defines the execution mode +type ExecMode uint8 + +// All possible execution modes. +// For backwards compatibility and easier casting, the exec mode values must be the same as in cosmos/cosmos-sdk/types package. +const ( + ExecModeCheck ExecMode = iota + ExecModeReCheck + ExecModeSimulate + _ + _ + _ + _ + ExecModeFinalize +) + +// Service creates a transaction service. +type Service interface { + // ExecMode returns the current execution mode. + ExecMode(ctx context.Context) ExecMode +} diff --git a/pkg/core/transaction/transaction.go b/pkg/core/transaction/transaction.go new file mode 100644 index 000000000..3efd88b5a --- /dev/null +++ b/pkg/core/transaction/transaction.go @@ -0,0 +1,45 @@ +package transaction + +type ( + // Msg uses structural types to define the interface for a message. + Msg = interface { + Reset() + String() string + ProtoMessage() + } + Identity = []byte +) + +// GenericMsg defines a generic version of a Msg. +// The GenericMsg refers to the non pointer version of Msg, +// and is required to allow its instantiations in generic contexts. +type GenericMsg[T any] interface { + *T + Msg +} + +// Codec defines the TX codec, which converts a TX from bytes to its concrete representation. +type Codec[T Tx] interface { + // Decode decodes the tx bytes into a DecodedTx, containing + // both concrete and bytes representation of the tx. + Decode([]byte) (T, error) + // DecodeJSON decodes the tx JSON bytes into a DecodedTx + DecodeJSON([]byte) (T, error) +} + +// Tx defines the interface for a transaction. +// All custom transactions must implement this interface. +type Tx interface { + // Hash returns the unique identifier for the Tx. + Hash() [32]byte + // GetMessages returns the list of state transitions of the Tx. + GetMessages() ([]Msg, error) + // GetSenders returns the tx state transition sender. + GetSenders() ([]Identity, error) // TODO reduce this to a single identity if accepted + // GetGasLimit returns the gas limit of the tx. Must return math.MaxUint64 for infinite gas + // txs. + GetGasLimit() (uint64, error) + // Bytes returns the encoded version of this tx. Note: this is ideally cached + // from the first instance of the decoding of the tx. + Bytes() []byte +} diff --git a/pkg/hway/README.md b/pkg/hway/README.md new file mode 100644 index 000000000..9a88828c3 --- /dev/null +++ b/pkg/hway/README.md @@ -0,0 +1 @@ +# Hway diff --git a/pkg/workers/handlers/jsonrpc.go b/pkg/hway/handlers/jsonrpc.go similarity index 100% rename from pkg/workers/handlers/jsonrpc.go rename to pkg/hway/handlers/jsonrpc.go diff --git a/pkg/workers/handlers/querier.go b/pkg/hway/handlers/querier.go similarity index 100% rename from pkg/workers/handlers/querier.go rename to pkg/hway/handlers/querier.go diff --git a/pkg/hway/handlers/sync.go b/pkg/hway/handlers/sync.go new file mode 100644 index 000000000..62fb99ec9 --- /dev/null +++ b/pkg/hway/handlers/sync.go @@ -0,0 +1,13 @@ +package handlers + +import "github.com/labstack/echo/v4" + +func FetchInitial(e echo.Context) error { + // Implement database schema endpoint + return nil +} + +func FetchCurrent(e echo.Context) error { + // Implement account entries endpoint + return nil +} diff --git a/pkg/workers/routes/gateway.go b/pkg/hway/routes/routes.go similarity index 100% rename from pkg/workers/routes/gateway.go rename to pkg/hway/routes/routes.go diff --git a/pkg/hway/types/api.pb.go b/pkg/hway/types/api.pb.go new file mode 100644 index 000000000..32a95f644 --- /dev/null +++ b/pkg/hway/types/api.pb.go @@ -0,0 +1,535 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: hway/v1/api.proto + +package types + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GetJWKSRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetJWKSRequest) Reset() { + *x = GetJWKSRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_hway_v1_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetJWKSRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetJWKSRequest) ProtoMessage() {} + +func (x *GetJWKSRequest) ProtoReflect() protoreflect.Message { + mi := &file_hway_v1_api_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetJWKSRequest.ProtoReflect.Descriptor instead. +func (*GetJWKSRequest) Descriptor() ([]byte, []int) { + return file_hway_v1_api_proto_rawDescGZIP(), []int{0} +} + +type GetJWKSResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Jwks string `protobuf:"bytes,1,opt,name=jwks,proto3" json:"jwks,omitempty"` +} + +func (x *GetJWKSResponse) Reset() { + *x = GetJWKSResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_hway_v1_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetJWKSResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetJWKSResponse) ProtoMessage() {} + +func (x *GetJWKSResponse) ProtoReflect() protoreflect.Message { + mi := &file_hway_v1_api_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetJWKSResponse.ProtoReflect.Descriptor instead. +func (*GetJWKSResponse) Descriptor() ([]byte, []int) { + return file_hway_v1_api_proto_rawDescGZIP(), []int{1} +} + +func (x *GetJWKSResponse) GetJwks() string { + if x != nil { + return x.Jwks + } + return "" +} + +type GetTokenRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"` + Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` + Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` + Asset string `protobuf:"bytes,4,opt,name=asset,proto3" json:"asset,omitempty"` +} + +func (x *GetTokenRequest) Reset() { + *x = GetTokenRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_hway_v1_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTokenRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTokenRequest) ProtoMessage() {} + +func (x *GetTokenRequest) ProtoReflect() protoreflect.Message { + mi := &file_hway_v1_api_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTokenRequest.ProtoReflect.Descriptor instead. +func (*GetTokenRequest) Descriptor() ([]byte, []int) { + return file_hway_v1_api_proto_rawDescGZIP(), []int{2} +} + +func (x *GetTokenRequest) GetSubject() string { + if x != nil { + return x.Subject + } + return "" +} + +func (x *GetTokenRequest) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *GetTokenRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *GetTokenRequest) GetAsset() string { + if x != nil { + return x.Asset + } + return "" +} + +type GetTokenResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *GetTokenResponse) Reset() { + *x = GetTokenResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_hway_v1_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTokenResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTokenResponse) ProtoMessage() {} + +func (x *GetTokenResponse) ProtoReflect() protoreflect.Message { + mi := &file_hway_v1_api_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTokenResponse.ProtoReflect.Descriptor instead. +func (*GetTokenResponse) Descriptor() ([]byte, []int) { + return file_hway_v1_api_proto_rawDescGZIP(), []int{3} +} + +func (x *GetTokenResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type GrantAuthorizationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"` + Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` + Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` + Asset string `protobuf:"bytes,4,opt,name=asset,proto3" json:"asset,omitempty"` + Assertion string `protobuf:"bytes,5,opt,name=assertion,proto3" json:"assertion,omitempty"` +} + +func (x *GrantAuthorizationRequest) Reset() { + *x = GrantAuthorizationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_hway_v1_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GrantAuthorizationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GrantAuthorizationRequest) ProtoMessage() {} + +func (x *GrantAuthorizationRequest) ProtoReflect() protoreflect.Message { + mi := &file_hway_v1_api_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GrantAuthorizationRequest.ProtoReflect.Descriptor instead. +func (*GrantAuthorizationRequest) Descriptor() ([]byte, []int) { + return file_hway_v1_api_proto_rawDescGZIP(), []int{4} +} + +func (x *GrantAuthorizationRequest) GetSubject() string { + if x != nil { + return x.Subject + } + return "" +} + +func (x *GrantAuthorizationRequest) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *GrantAuthorizationRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *GrantAuthorizationRequest) GetAsset() string { + if x != nil { + return x.Asset + } + return "" +} + +func (x *GrantAuthorizationRequest) GetAssertion() string { + if x != nil { + return x.Assertion + } + return "" +} + +type GrantAuthorizationResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *GrantAuthorizationResponse) Reset() { + *x = GrantAuthorizationResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_hway_v1_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GrantAuthorizationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GrantAuthorizationResponse) ProtoMessage() {} + +func (x *GrantAuthorizationResponse) ProtoReflect() protoreflect.Message { + mi := &file_hway_v1_api_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GrantAuthorizationResponse.ProtoReflect.Descriptor instead. +func (*GrantAuthorizationResponse) Descriptor() ([]byte, []int) { + return file_hway_v1_api_proto_rawDescGZIP(), []int{5} +} + +func (x *GrantAuthorizationResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +var File_hway_v1_api_proto protoreflect.FileDescriptor + +var file_hway_v1_api_proto_rawDesc = []byte{ + 0x0a, 0x11, 0x68, 0x77, 0x61, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x22, 0x10, 0x0a, 0x0e, + 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x25, + 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x77, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6a, 0x77, 0x6b, 0x73, 0x22, 0x6b, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x73, 0x73, + 0x65, 0x74, 0x22, 0x28, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x93, 0x01, 0x0a, + 0x19, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, + 0x73, 0x73, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xe7, 0x01, 0x0a, 0x07, 0x48, 0x69, 0x67, 0x68, 0x77, + 0x61, 0x79, 0x12, 0x3c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x12, 0x17, 0x2e, + 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x18, 0x2e, 0x68, + 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x5d, 0x0a, 0x12, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x77, + 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, + 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x68, + 0x77, 0x61, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_hway_v1_api_proto_rawDescOnce sync.Once + file_hway_v1_api_proto_rawDescData = file_hway_v1_api_proto_rawDesc +) + +func file_hway_v1_api_proto_rawDescGZIP() []byte { + file_hway_v1_api_proto_rawDescOnce.Do(func() { + file_hway_v1_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_hway_v1_api_proto_rawDescData) + }) + return file_hway_v1_api_proto_rawDescData +} + +var file_hway_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_hway_v1_api_proto_goTypes = []interface{}{ + (*GetJWKSRequest)(nil), // 0: hway.v1.GetJWKSRequest + (*GetJWKSResponse)(nil), // 1: hway.v1.GetJWKSResponse + (*GetTokenRequest)(nil), // 2: hway.v1.GetTokenRequest + (*GetTokenResponse)(nil), // 3: hway.v1.GetTokenResponse + (*GrantAuthorizationRequest)(nil), // 4: hway.v1.GrantAuthorizationRequest + (*GrantAuthorizationResponse)(nil), // 5: hway.v1.GrantAuthorizationResponse +} +var file_hway_v1_api_proto_depIdxs = []int32{ + 0, // 0: hway.v1.Highway.GetJWKS:input_type -> hway.v1.GetJWKSRequest + 2, // 1: hway.v1.Highway.GetToken:input_type -> hway.v1.GetTokenRequest + 4, // 2: hway.v1.Highway.GrantAuthorization:input_type -> hway.v1.GrantAuthorizationRequest + 1, // 3: hway.v1.Highway.GetJWKS:output_type -> hway.v1.GetJWKSResponse + 3, // 4: hway.v1.Highway.GetToken:output_type -> hway.v1.GetTokenResponse + 5, // 5: hway.v1.Highway.GrantAuthorization:output_type -> hway.v1.GrantAuthorizationResponse + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_hway_v1_api_proto_init() } +func file_hway_v1_api_proto_init() { + if File_hway_v1_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_hway_v1_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetJWKSRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_hway_v1_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetJWKSResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_hway_v1_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTokenRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_hway_v1_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTokenResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_hway_v1_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GrantAuthorizationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_hway_v1_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GrantAuthorizationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_hway_v1_api_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_hway_v1_api_proto_goTypes, + DependencyIndexes: file_hway_v1_api_proto_depIdxs, + MessageInfos: file_hway_v1_api_proto_msgTypes, + }.Build() + File_hway_v1_api_proto = out.File + file_hway_v1_api_proto_rawDesc = nil + file_hway_v1_api_proto_goTypes = nil + file_hway_v1_api_proto_depIdxs = nil +} diff --git a/pkg/hway/types/client.pb.go b/pkg/hway/types/client.pb.go new file mode 100644 index 000000000..6fc6c8616 --- /dev/null +++ b/pkg/hway/types/client.pb.go @@ -0,0 +1,63 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: hway/v1/client.proto + +package types + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var File_hway_v1_client_proto protoreflect.FileDescriptor + +var file_hway_v1_client_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x68, 0x77, 0x61, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x42, + 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, + 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x68, 0x77, + 0x61, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, +} + +var file_hway_v1_client_proto_goTypes = []interface{}{} +var file_hway_v1_client_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_hway_v1_client_proto_init() } +func file_hway_v1_client_proto_init() { + if File_hway_v1_client_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_hway_v1_client_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hway_v1_client_proto_goTypes, + DependencyIndexes: file_hway_v1_client_proto_depIdxs, + }.Build() + File_hway_v1_client_proto = out.File + file_hway_v1_client_proto_rawDesc = nil + file_hway_v1_client_proto_goTypes = nil + file_hway_v1_client_proto_depIdxs = nil +} diff --git a/pkg/motr/README.md b/pkg/motr/README.md new file mode 100644 index 000000000..cab2301c5 --- /dev/null +++ b/pkg/motr/README.md @@ -0,0 +1 @@ +# Motr diff --git a/internal/dwn/gen/Config.pkl.go b/pkg/motr/config/Config.pkl.go similarity index 88% rename from internal/dwn/gen/Config.pkl.go rename to pkg/motr/config/Config.pkl.go index e08b568dd..95032bf97 100644 --- a/internal/dwn/gen/Config.pkl.go +++ b/pkg/motr/config/Config.pkl.go @@ -1,5 +1,5 @@ -// Code generated from Pkl module `dwngen`. DO NOT EDIT. -package gen +// Code generated from Pkl module `dwn`. DO NOT EDIT. +package config type Config struct { IpfsGatewayUrl string `pkl:"ipfsGatewayUrl" json:"ipfsGatewayUrl,omitempty"` diff --git a/internal/dwn/gen/Dwngen.pkl.go b/pkg/motr/config/Dwn.pkl.go similarity index 68% rename from internal/dwn/gen/Dwngen.pkl.go rename to pkg/motr/config/Dwn.pkl.go index 4f7431936..8b8b4d9ca 100644 --- a/internal/dwn/gen/Dwngen.pkl.go +++ b/pkg/motr/config/Dwn.pkl.go @@ -1,5 +1,5 @@ -// Code generated from Pkl module `dwngen`. DO NOT EDIT. -package gen +// Code generated from Pkl module `dwn`. DO NOT EDIT. +package config import ( "context" @@ -7,11 +7,11 @@ import ( "github.com/apple/pkl-go/pkl" ) -type Dwngen struct { +type Dwn struct { } -// LoadFromPath loads the pkl module at the given path and evaluates it into a Dwngen -func LoadFromPath(ctx context.Context, path string) (ret *Dwngen, err error) { +// LoadFromPath loads the pkl module at the given path and evaluates it into a Dwn +func LoadFromPath(ctx context.Context, path string) (ret *Dwn, err error) { evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions) if err != nil { return nil, err @@ -26,9 +26,9 @@ func LoadFromPath(ctx context.Context, path string) (ret *Dwngen, err error) { return ret, err } -// Load loads the pkl module at the given source and evaluates it with the given evaluator into a Dwngen -func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*Dwngen, error) { - var ret Dwngen +// Load loads the pkl module at the given source and evaluates it with the given evaluator into a Dwn +func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*Dwn, error) { + var ret Dwn if err := evaluator.EvaluateModule(ctx, source, &ret); err != nil { return nil, err } diff --git a/internal/dwn/gen/Schema.pkl.go b/pkg/motr/config/Schema.pkl.go similarity index 87% rename from internal/dwn/gen/Schema.pkl.go rename to pkg/motr/config/Schema.pkl.go index eb9b6edfe..f05180f0f 100644 --- a/internal/dwn/gen/Schema.pkl.go +++ b/pkg/motr/config/Schema.pkl.go @@ -1,5 +1,5 @@ -// Code generated from Pkl module `dwngen`. DO NOT EDIT. -package gen +// Code generated from Pkl module `dwn`. DO NOT EDIT. +package config type Schema struct { Version int `pkl:"version"` diff --git a/pkg/motr/config/init.pkl.go b/pkg/motr/config/init.pkl.go new file mode 100644 index 000000000..5b5b2afa0 --- /dev/null +++ b/pkg/motr/config/init.pkl.go @@ -0,0 +1,10 @@ +// Code generated from Pkl module `dwn`. DO NOT EDIT. +package config + +import "github.com/apple/pkl-go/pkl" + +func init() { + pkl.RegisterMapping("dwn", Dwn{}) + pkl.RegisterMapping("dwn#Config", Config{}) + pkl.RegisterMapping("dwn#Schema", Schema{}) +} diff --git a/internal/dwn/embed.go b/pkg/motr/embed.go similarity index 59% rename from internal/dwn/embed.go rename to pkg/motr/embed.go index c56183bbd..c4e6c99d2 100644 --- a/internal/dwn/embed.go +++ b/pkg/motr/embed.go @@ -1,30 +1,27 @@ -package dwn +package motr import ( _ "embed" "encoding/json" "github.com/ipfs/boxo/files" - "github.com/onsonr/sonr/internal/dwn/gen" - "github.com/onsonr/sonr/pkg/nebula" + + "github.com/onsonr/sonr/pkg/motr/config" + "github.com/onsonr/sonr/pkg/motr/static" ) const ( - FileNameAppWASM = "app.wasm" - FileNameConfigJSON = "dwn.json" + FileNameConfigJSON = "dwn.pkl" FileNameIndexHTML = "index.html" FileNameWorkerJS = "sw.js" ) -//go:embed app.wasm -var dwnWasmData []byte - -//go:embed sw.js +//go:embed static/sw.js var swJSData []byte // NewVaultDirectory creates a new directory with the default files -func NewVaultDirectory(cnfg *gen.Config) (files.Node, error) { - idxFile, err := nebula.BuildVaultFile(cnfg) +func NewVaultDirectory(cnfg *config.Config) (files.Node, error) { + idxFile, err := static.BuildVaultFile(cnfg) if err != nil { return nil, err } @@ -33,7 +30,6 @@ func NewVaultDirectory(cnfg *gen.Config) (files.Node, error) { return nil, err } fileMap := map[string]files.Node{ - FileNameAppWASM: files.NewBytesFile(dwnWasmData), FileNameConfigJSON: files.NewBytesFile(cnfgBz), FileNameIndexHTML: idxFile, FileNameWorkerJS: files.NewBytesFile(swJSData), diff --git a/pkg/workers/handlers/auth.go b/pkg/motr/handlers/auth.go similarity index 84% rename from pkg/workers/handlers/auth.go rename to pkg/motr/handlers/auth.go index 6b3ee13ed..2ed26e8a9 100644 --- a/pkg/workers/handlers/auth.go +++ b/pkg/motr/handlers/auth.go @@ -4,24 +4,20 @@ import ( "github.com/go-webauthn/webauthn/protocol" "github.com/labstack/echo/v4" - "github.com/onsonr/sonr/internal/orm" + "github.com/onsonr/sonr/pkg/motr/types/orm" ) -type authAPI struct{} - -var Auth = new(authAPI) - // ╭───────────────────────────────────────────────────────────╮ // │ Login Handlers │ // ╰───────────────────────────────────────────────────────────╯ // LoginSubjectCheck handles the login subject check. -func (a *authAPI) LoginSubjectCheck(e echo.Context) error { +func LoginSubjectCheck(e echo.Context) error { return e.JSON(200, "HandleCredentialAssertion") } // LoginSubjectStart handles the login subject start. -func (a *authAPI) LoginSubjectStart(e echo.Context) error { +func LoginSubjectStart(e echo.Context) error { opts := &protocol.PublicKeyCredentialRequestOptions{ UserVerification: "preferred", Challenge: []byte("challenge"), @@ -30,7 +26,7 @@ func (a *authAPI) LoginSubjectStart(e echo.Context) error { } // LoginSubjectFinish handles the login subject finish. -func (a *authAPI) LoginSubjectFinish(e echo.Context) error { +func LoginSubjectFinish(e echo.Context) error { var crr protocol.CredentialAssertionResponse if err := e.Bind(&crr); err != nil { return err @@ -43,13 +39,13 @@ func (a *authAPI) LoginSubjectFinish(e echo.Context) error { // ╰───────────────────────────────────────────────────────────╯ // RegisterSubjectCheck handles the register subject check. -func (a *authAPI) RegisterSubjectCheck(e echo.Context) error { +func RegisterSubjectCheck(e echo.Context) error { subject := e.FormValue("subject") return e.JSON(200, subject) } // RegisterSubjectStart handles the register subject start. -func (a *authAPI) RegisterSubjectStart(e echo.Context) error { +func RegisterSubjectStart(e echo.Context) error { // Get subject and address subject := e.FormValue("subject") address := e.FormValue("address") @@ -63,7 +59,7 @@ func (a *authAPI) RegisterSubjectStart(e echo.Context) error { } // RegisterSubjectFinish handles the register subject finish. -func (a *authAPI) RegisterSubjectFinish(e echo.Context) error { +func RegisterSubjectFinish(e echo.Context) error { // Deserialize the JSON into a temporary struct var ccr protocol.CredentialCreationResponse if err := e.Bind(&ccr); err != nil { diff --git a/pkg/motr/handlers/openid.go b/pkg/motr/handlers/openid.go new file mode 100644 index 000000000..0f7c8417e --- /dev/null +++ b/pkg/motr/handlers/openid.go @@ -0,0 +1,23 @@ +package handlers + +import ( + "github.com/labstack/echo/v4" +) + +func GrantAuthorization(e echo.Context) error { + // Implement authorization endpoint using passkey authentication + // Store session data in cache + return nil +} + +func GetJWKS(e echo.Context) error { + // Implement token endpoint + // Use cached session data for validation + return nil +} + +func GetToken(e echo.Context) error { + // Implement token endpoint + // Use cached session data for validation + return nil +} diff --git a/pkg/motr/routes/routes.go b/pkg/motr/routes/routes.go new file mode 100644 index 000000000..71ee2f696 --- /dev/null +++ b/pkg/motr/routes/routes.go @@ -0,0 +1,26 @@ +package routes + +import ( + "github.com/labstack/echo/v4" + + "github.com/onsonr/sonr/pkg/motr/handlers" +) + +// RegisterWebNodeAPI registers the Decentralized Web Node API routes. +func RegisterWebNodeAPI(e *echo.Echo) { + g1 := e.Group("api") + g1.GET("/register/:subject/start", handlers.RegisterSubjectStart) + g1.POST("/register/:subject/check", handlers.RegisterSubjectCheck) + g1.POST("/register/:subject/finish", handlers.RegisterSubjectFinish) + + g1.GET("/login/:subject/start", handlers.LoginSubjectStart) + g1.POST("/login/:subject/check", handlers.LoginSubjectCheck) + g1.POST("/login/:subject/finish", handlers.LoginSubjectFinish) + + g1.GET("/:origin/grant/jwks", handlers.GetJWKS) + g1.GET("/:origin/grant/token", handlers.GetToken) + g1.POST("/:origin/grant/:subject", handlers.GrantAuthorization) +} + +func RegisterWebNodeViews(e *echo.Echo) { +} diff --git a/pkg/nebula/index.go b/pkg/motr/static/index.go similarity index 74% rename from pkg/nebula/index.go rename to pkg/motr/static/index.go index 7bbebfad8..079d92da6 100644 --- a/pkg/nebula/index.go +++ b/pkg/motr/static/index.go @@ -1,16 +1,17 @@ -package nebula +package static import ( "bytes" "context" "github.com/ipfs/boxo/files" - "github.com/onsonr/sonr/internal/dwn/gen" + + dwn "github.com/onsonr/sonr/pkg/motr/config" "github.com/onsonr/sonr/pkg/nebula/views" ) // BuildVaultFile builds the index.html file for the vault -func BuildVaultFile(cnfg *gen.Config) (files.Node, error) { +func BuildVaultFile(cnfg *dwn.Config) (files.Node, error) { w := bytes.NewBuffer(nil) err := views.VaultIndexFile().Render(context.Background(), w) if err != nil { diff --git a/internal/dwn/sw.js b/pkg/motr/static/sw.js similarity index 100% rename from internal/dwn/sw.js rename to pkg/motr/static/sw.js diff --git a/pkg/motr/types/api.pb.go b/pkg/motr/types/api.pb.go new file mode 100644 index 000000000..fa349d9ca --- /dev/null +++ b/pkg/motr/types/api.pb.go @@ -0,0 +1,342 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: motr/v1/api.proto + +package types + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PinRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cid string `protobuf:"bytes,1,opt,name=cid,proto3" json:"cid,omitempty"` +} + +func (x *PinRequest) Reset() { + *x = PinRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_motr_v1_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PinRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PinRequest) ProtoMessage() {} + +func (x *PinRequest) ProtoReflect() protoreflect.Message { + mi := &file_motr_v1_api_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PinRequest.ProtoReflect.Descriptor instead. +func (*PinRequest) Descriptor() ([]byte, []int) { + return file_motr_v1_api_proto_rawDescGZIP(), []int{0} +} + +func (x *PinRequest) GetCid() string { + if x != nil { + return x.Cid + } + return "" +} + +type PinResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *PinResponse) Reset() { + *x = PinResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_motr_v1_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PinResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PinResponse) ProtoMessage() {} + +func (x *PinResponse) ProtoReflect() protoreflect.Message { + mi := &file_motr_v1_api_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PinResponse.ProtoReflect.Descriptor instead. +func (*PinResponse) Descriptor() ([]byte, []int) { + return file_motr_v1_api_proto_rawDescGZIP(), []int{1} +} + +func (x *PinResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type UnpinRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cid string `protobuf:"bytes,1,opt,name=cid,proto3" json:"cid,omitempty"` +} + +func (x *UnpinRequest) Reset() { + *x = UnpinRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_motr_v1_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnpinRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnpinRequest) ProtoMessage() {} + +func (x *UnpinRequest) ProtoReflect() protoreflect.Message { + mi := &file_motr_v1_api_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnpinRequest.ProtoReflect.Descriptor instead. +func (*UnpinRequest) Descriptor() ([]byte, []int) { + return file_motr_v1_api_proto_rawDescGZIP(), []int{2} +} + +func (x *UnpinRequest) GetCid() string { + if x != nil { + return x.Cid + } + return "" +} + +type UnpinResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *UnpinResponse) Reset() { + *x = UnpinResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_motr_v1_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnpinResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnpinResponse) ProtoMessage() {} + +func (x *UnpinResponse) ProtoReflect() protoreflect.Message { + mi := &file_motr_v1_api_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnpinResponse.ProtoReflect.Descriptor instead. +func (*UnpinResponse) Descriptor() ([]byte, []int) { + return file_motr_v1_api_proto_rawDescGZIP(), []int{3} +} + +func (x *UnpinResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +var File_motr_v1_api_proto protoreflect.FileDescriptor + +var file_motr_v1_api_proto_rawDesc = []byte{ + 0x0a, 0x11, 0x6d, 0x6f, 0x74, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, 0x22, 0x1e, 0x0a, 0x0a, + 0x50, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x22, 0x27, 0x0a, 0x0b, + 0x50, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x20, 0x0a, 0x0c, 0x55, 0x6e, 0x70, 0x69, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x22, 0x29, 0x0a, 0x0d, 0x55, 0x6e, 0x70, 0x69, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x32, 0x70, 0x0a, 0x04, 0x4d, 0x6f, 0x74, 0x72, 0x12, 0x30, 0x0a, 0x03, 0x50, 0x69, + 0x6e, 0x12, 0x13, 0x2e, 0x6d, 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6d, 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, + 0x55, 0x6e, 0x70, 0x69, 0x6e, 0x12, 0x15, 0x2e, 0x6d, 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x6e, 0x70, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d, + 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, + 0x6b, 0x67, 0x2f, 0x6d, 0x6f, 0x74, 0x72, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_motr_v1_api_proto_rawDescOnce sync.Once + file_motr_v1_api_proto_rawDescData = file_motr_v1_api_proto_rawDesc +) + +func file_motr_v1_api_proto_rawDescGZIP() []byte { + file_motr_v1_api_proto_rawDescOnce.Do(func() { + file_motr_v1_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_motr_v1_api_proto_rawDescData) + }) + return file_motr_v1_api_proto_rawDescData +} + +var file_motr_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_motr_v1_api_proto_goTypes = []interface{}{ + (*PinRequest)(nil), // 0: motr.v1.PinRequest + (*PinResponse)(nil), // 1: motr.v1.PinResponse + (*UnpinRequest)(nil), // 2: motr.v1.UnpinRequest + (*UnpinResponse)(nil), // 3: motr.v1.UnpinResponse +} +var file_motr_v1_api_proto_depIdxs = []int32{ + 0, // 0: motr.v1.Motr.Pin:input_type -> motr.v1.PinRequest + 2, // 1: motr.v1.Motr.Unpin:input_type -> motr.v1.UnpinRequest + 1, // 2: motr.v1.Motr.Pin:output_type -> motr.v1.PinResponse + 3, // 3: motr.v1.Motr.Unpin:output_type -> motr.v1.UnpinResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_motr_v1_api_proto_init() } +func file_motr_v1_api_proto_init() { + if File_motr_v1_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_motr_v1_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PinRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_motr_v1_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PinResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_motr_v1_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnpinRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_motr_v1_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnpinResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_motr_v1_api_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_motr_v1_api_proto_goTypes, + DependencyIndexes: file_motr_v1_api_proto_depIdxs, + MessageInfos: file_motr_v1_api_proto_msgTypes, + }.Build() + File_motr_v1_api_proto = out.File + file_motr_v1_api_proto_rawDesc = nil + file_motr_v1_api_proto_goTypes = nil + file_motr_v1_api_proto_depIdxs = nil +} diff --git a/internal/orm/Account.pkl.go b/pkg/motr/types/orm/Account.pkl.go similarity index 100% rename from internal/orm/Account.pkl.go rename to pkg/motr/types/orm/Account.pkl.go diff --git a/internal/orm/Asset.pkl.go b/pkg/motr/types/orm/Asset.pkl.go similarity index 100% rename from internal/orm/Asset.pkl.go rename to pkg/motr/types/orm/Asset.pkl.go diff --git a/internal/orm/Chain.pkl.go b/pkg/motr/types/orm/Chain.pkl.go similarity index 100% rename from internal/orm/Chain.pkl.go rename to pkg/motr/types/orm/Chain.pkl.go diff --git a/internal/orm/Credential.pkl.go b/pkg/motr/types/orm/Credential.pkl.go similarity index 100% rename from internal/orm/Credential.pkl.go rename to pkg/motr/types/orm/Credential.pkl.go diff --git a/internal/orm/DID.pkl.go b/pkg/motr/types/orm/DID.pkl.go similarity index 60% rename from internal/orm/DID.pkl.go rename to pkg/motr/types/orm/DID.pkl.go index 8e4ee3f0a..6e630df07 100644 --- a/internal/orm/DID.pkl.go +++ b/pkg/motr/types/orm/DID.pkl.go @@ -2,11 +2,11 @@ package orm import ( - "github.com/onsonr/sonr/internal/orm/keyalgorithm" - "github.com/onsonr/sonr/internal/orm/keycurve" - "github.com/onsonr/sonr/internal/orm/keyencoding" - "github.com/onsonr/sonr/internal/orm/keyrole" - "github.com/onsonr/sonr/internal/orm/keytype" + "github.com/onsonr/sonr/pkg/motr/types/orm/keyalgorithm" + "github.com/onsonr/sonr/pkg/motr/types/orm/keycurve" + "github.com/onsonr/sonr/pkg/motr/types/orm/keyencoding" + "github.com/onsonr/sonr/pkg/motr/types/orm/keyrole" + "github.com/onsonr/sonr/pkg/motr/types/orm/keytype" ) type DID struct { diff --git a/internal/orm/Grant.pkl.go b/pkg/motr/types/orm/Grant.pkl.go similarity index 100% rename from internal/orm/Grant.pkl.go rename to pkg/motr/types/orm/Grant.pkl.go diff --git a/internal/orm/JWK.pkl.go b/pkg/motr/types/orm/JWK.pkl.go similarity index 100% rename from internal/orm/JWK.pkl.go rename to pkg/motr/types/orm/JWK.pkl.go diff --git a/internal/orm/Keyshare.pkl.go b/pkg/motr/types/orm/Keyshare.pkl.go similarity index 100% rename from internal/orm/Keyshare.pkl.go rename to pkg/motr/types/orm/Keyshare.pkl.go diff --git a/internal/orm/Orm.pkl.go b/pkg/motr/types/orm/Orm.pkl.go similarity index 100% rename from internal/orm/Orm.pkl.go rename to pkg/motr/types/orm/Orm.pkl.go diff --git a/internal/orm/Profile.pkl.go b/pkg/motr/types/orm/Profile.pkl.go similarity index 100% rename from internal/orm/Profile.pkl.go rename to pkg/motr/types/orm/Profile.pkl.go diff --git a/internal/orm/assettype/AssetType.pkl.go b/pkg/motr/types/orm/assettype/AssetType.pkl.go similarity index 100% rename from internal/orm/assettype/AssetType.pkl.go rename to pkg/motr/types/orm/assettype/AssetType.pkl.go diff --git a/internal/orm/didmethod/DIDMethod.pkl.go b/pkg/motr/types/orm/didmethod/DIDMethod.pkl.go similarity index 100% rename from internal/orm/didmethod/DIDMethod.pkl.go rename to pkg/motr/types/orm/didmethod/DIDMethod.pkl.go diff --git a/internal/orm/init.pkl.go b/pkg/motr/types/orm/init.pkl.go similarity index 100% rename from internal/orm/init.pkl.go rename to pkg/motr/types/orm/init.pkl.go diff --git a/internal/orm/keyalgorithm/KeyAlgorithm.pkl.go b/pkg/motr/types/orm/keyalgorithm/KeyAlgorithm.pkl.go similarity index 100% rename from internal/orm/keyalgorithm/KeyAlgorithm.pkl.go rename to pkg/motr/types/orm/keyalgorithm/KeyAlgorithm.pkl.go diff --git a/internal/orm/keycurve/KeyCurve.pkl.go b/pkg/motr/types/orm/keycurve/KeyCurve.pkl.go similarity index 100% rename from internal/orm/keycurve/KeyCurve.pkl.go rename to pkg/motr/types/orm/keycurve/KeyCurve.pkl.go diff --git a/internal/orm/keyencoding/KeyEncoding.pkl.go b/pkg/motr/types/orm/keyencoding/KeyEncoding.pkl.go similarity index 100% rename from internal/orm/keyencoding/KeyEncoding.pkl.go rename to pkg/motr/types/orm/keyencoding/KeyEncoding.pkl.go diff --git a/internal/orm/keyrole/KeyRole.pkl.go b/pkg/motr/types/orm/keyrole/KeyRole.pkl.go similarity index 100% rename from internal/orm/keyrole/KeyRole.pkl.go rename to pkg/motr/types/orm/keyrole/KeyRole.pkl.go diff --git a/internal/orm/keysharerole/KeyShareRole.pkl.go b/pkg/motr/types/orm/keysharerole/KeyShareRole.pkl.go similarity index 100% rename from internal/orm/keysharerole/KeyShareRole.pkl.go rename to pkg/motr/types/orm/keysharerole/KeyShareRole.pkl.go diff --git a/internal/orm/keytype/KeyType.pkl.go b/pkg/motr/types/orm/keytype/KeyType.pkl.go similarity index 100% rename from internal/orm/keytype/KeyType.pkl.go rename to pkg/motr/types/orm/keytype/KeyType.pkl.go diff --git a/internal/orm/permissiongrant/PermissionGrant.pkl.go b/pkg/motr/types/orm/permissiongrant/PermissionGrant.pkl.go similarity index 100% rename from internal/orm/permissiongrant/PermissionGrant.pkl.go rename to pkg/motr/types/orm/permissiongrant/PermissionGrant.pkl.go diff --git a/internal/orm/permissionscope/PermissionScope.pkl.go b/pkg/motr/types/orm/permissionscope/PermissionScope.pkl.go similarity index 100% rename from internal/orm/permissionscope/PermissionScope.pkl.go rename to pkg/motr/types/orm/permissionscope/PermissionScope.pkl.go diff --git a/internal/orm/schema.go b/pkg/motr/types/orm/schema.go similarity index 100% rename from internal/orm/schema.go rename to pkg/motr/types/orm/schema.go diff --git a/internal/orm/webauthn.go b/pkg/motr/types/orm/webauthn.go similarity index 100% rename from internal/orm/webauthn.go rename to pkg/motr/types/orm/webauthn.go diff --git a/pkg/nebula/marketing/section_arch.templ b/pkg/nebula/marketing/section_arch.templ index 8c828a50e..ce51901cd 100644 --- a/pkg/nebula/marketing/section_arch.templ +++ b/pkg/nebula/marketing/section_arch.templ @@ -1,8 +1,8 @@ package marketing import ( - models "github.com/onsonr/sonr/internal/orm/marketing" "github.com/onsonr/sonr/pkg/nebula/global" + models "github.com/onsonr/sonr/pkg/nebula/types" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_arch_templ.go b/pkg/nebula/marketing/section_arch_templ.go index d81293a73..538845904 100644 --- a/pkg/nebula/marketing/section_arch_templ.go +++ b/pkg/nebula/marketing/section_arch_templ.go @@ -9,8 +9,8 @@ import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import ( - models "github.com/onsonr/sonr/internal/orm/marketing" "github.com/onsonr/sonr/pkg/nebula/global" + models "github.com/onsonr/sonr/pkg/nebula/types" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_cta.templ b/pkg/nebula/marketing/section_cta.templ index f32e9f6b0..07d87b740 100644 --- a/pkg/nebula/marketing/section_cta.templ +++ b/pkg/nebula/marketing/section_cta.templ @@ -1,6 +1,6 @@ package marketing -import models "github.com/onsonr/sonr/internal/orm/marketing" +import models "github.com/onsonr/sonr/pkg/nebula/types" // ╭───────────────────────────────────────────────────────────╮ // │ Data Model │ diff --git a/pkg/nebula/marketing/section_cta_templ.go b/pkg/nebula/marketing/section_cta_templ.go index f9457fa50..9ccb79420 100644 --- a/pkg/nebula/marketing/section_cta_templ.go +++ b/pkg/nebula/marketing/section_cta_templ.go @@ -8,7 +8,7 @@ package marketing import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import models "github.com/onsonr/sonr/internal/orm/marketing" +import models "github.com/onsonr/sonr/pkg/nebula/types" // ╭───────────────────────────────────────────────────────────╮ // │ Data Model │ diff --git a/pkg/nebula/marketing/section_hero.templ b/pkg/nebula/marketing/section_hero.templ index 749d66b19..816dbf74a 100644 --- a/pkg/nebula/marketing/section_hero.templ +++ b/pkg/nebula/marketing/section_hero.templ @@ -2,8 +2,8 @@ package marketing import ( "fmt" - models "github.com/onsonr/sonr/internal/orm/marketing" "github.com/onsonr/sonr/pkg/nebula/global/ui" + models "github.com/onsonr/sonr/pkg/nebula/types" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_hero_templ.go b/pkg/nebula/marketing/section_hero_templ.go index 5ca335062..e3a284a0a 100644 --- a/pkg/nebula/marketing/section_hero_templ.go +++ b/pkg/nebula/marketing/section_hero_templ.go @@ -10,8 +10,8 @@ import templruntime "github.com/a-h/templ/runtime" import ( "fmt" - models "github.com/onsonr/sonr/internal/orm/marketing" "github.com/onsonr/sonr/pkg/nebula/global/ui" + models "github.com/onsonr/sonr/pkg/nebula/types" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_highlights.templ b/pkg/nebula/marketing/section_highlights.templ index 711a452b8..7ed4496b1 100644 --- a/pkg/nebula/marketing/section_highlights.templ +++ b/pkg/nebula/marketing/section_highlights.templ @@ -2,7 +2,7 @@ package marketing import ( "fmt" - models "github.com/onsonr/sonr/internal/orm/marketing" + models "github.com/onsonr/sonr/pkg/nebula/types" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_highlights_templ.go b/pkg/nebula/marketing/section_highlights_templ.go index 08f0b6d0b..7db4c2961 100644 --- a/pkg/nebula/marketing/section_highlights_templ.go +++ b/pkg/nebula/marketing/section_highlights_templ.go @@ -10,7 +10,7 @@ import templruntime "github.com/a-h/templ/runtime" import ( "fmt" - models "github.com/onsonr/sonr/internal/orm/marketing" + models "github.com/onsonr/sonr/pkg/nebula/types" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_lowlights.templ b/pkg/nebula/marketing/section_lowlights.templ index 40c3ebc66..f2e3d08cd 100644 --- a/pkg/nebula/marketing/section_lowlights.templ +++ b/pkg/nebula/marketing/section_lowlights.templ @@ -1,8 +1,8 @@ package marketing import ( - models "github.com/onsonr/sonr/internal/orm/marketing" global "github.com/onsonr/sonr/pkg/nebula/global" + models "github.com/onsonr/sonr/pkg/nebula/types" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_lowlights_templ.go b/pkg/nebula/marketing/section_lowlights_templ.go index a0c495788..e3ac78ced 100644 --- a/pkg/nebula/marketing/section_lowlights_templ.go +++ b/pkg/nebula/marketing/section_lowlights_templ.go @@ -9,8 +9,8 @@ import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import ( - models "github.com/onsonr/sonr/internal/orm/marketing" global "github.com/onsonr/sonr/pkg/nebula/global" + models "github.com/onsonr/sonr/pkg/nebula/types" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_mission.templ b/pkg/nebula/marketing/section_mission.templ index 738ffcd50..a48e9296b 100644 --- a/pkg/nebula/marketing/section_mission.templ +++ b/pkg/nebula/marketing/section_mission.templ @@ -1,6 +1,6 @@ package marketing -import models "github.com/onsonr/sonr/internal/orm/marketing" +import models "github.com/onsonr/sonr/pkg/nebula/types" // mission is the (3rd) home page mission section var mission = &models.Mission{ diff --git a/pkg/nebula/marketing/section_mission_templ.go b/pkg/nebula/marketing/section_mission_templ.go index e46abce2a..f5c2da36e 100644 --- a/pkg/nebula/marketing/section_mission_templ.go +++ b/pkg/nebula/marketing/section_mission_templ.go @@ -8,7 +8,7 @@ package marketing import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import models "github.com/onsonr/sonr/internal/orm/marketing" +import models "github.com/onsonr/sonr/pkg/nebula/types" // mission is the (3rd) home page mission section var mission = &models.Mission{ diff --git a/pkg/nebula/routes/auth.go b/pkg/nebula/routes/auth.go index 336aa4eb9..17a179b60 100644 --- a/pkg/nebula/routes/auth.go +++ b/pkg/nebula/routes/auth.go @@ -4,7 +4,8 @@ import ( "log" "github.com/labstack/echo/v4" - "github.com/onsonr/sonr/internal/ctx" + + "github.com/onsonr/sonr/pkg/common/ctx" "github.com/onsonr/sonr/pkg/nebula/modals" "github.com/onsonr/sonr/pkg/nebula/views" ) diff --git a/pkg/nebula/routes/home.go b/pkg/nebula/routes/home.go index c8ff70fe4..0525b9dfd 100644 --- a/pkg/nebula/routes/home.go +++ b/pkg/nebula/routes/home.go @@ -4,7 +4,8 @@ import ( "log" "github.com/labstack/echo/v4" - "github.com/onsonr/sonr/internal/ctx" + + "github.com/onsonr/sonr/pkg/common/ctx" "github.com/onsonr/sonr/pkg/nebula/marketing" ) diff --git a/internal/orm/marketing/models.go b/pkg/nebula/types/marketing.go similarity index 99% rename from internal/orm/marketing/models.go rename to pkg/nebula/types/marketing.go index 89ebb6025..e035f71f0 100644 --- a/internal/orm/marketing/models.go +++ b/pkg/nebula/types/marketing.go @@ -1,4 +1,4 @@ -package marketing +package types type Button struct { Text string diff --git a/pkg/workers/README.md b/pkg/workers/README.md deleted file mode 100644 index 4684b1afa..000000000 --- a/pkg/workers/README.md +++ /dev/null @@ -1 +0,0 @@ -# Workers diff --git a/pkg/workers/client/http.go b/pkg/workers/client/http.go deleted file mode 100644 index bcdc78a4b..000000000 --- a/pkg/workers/client/http.go +++ /dev/null @@ -1,47 +0,0 @@ -package client - -import "net/http" - -// SonrClient is a REST HTTP client for Querying Module Endpoints -// for the Sonr blockchain. -type SonrClient struct { - apiURL string -} - -// NewLocal creates a new SonrClient for local development. -func NewLocal() (*SonrClient, error) { - // create http client - client := &SonrClient{ - apiURL: "http://localhost:1323", - } - // Issue ping to check if server is up - resp, err := http.Get(client.apiURL + "/genesis") - if err != nil { - return nil, err - } - defer resp.Body.Close() - // Check if server is up - if resp.StatusCode != http.StatusOK { - return nil, err - } - return client, nil -} - -// NewRemote creates a new SonrClient for remote production. -func NewRemote(url string) (*SonrClient, error) { - // create http client - client := &SonrClient{ - apiURL: url, - } - // Issue ping to check if server is up - resp, err := http.Get(client.apiURL + "/genesis") - if err != nil { - return nil, err - } - defer resp.Body.Close() - // Check if server is up - if resp.StatusCode != http.StatusOK { - return nil, err - } - return client, nil -} diff --git a/pkg/workers/handlers/openid.go b/pkg/workers/handlers/openid.go deleted file mode 100644 index 3d061f31c..000000000 --- a/pkg/workers/handlers/openid.go +++ /dev/null @@ -1,31 +0,0 @@ -package handlers - -import ( - "github.com/labstack/echo/v4" -) - -func (a *openidAPI) GrantAuthorization(e echo.Context) error { - // Implement authorization endpoint using passkey authentication - // Store session data in cache - return nil -} - -func (a *openidAPI) GetJWKS(e echo.Context) error { - // Implement token endpoint - // Use cached session data for validation - return nil -} - -func (a *openidAPI) GetToken(e echo.Context) error { - // Implement token endpoint - // Use cached session data for validation - return nil -} - -// ╭───────────────────────────────────────────────────────────╮ -// │ Group Structures │ -// ╰───────────────────────────────────────────────────────────╯ - -type openidAPI struct{} - -var OpenID = new(openidAPI) diff --git a/pkg/workers/handlers/sync.go b/pkg/workers/handlers/sync.go deleted file mode 100644 index d6a3996c3..000000000 --- a/pkg/workers/handlers/sync.go +++ /dev/null @@ -1,25 +0,0 @@ -package handlers - -import "github.com/labstack/echo/v4" - -// ╭───────────────────────────────────────────────────────────╮ -// │ Dexie Database Handlers │ -// ╰───────────────────────────────────────────────────────────╯ - -func (a *syncAPI) FetchInitial(e echo.Context) error { - // Implement database schema endpoint - return nil -} - -func (a *syncAPI) FetchCurrent(e echo.Context) error { - // Implement account entries endpoint - return nil -} - -// ╭───────────────────────────────────────────────────────────╮ -// │ Group Structures │ -// ╰───────────────────────────────────────────────────────────╯ - -type syncAPI struct{} - -var Sync = new(syncAPI) diff --git a/pkg/workers/routes/webnode.go b/pkg/workers/routes/webnode.go deleted file mode 100644 index fa0cb3900..000000000 --- a/pkg/workers/routes/webnode.go +++ /dev/null @@ -1,33 +0,0 @@ -package routes - -import ( - "github.com/labstack/echo/v4" - - "github.com/onsonr/sonr/pkg/nebula/routes" - "github.com/onsonr/sonr/pkg/workers/handlers" -) - -// RegisterWebNodeAPI registers the Decentralized Web Node API routes. -func RegisterWebNodeAPI(e *echo.Echo) { - g1 := e.Group("api") - g1.GET("/register/:subject/start", handlers.Auth.RegisterSubjectStart) - g1.POST("/register/:subject/check", handlers.Auth.RegisterSubjectCheck) - g1.POST("/register/:subject/finish", handlers.Auth.RegisterSubjectFinish) - - g1.GET("/login/:subject/start", handlers.Auth.LoginSubjectStart) - g1.POST("/login/:subject/check", handlers.Auth.LoginSubjectCheck) - g1.POST("/login/:subject/finish", handlers.Auth.LoginSubjectFinish) - - g1.GET("/:origin/grant/jwks", handlers.OpenID.GetJWKS) - g1.GET("/:origin/grant/token", handlers.OpenID.GetToken) - g1.POST("/:origin/grant/:subject", handlers.OpenID.GrantAuthorization) -} - -// RegisterWebNodeViews registers the Decentralized Web Node HTMX views. -func RegisterWebNodeViews(e *echo.Echo) { - e.File("/", "index.html") - e.GET("/#", routes.CurrentViewRoute) - e.GET("/login", routes.LoginModalRoute) - e.File("/config", "config.json") - e.GET("/register", routes.RegisterModalRoute) -} diff --git a/pkl/Txns.pkl b/pkl/Txns.pkl deleted file mode 100644 index e658489b1..000000000 --- a/pkl/Txns.pkl +++ /dev/null @@ -1,174 +0,0 @@ -@go.Package { name = "github.com/onsonr/sonr/internal/orm/transactions" } - -module transactions - -import "package://pkg.pkl-lang.org/pkl-go/pkl.golang@0.5.0#/go.pkl" - -/// Common Cosmos SDK types -typealias Coin = Dynamic -typealias AccAddress = String -typealias ValAddress = String -typealias Timestamp = String - -/// Base class for all messages -abstract class Msg { - /// The type URL for the message - typeUrl: String -} - -/// Base class for all proposals -class Proposal { - /// The title of the proposal - title: String - - /// The description of the proposal - description: String -} - -/// Gov module messages -class MsgGovSubmitProposal extends Msg { - typeUrl = "/cosmos.gov.v1beta1.MsgSubmitProposal" - content: Proposal - initialDeposit: List - proposer: AccAddress -} - -class MsgGovVote extends Msg { - typeUrl = "/cosmos.gov.v1beta1.MsgVote" - proposalId: Int - voter: AccAddress - option: Int -} - -class MsgGovDeposit extends Msg { - typeUrl = "/cosmos.gov.v1beta1.MsgDeposit" - proposalId: Int - depositor: AccAddress - amount: List -} - -/// Group module messages - class MsgGroupCreateGroup extends Msg { - typeUrl = "/cosmos.group.v1.MsgCreateGroup" - admin: AccAddress - members: List - metadata: String - } - - class MsgGroupSubmitProposal extends Msg { - typeUrl = "/cosmos.group.v1.MsgSubmitProposal" - groupPolicyAddress: AccAddress - proposers: List - metadata: String - messages: List - exec: Int - } - - class MsgGroupVote extends Msg { - typeUrl = "/cosmos.group.v1.MsgVote" - proposalId: Int - voter: AccAddress - option: Int - metadata: String - exec: Int - } - -/// Staking module messages - class MsgStakingCreateValidator extends Msg { - typeUrl = "/cosmos.staking.v1beta1.MsgCreateValidator" - description: Dynamic - commission: Dynamic - minSelfDelegation: String - delegatorAddress: AccAddress - validatorAddress: ValAddress - pubkey: Dynamic - value: Coin - } - - class MsgStakingDelegate extends Msg { - typeUrl = "/cosmos.staking.v1beta1.MsgDelegate" - delegatorAddress: AccAddress - validatorAddress: ValAddress - amount: Coin - } - - class MsgStakingUndelegate extends Msg { - typeUrl = "/cosmos.staking.v1beta1.MsgUndelegate" - delegatorAddress: AccAddress - validatorAddress: ValAddress - amount: Coin - } - - class MsgStakingBeginRedelegate extends Msg { - typeUrl = "/cosmos.staking.v1beta1.MsgBeginRedelegate" - delegatorAddress: AccAddress - validatorSrcAddress: ValAddress - validatorDstAddress: ValAddress - amount: Coin - } - class MsgDidUpdateParams extends Msg { - typeUrl = "/sonr.did.v1.MsgUpdateParams" - authority: AccAddress - params: Dynamic - token: Dynamic - } - - class MsgDidAllocateVault extends Msg { - typeUrl = "/sonr.did.v1.MsgAllocateVault" - authority: AccAddress - subject: String - token: Dynamic - } - - class MsgDidProveWitness extends Msg { - typeUrl = "/sonr.did.v1.MsgProveWitness" - authority: AccAddress - property: String - witness: Listing - token: Dynamic - } - - class MsgDidSyncVault extends Msg { - typeUrl = "/sonr.did.v1.MsgSyncVault" - controller: AccAddress - token: Dynamic - } - -class MsgDidRegisterController extends Msg { - typeUrl = "/sonr.did.v1.MsgRegisterController" - authority: AccAddress - cid: String - origin: String - authentication: List - token: Dynamic - } - -class MsgDidAuthorize extends Msg { - typeUrl = "/sonr.did.v1.MsgAuthorize" - authority: AccAddress - controller: AccAddress - address: AccAddress - origin: String - token: Dynamic - } - -class MsgDidRegisterService extends Msg { - typeUrl = "/sonr.did.v1.MsgRegisterService" - controller: AccAddress - originUri: String - scopes: Dynamic - description: String - serviceEndpoints: Map - metadata: Dynamic - token: Dynamic - } - -/// Represents a transaction body -class TxBody { - messages: List - memo: String? - timeoutHeight: Int? - extensionOptions: List? - nonCriticalExtensionOptions: List? -} - diff --git a/proto/README.md b/proto/README.md index 184b8d63d..d99969d9a 100644 --- a/proto/README.md +++ b/proto/README.md @@ -10,10 +10,6 @@ This directory contains the protobuf definitions for the Sonr blockchain. The `did` directory contains the protobuf definitions for the DID module. -### `macaroon` - -The `macaroon` directory contains the protobuf definitions for the Macaroon module. - ### `service` The `service` directory contains the protobuf definitions for the Service module. @@ -21,5 +17,3 @@ The `service` directory contains the protobuf definitions for the Service module ### `vault` The `vault` directory contains the protobuf definitions for the Vault module. - -### `buf.gen.gogo.yaml` diff --git a/proto/buf.lock b/proto/buf.lock index e9e9d3b8f..b003e48f9 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -19,8 +19,13 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - commit: e7f8d366f5264595bcc4cd4139af9973 - digest: shake256:e5e5f1c12f82e028ea696faa43b4f9dc6258a6d1226282962a8c8b282e10946281d815884f574bd279ebd9cd7588629beb3db17b892af6c33b56f92f8f67f509 + commit: c0913f24652a4cfc95f77d97443a5005 + digest: shake256:0ef3248c6235d420fe61f373154adcde6b94e3297f82472b1d8d8c3747240b61b4a10405e2a6f8ac1c98816ac6e690ea7871024aa5ae0e035cd540214667ceed + - remote: buf.build + owner: onsonr + repository: thirdparty + commit: 915d759135b04de684c86d9cf5daf256 + digest: shake256:13d0254ab4884f2d47f21d229dc3b17ea859f81d8283c021956ccd0da864228a939d055c8c85a86c66307fd7bd19654da6b3fb89fccd6c6d38ee46651a5951b5 - remote: buf.build owner: protocolbuffers repository: wellknowntypes diff --git a/proto/buf.yaml b/proto/buf.yaml index af2b76670..d16bcb9d8 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -5,6 +5,7 @@ deps: - buf.build/cosmos/cosmos-proto - buf.build/cosmos/gogo-proto - buf.build/googleapis/googleapis + - buf.build/onsonr/thirdparty breaking: use: - FILE diff --git a/proto/did/module/v1/module.proto b/proto/did/module/v1/module.proto index c813587d2..3e6599ea6 100644 --- a/proto/did/module/v1/module.proto +++ b/proto/did/module/v1/module.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package onsonr.sonr.did.module.v1; +package did.module.v1; import "cosmos/app/v1alpha1/module.proto"; // Module is the app config object of the module. // Learn more: https://docs.cosmos.network/main/building-modules/depinject message Module { - option (cosmos.app.v1alpha1.module) = {go_import: "github.com/onsonr/sonr/x/did"}; + option (cosmos.app.v1alpha1.module) = {go_import: "github.com/onsonr/sonr"}; } diff --git a/proto/did/v1/genesis.proto b/proto/did/v1/genesis.proto index 4bc2a52e2..2544ecc9f 100644 --- a/proto/did/v1/genesis.proto +++ b/proto/did/v1/genesis.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package did.v1; import "amino/amino.proto"; +import "did/v1/params.proto"; import "gogoproto/gogo.proto"; option go_package = "github.com/onsonr/sonr/x/did/types"; @@ -9,63 +10,16 @@ option go_package = "github.com/onsonr/sonr/x/did/types"; // GenesisState defines the module genesis state message GenesisState { // Params defines all the parameters of the module. - Params params = 1 [ (gogoproto.nullable) = false ]; + Params params = 1 [(gogoproto.nullable) = false]; } -// Params defines the set of module parameters. -message Params { - option (amino.name) = "did/params"; - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - // Whitelisted Assets - - // Whitelisted Key Types - map allowed_public_keys = 2; - - // ConveyancePreference defines the conveyance preference - string conveyance_preference = 3; - - // AttestationFormats defines the attestation formats - repeated string attestation_formats = 4; -} - -// KeyInfo defines information for accepted PubKey types -message KeyInfo { - string role = 1; - string algorithm = 2; // e.g., "ES256", "EdDSA", "ES256K" - string encoding = 3; // e.g., "hex", "base64", "multibase" - string curve = 4; // e.g., "P256", "P384", "P521", "X25519", "X448", - // "Ed25519", "Ed448", "secp256k1" -} - -message Keyshares { - string validator_cid = 1; - string user_cid = 2; - int64 last_updated_block = 3; -} - -// PubKey defines a public key for a did -message PubKey { - string role = 1; - string key_type = 2; - RawKey raw_key = 3; - JSONWebKey jwk = 4; -} - -// JWK represents a JSON Web Key -message JSONWebKey { - string kty = 1; // Key Type - string crv = 2; // Curve (for EC and OKP keys) - string x = 3; // X coordinate (for EC and OKP keys) - string y = 4; // Y coordinate (for EC keys) - string n = 5; // Modulus (for RSA keys) - string e = 6; // Exponent (for RSA keys) -} - -message RawKey { - string algorithm = 1; - string encoding = 2; - string curve = 3; - bytes key = 4; +// Document defines a DID document +message Document { + string id = 1; + string controller = 2; // The DID of the controller + repeated string authentication = 3; + repeated string assertion_method = 4; + repeated string capability_delegation = 5; + repeated string capability_invocation = 6; + repeated string service = 7; } diff --git a/proto/did/v1/params.proto b/proto/did/v1/params.proto new file mode 100644 index 000000000..a27e60ec0 --- /dev/null +++ b/proto/did/v1/params.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +package did.v1; + +import "amino/amino.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/onsonr/sonr/x/did/types"; + +// Params defines the set of module parameters. +message Params { + option (amino.name) = "did/params"; + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // Whitelisted Assets + + // Whitelisted Key Types + map allowed_public_keys = 2; + + // ConveyancePreference defines the conveyance preference + string conveyance_preference = 3; + + // AttestationFormats defines the attestation formats + repeated string attestation_formats = 4; +} + +// KeyInfo defines information for accepted PubKey types +message KeyInfo { + string role = 1; + string algorithm = 2; // e.g., "ES256", "EdDSA", "ES256K" + string encoding = 3; // e.g., "hex", "base64", "multibase" + string curve = 4; // e.g., "P256", "P384", "P521", "X25519", "X448", + // "Ed25519", "Ed448", "secp256k1" +} diff --git a/proto/did/v1/query.proto b/proto/did/v1/query.proto index 42559bf7f..4d3a54396 100644 --- a/proto/did/v1/query.proto +++ b/proto/did/v1/query.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package did.v1; import "did/v1/genesis.proto"; +import "did/v1/params.proto"; import "google/api/annotations.proto"; option go_package = "github.com/onsonr/sonr/x/did/types"; @@ -18,11 +19,6 @@ service Query { option (google.api.http).get = "/did/v1/{did}"; } - // Sign signs a message with the DID document - rpc Sign(QuerySignRequest) returns (QuerySignResponse) { - option (google.api.http).post = "/did/v1/{did}/sign"; - } - // Verify verifies a message with the DID document rpc Verify(QueryVerifyRequest) returns (QueryVerifyResponse) { option (google.api.http).post = "/did/v1/{did}/verify"; @@ -79,14 +75,3 @@ message QueryVerifyResponse { // valid is the validity of the signature bool valid = 1; } - -// Document defines a DID document -message Document { - string id = 1; - string controller = 2; // The DID of the controller - repeated string authentication = 3; - repeated string assertion_method = 4; - repeated string capability_delegation = 5; - repeated string capability_invocation = 6; - repeated string service = 7; -} diff --git a/proto/did/v1/state.proto b/proto/did/v1/state.proto index ccffbe3dc..3d4576380 100644 --- a/proto/did/v1/state.proto +++ b/proto/did/v1/state.proto @@ -9,9 +9,13 @@ option go_package = "github.com/onsonr/sonr/x/did/types"; message Assertion { option (cosmos.orm.v1.table) = { - id : 1 - primary_key : {fields : "did"} - index : {id : 1 fields : "controller,subject" unique : true} + id: 1 + primary_key: {fields: "did"} + index: { + id: 1 + fields: "controller,subject" + unique: true + } }; // The unique identifier of the assertion @@ -23,8 +27,8 @@ message Assertion { // Origin of the authentication string subject = 3; - // PubKey is the verification method - PubKey public_key = 4; + // string is the verification method + string public_key_hex = 4; // AssertionType is the assertion type string assertion_type = 5; @@ -38,9 +42,13 @@ message Assertion { message Authentication { option (cosmos.orm.v1.table) = { - id : 2 - primary_key : {fields : "did"} - index : {id : 1 fields : "controller,subject" unique : true} + id: 2 + primary_key: {fields: "did"} + index: { + id: 1 + fields: "controller,subject" + unique: true + } }; // The unique identifier of the authentication @@ -52,8 +60,8 @@ message Authentication { // Origin of the authentication string subject = 3; - // PubKey is the verification method - PubKey public_key = 4; + // string is the verification method + string public_key_hex = 4; // CredentialID is the byte representation of the credential ID bytes credential_id = 5; @@ -65,15 +73,57 @@ message Authentication { int64 creation_block = 7; } +// Macaroon is a Macaroon message type. +message Biscuit { + option (cosmos.orm.v1.table) = { + id: 5 + primary_key: { + fields: "id" + auto_increment: true + } + index: { + id: 1 + fields: "subject,origin" + unique: true + } + }; + + uint64 id = 1; + string controller = 2; + string subject = 3; + string origin = 4; + int64 expiry_height = 5; + string macaroon = 6; +} + // Controller represents a Sonr DWN Vault message Controller { option (cosmos.orm.v1.table) = { - id : 3 - primary_key : {fields : "number" auto_increment : true} - index : {id : 1 fields : "sonr_address" unique : true} - index : {id : 2 fields : "eth_address" unique : true} - index : {id : 3 fields : "btc_address" unique : true} - index : {id : 4 fields : "did" unique : true} + id: 3 + primary_key: { + fields: "number" + auto_increment: true + } + index: { + id: 1 + fields: "sonr_address" + unique: true + } + index: { + id: 2 + fields: "eth_address" + unique: true + } + index: { + id: 3 + fields: "btc_address" + unique: true + } + index: { + id: 4 + fields: "did" + unique: true + } }; // The unique identifier of the controller @@ -91,8 +141,8 @@ message Controller { // The DID of the controller string btc_address = 5; - // PubKey is the verification method - PubKey public_key = 6; + // string is the verification method + string public_key_hex = 6; // Pointer to the Keyshares string ks_val = 7; @@ -104,45 +154,26 @@ message Controller { int64 creation_block = 9; } -// Grant is a Grant message type. -message Grant { - option (cosmos.orm.v1.table) = { - id : 4 - primary_key : {fields : "id" auto_increment : true} - index : {id : 1 fields : "subject,origin" unique : true} - }; - - uint64 id = 1; - string controller = 2; - string subject = 3; - string origin = 4; - int64 expiry_height = 5; -} - -// Macaroon is a Macaroon message type. -message Macaroon { - option (cosmos.orm.v1.table) = { - id : 5 - primary_key : {fields : "id" auto_increment : true} - index : {id : 1 fields : "subject,origin" unique : true} - }; - - uint64 id = 1; - string controller = 2; - string subject = 3; - string origin = 4; - int64 expiry_height = 5; - string macaroon = 6; -} - // Verification represents a verification method message Verification { option (cosmos.orm.v1.table) = { - id : 6 - primary_key : {fields : "did"} - index : {id : 1 fields : "issuer,subject" unique : true} - index : {id : 2 fields : "controller,did_method,issuer" unique : true} - index : {id : 3 fields : "verification_type,subject,issuer" unique : true} + id: 6 + primary_key: {fields: "did"} + index: { + id: 1 + fields: "issuer,subject" + unique: true + } + index: { + id: 2 + fields: "controller,did_method,issuer" + unique: true + } + index: { + id: 3 + fields: "verification_type,subject,issuer" + unique: true + } }; // The unique identifier of the verification @@ -161,7 +192,7 @@ message Verification { string subject = 5; // The public key of the verification - PubKey public_key = 6; + string public_key_hex = 6; // The verification method type string verification_type = 7; diff --git a/proto/did/v1/tx.proto b/proto/did/v1/tx.proto index 20a310c3f..c451ad2e8 100644 --- a/proto/did/v1/tx.proto +++ b/proto/did/v1/tx.proto @@ -5,6 +5,7 @@ package did.v1; import "cosmos/msg/v1/msg.proto"; import "cosmos_proto/cosmos.proto"; import "did/v1/genesis.proto"; +import "did/v1/params.proto"; import "gogoproto/gogo.proto"; option go_package = "github.com/onsonr/sonr/x/did/types"; @@ -21,16 +22,13 @@ service Msg { rpc LinkAssertion(MsgLinkAssertion) returns (MsgLinkAssertionResponse); // LinkAuthentication links an authentication to a controller. - rpc LinkAuthentication(MsgLinkAuthentication) - returns (MsgLinkAuthenticationResponse); + rpc LinkAuthentication(MsgLinkAuthentication) returns (MsgLinkAuthenticationResponse); // UnlinkAssertion unlinks an assertion from a controller. - rpc UnlinkAssertion(MsgUnlinkAssertion) - returns (MsgUnlinkAssertionResponse); + rpc UnlinkAssertion(MsgUnlinkAssertion) returns (MsgUnlinkAssertionResponse); // UnlinkAuthentication unlinks an authentication from a controller. - rpc UnlinkAuthentication(MsgUnlinkAuthentication) - returns (MsgUnlinkAuthenticationResponse); + rpc UnlinkAuthentication(MsgUnlinkAuthentication) returns (MsgUnlinkAuthenticationResponse); // UpdateParams defines a governance operation for updating the parameters. rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); @@ -41,7 +39,7 @@ message MsgLinkAuthentication { option (cosmos.msg.v1.signer) = "controller"; // Controller is the address of the controller to authenticate. - string controller = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string controller = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // Subject is the subject of the authentication. string subject = 2; @@ -72,7 +70,7 @@ message MsgLinkAssertion { option (cosmos.msg.v1.signer) = "controller"; // Controller is the address of the controller to authenticate. - string controller = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string controller = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // Subject is the subject of the authentication. string subject = 2; @@ -95,13 +93,12 @@ message MsgLinkAssertionResponse { string did = 2; } - // MsgExecuteTx is the message type for the ExecuteTx RPC. message MsgExecuteTx { option (cosmos.msg.v1.signer) = "controller"; // Controller is the address of the controller to authenticate. - string controller = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string controller = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // Messages is the list of messages to execute. map messages = 2; @@ -121,7 +118,7 @@ message MsgUnlinkAssertion { option (cosmos.msg.v1.signer) = "controller"; // Controller is the address of the controller to authenticate. - string controller = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string controller = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // Assertion is the assertion of the authentication. string assertion_did = 2; @@ -146,7 +143,7 @@ message MsgUnlinkAuthentication { option (cosmos.msg.v1.signer) = "controller"; // Controller is the address of the controller to authenticate. - string controller = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string controller = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // Subject is the subject of the authentication. string authentication_did = 2; @@ -173,10 +170,10 @@ message MsgUpdateParams { option (cosmos.msg.v1.signer) = "authority"; // authority is the address of the governance account. - string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // params defines the parameters to update. - Params params = 2 [ (gogoproto.nullable) = false ]; + Params params = 2 [(gogoproto.nullable) = false]; // token is the macron token to authenticate the operation. string token = 3; diff --git a/proto/service/module/v1/module.proto b/proto/service/module/v1/module.proto index 115913b1c..15a603131 100644 --- a/proto/service/module/v1/module.proto +++ b/proto/service/module/v1/module.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package onsonr.sonr.service.module.v1; +package service.module.v1; import "cosmos/app/v1alpha1/module.proto"; // Module is the app config object of the module. // Learn more: https://docs.cosmos.network/main/building-modules/depinject message Module { - option (cosmos.app.v1alpha1.module) = {go_import: "github.com/onsonr/sonr/x/service"}; + option (cosmos.app.v1alpha1.module) = {go_import: "github.com/onsonr/sonr"}; } diff --git a/proto/service/v1/state.proto b/proto/service/v1/state.proto index 78c6520f2..b9a84b191 100644 --- a/proto/service/v1/state.proto +++ b/proto/service/v1/state.proto @@ -9,9 +9,16 @@ option go_package = "github.com/onsonr/sonr/x/service/types"; message Metadata { option (cosmos.orm.v1.table) = { - id : 1 - primary_key : {fields : "id" auto_increment : true} - index : {id : 1 fields : "origin" unique : true} + id: 1 + primary_key: { + fields: "id" + auto_increment: true + } + index: { + id: 1 + fields: "origin" + unique: true + } }; uint64 id = 1; @@ -19,16 +26,20 @@ message Metadata { string name = 3; string description = 4; string category = 5; - URI icon = 6; + string icon = 6; repeated string tags = 7; } // Profile represents a DID alias message Profile { option (cosmos.orm.v1.table) = { - id : 2 - primary_key : {fields : "id"} - index : {id : 1 fields : "subject,origin" unique : true} + id: 2 + primary_key: {fields: "id"} + index: { + id: 1 + fields: "subject,origin" + unique: true + } }; // The unique identifier of the alias @@ -43,13 +54,3 @@ message Profile { // Controller of the alias string controller = 4; } - -message URI { - enum Protocol { - HTTPS = 0; - IPFS = 1; - } - - Protocol protocol = 1; - string uri = 2; -} diff --git a/proto/service/v1/tx.proto b/proto/service/v1/tx.proto index 35bbb4e77..063b48c61 100644 --- a/proto/service/v1/tx.proto +++ b/proto/service/v1/tx.proto @@ -29,12 +29,12 @@ message MsgUpdateParams { option (cosmos.msg.v1.signer) = "authority"; // authority is the address of the governance account. - string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // params defines the parameters to update. // // NOTE: All parameters must be supplied. - Params params = 2 [ (gogoproto.nullable) = false ]; + Params params = 2 [(gogoproto.nullable) = false]; } // MsgUpdateParamsResponse defines the response structure for executing a @@ -48,7 +48,7 @@ message MsgRegisterService { option (cosmos.msg.v1.signer) = "controller"; // authority is the address of the governance account. - string controller = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string controller = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // origin is the origin of the request in wildcard form. Requires valid TXT // record in DNS. diff --git a/proto/vault/module/v1/module.proto b/proto/vault/module/v1/module.proto index 3501fc75b..c3d0166ee 100644 --- a/proto/vault/module/v1/module.proto +++ b/proto/vault/module/v1/module.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package onsonr.sonr.vault.module.v1; +package vault.module.v1; import "cosmos/app/v1alpha1/module.proto"; // Module is the app config object of the module. // Learn more: https://docs.cosmos.network/main/building-modules/depinject message Module { - option (cosmos.app.v1alpha1.module) = {go_import: "github.com/onsonr/sonr/x/vault"}; + option (cosmos.app.v1alpha1.module) = {go_import: "github.com/onsonr/sonr"}; } diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index aeac42056..844cbdbaf 100644 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -3,6 +3,7 @@ set -e GO_MOD_PACKAGE="github.com/onsonr/sonr" +ROOT_DIR=$(git rev-parse --show-toplevel) echo "Generating gogo proto code" cd proto @@ -28,7 +29,7 @@ rm -rf github.com # Copy files over for dep injection rm -rf api && mkdir api -custom_modules=$(find . -name 'module' -type d -not -path "./proto/*") +custom_modules=$(find . -name 'module' -type d -not -path "./proto/*" -not -path "./.cache/*") # get the 1 up directory (so ./cosmos/mint/module becomes ./cosmos/mint) # remove the relative path starter from base namespaces. so ./cosmos/mint becomes cosmos/mint @@ -48,3 +49,19 @@ for module in $base_namespace; do rm -rf $module done + +cd $ROOT_DIR + +echo "Generating third-party proto code" +cd third_party/proto +buf generate + +echo "Copying generated proto code" +cd $ROOT_DIR/github.com/onsonr/sonr/pkg + +cp -r hway/types/* $ROOT_DIR/pkg/hway/types +cp -r common/types/* $ROOT_DIR/pkg/common/types +cp -r motr/types/* $ROOT_DIR/pkg/motr/types + +echo "Cleaning up" +rm -rf $ROOT_DIR/github.com diff --git a/pkl/README.md b/third_party/pkl/README.md similarity index 100% rename from pkl/README.md rename to third_party/pkl/README.md diff --git a/pkl/DWN.pkl b/third_party/pkl/src/sonr.configs.v1/DWN.pkl similarity index 90% rename from pkl/DWN.pkl rename to third_party/pkl/src/sonr.configs.v1/DWN.pkl index 05fc73f79..546b7da85 100644 --- a/pkl/DWN.pkl +++ b/third_party/pkl/src/sonr.configs.v1/DWN.pkl @@ -1,6 +1,6 @@ -@go.Package { name = "github.com/onsonr/sonr/internal/dwn/gen" } +@go.Package { name = "github.com/onsonr/sonr/pkg/motr/config" } -module dwngen +module dwn import "package://pkg.pkl-lang.org/pkl-go/pkl.golang@0.5.0#/go.pkl" diff --git a/pkl/ORM.pkl b/third_party/pkl/src/sonr.models.v1/ORM.pkl similarity index 98% rename from pkl/ORM.pkl rename to third_party/pkl/src/sonr.models.v1/ORM.pkl index 4847f7cac..c074e3619 100644 --- a/pkl/ORM.pkl +++ b/third_party/pkl/src/sonr.models.v1/ORM.pkl @@ -1,4 +1,4 @@ -@go.Package { name = "github.com/onsonr/sonr/internal/orm" } +@go.Package { name = "github.com/onsonr/sonr/pkg/motr/types/orm" } module orm diff --git a/third_party/proto/README.md b/third_party/proto/README.md new file mode 100644 index 000000000..a8b7e3ffd --- /dev/null +++ b/third_party/proto/README.md @@ -0,0 +1,19 @@ +# Sonr Third Party Protobuf + +## Overview + +This directory contains the protobuf definitions for packages that are not part of the Sonr blockchain. + +## Directory Structure + +### `hway` + +The `hway` directory contains the protobuf definitions for the Highway gateway. + +### `ipfs` + +The `ipfs` directory contains the protobuf definitions for the IPFS Network. + +### `motr` + +The `motr` directory contains the protobuf definitions for the Motr client. diff --git a/third_party/proto/buf.gen.yaml b/third_party/proto/buf.gen.yaml new file mode 100644 index 000000000..85f837e44 --- /dev/null +++ b/third_party/proto/buf.gen.yaml @@ -0,0 +1,7 @@ +version: v1 +plugins: + - name: go + out: ../.. + - name: grpc-gateway + out: ../.. + opt: logtostderr=true,allow_colon_final_segments=true diff --git a/third_party/proto/buf.lock b/third_party/proto/buf.lock new file mode 100644 index 000000000..fdb5ceebd --- /dev/null +++ b/third_party/proto/buf.lock @@ -0,0 +1,38 @@ +# Generated by buf. DO NOT EDIT. +version: v1 +deps: + - remote: buf.build + owner: cosmos + repository: cosmos-proto + commit: 04467658e59e44bbb22fe568206e1f70 + digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466 + - remote: buf.build + owner: cosmos + repository: cosmos-sdk + commit: 05419252bcc241ea8023acf1ed4cadc5 + digest: shake256:1e54a48c19a8b59d35e0a7efa76402939f515f2d8005df099856f24c37c20a52800308f025abb8cffcd014d437b49707388aaca4865d9d063d8f25d5d4eb77d5 + - remote: buf.build + owner: cosmos + repository: gogo-proto + commit: 88ef6483f90f478fb938c37dde52ece3 + digest: shake256:89c45df2aa11e0cff97b0d695436713db3d993d76792e9f8dc1ae90e6ab9a9bec55503d48ceedd6b86069ab07d3041b32001b2bfe0227fa725dd515ff381e5ba + - remote: buf.build + owner: googleapis + repository: googleapis + commit: c0913f24652a4cfc95f77d97443a5005 + digest: shake256:0ef3248c6235d420fe61f373154adcde6b94e3297f82472b1d8d8c3747240b61b4a10405e2a6f8ac1c98816ac6e690ea7871024aa5ae0e035cd540214667ceed + - remote: buf.build + owner: onsonr + repository: sonr + commit: e2a05b1a59154da6be3fe148cf01a375 + digest: shake256:0714d88978fe9a1d7b438b13ee1e95aeaef24c7f3667957da60b9a9d8f2ad55f40c2fb84409e21d47738969bff02fa16682340449653508a2ce6196ac2aec36b + - remote: buf.build + owner: protocolbuffers + repository: wellknowntypes + commit: 657250e6a39648cbb169d079a60bd9ba + digest: shake256:00de25001b8dd2e29d85fc4bcc3ede7aed886d76d67f5e0f7a9b320b90f871d3eb73507d50818d823a0512f3f8db77a11c043685528403e31ff3fef18323a9fb + - remote: buf.build + owner: tendermint + repository: tendermint + commit: 33ed361a90514289beabf3189e1d7665 + digest: shake256:038267e06294714fd883610626554b04a127b576b4e253befb4206cb72d5d3c1eeccacd4b9ec8e3fb891f7c14e1cb0f770c077d2989638995b0a61c85afedb1d diff --git a/third_party/proto/buf.yaml b/third_party/proto/buf.yaml new file mode 100644 index 000000000..5015909eb --- /dev/null +++ b/third_party/proto/buf.yaml @@ -0,0 +1,15 @@ +version: v1 +name: buf.build/onsonr/thirdparty +deps: + - buf.build/onsonr/sonr +lint: + use: + - DEFAULT + - COMMENTS + - FILE_LOWER_SNAKE_CASE + except: + - UNARY_RPC + - COMMENT_FIELD + - SERVICE_SUFFIX + - PACKAGE_VERSION_SUFFIX + - RPC_REQUEST_STANDARD_NAME diff --git a/third_party/proto/common/v1/ipfs.proto b/third_party/proto/common/v1/ipfs.proto new file mode 100644 index 000000000..65ec027a2 --- /dev/null +++ b/third_party/proto/common/v1/ipfs.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +package common.v1; + +option go_package = "github.com/onsonr/sonr/pkg/common/types;commonv1"; diff --git a/third_party/proto/common/v1/keys.proto b/third_party/proto/common/v1/keys.proto new file mode 100644 index 000000000..2791c656d --- /dev/null +++ b/third_party/proto/common/v1/keys.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package common.v1; + +option go_package = "github.com/onsonr/sonr/pkg/common/types;commonv1"; + +// PubKey defines a public key for a did +message PubKey { + string role = 1; + string key_type = 2; + RawKey raw_key = 3; + JSONWebKey jwk = 4; +} + +// JWK represents a JSON Web Key +message JSONWebKey { + string kty = 1; // Key Type + string crv = 2; // Curve (for EC and OKP keys) + string x = 3; // X coordinate (for EC and OKP keys) + string y = 4; // Y coordinate (for EC keys) + string n = 5; // Modulus (for RSA keys) + string e = 6; // Exponent (for RSA keys) +} + +message RawKey { + string algorithm = 1; + string encoding = 2; + string curve = 3; + bytes key = 4; +} diff --git a/third_party/proto/common/v1/uri.proto b/third_party/proto/common/v1/uri.proto new file mode 100644 index 000000000..365a0e4d3 --- /dev/null +++ b/third_party/proto/common/v1/uri.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package common.v1; + +option go_package = "github.com/onsonr/sonr/pkg/common/types;commonv1"; + +message URI { + enum URIProtocol { + HTTPS = 0; + IPFS = 1; + IPNS = 2; + DID = 3; + } + URIProtocol protocol = 1; + string value = 2; +} diff --git a/third_party/proto/hway/v1/api.proto b/third_party/proto/hway/v1/api.proto new file mode 100644 index 000000000..b473407ac --- /dev/null +++ b/third_party/proto/hway/v1/api.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package hway.v1; + +option go_package = "github.com/onsonr/sonr/pkg/hway/types"; + +service Highway { + rpc GetJWKS(GetJWKSRequest) returns (GetJWKSResponse); + rpc GetToken(GetTokenRequest) returns (GetTokenResponse); + rpc GrantAuthorization(GrantAuthorizationRequest) returns (GrantAuthorizationResponse); +} + +message GetJWKSRequest {} + +message GetJWKSResponse { + string jwks = 1; +} + +message GetTokenRequest { + string subject = 1; + string origin = 2; + string key = 3; + string asset = 4; +} + +message GetTokenResponse { + string token = 1; +} + +message GrantAuthorizationRequest { + string subject = 1; + string origin = 2; + string key = 3; + string asset = 4; + string assertion = 5; +} + +message GrantAuthorizationResponse { + string token = 1; +} diff --git a/third_party/proto/hway/v1/client.proto b/third_party/proto/hway/v1/client.proto new file mode 100644 index 000000000..a77ad48ef --- /dev/null +++ b/third_party/proto/hway/v1/client.proto @@ -0,0 +1,3 @@ +package hway.v1; + +option go_package = "github.com/onsonr/sonr/pkg/hway/types"; diff --git a/third_party/proto/motr/v1/api.proto b/third_party/proto/motr/v1/api.proto new file mode 100644 index 000000000..e0606f00c --- /dev/null +++ b/third_party/proto/motr/v1/api.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package motr.v1; + +option go_package = "github.com/onsonr/sonr/pkg/motr/types"; + +service Motr { + rpc Pin(PinRequest) returns (PinResponse); + rpc Unpin(UnpinRequest) returns (UnpinResponse); +} + +message PinRequest { + string cid = 1; +} + +message PinResponse { + bool success = 1; +} + +message UnpinRequest { + string cid = 1; +} + +message UnpinResponse { + bool success = 1; +} diff --git a/x/did/types/controller.go b/x/did/controller/base.go similarity index 63% rename from x/did/types/controller.go rename to x/did/controller/base.go index a3e0d4dfc..43beea8bb 100644 --- a/x/did/types/controller.go +++ b/x/did/controller/base.go @@ -1,20 +1,20 @@ -package types +package controller import ( "github.com/onsonr/crypto/mpc" - sdk "github.com/cosmos/cosmos-sdk/types" - didv1 "github.com/onsonr/sonr/api/did/v1" + commonv1 "github.com/onsonr/sonr/pkg/common/types" + "github.com/onsonr/sonr/x/did/types" ) type ControllerI interface { ChainID() string - GetPubKey() *didv1.PubKey + GetPubKey() *commonv1.PubKey SonrAddress() string RawPublicKey() []byte } -func NewController(shares []mpc.Share) (ControllerI, error) { +func New(shares []mpc.Share) (ControllerI, error) { var ( valKs = shares[0] userKs = shares[1] @@ -23,7 +23,7 @@ func NewController(shares []mpc.Share) (ControllerI, error) { if err != nil { return nil, err } - sonrAddr, err := ComputeSonrAddress(pb) + sonrAddr, err := types.ComputeSonrAddr(pb) if err != nil { return nil, err } @@ -36,14 +36,6 @@ func NewController(shares []mpc.Share) (ControllerI, error) { }, nil } -func LoadControllerFromTableEntry(ctx sdk.Context, entry *didv1.Controller) (ControllerI, error) { - return &controller{ - address: entry.Did, - chainID: ctx.ChainID(), - publicKey: entry.PublicKey.RawKey.Key, - }, nil -} - type controller struct { userKs mpc.Share valKs mpc.Share @@ -57,10 +49,10 @@ func (c *controller) ChainID() string { return c.chainID } -func (c *controller) GetPubKey() *didv1.PubKey { - return &didv1.PubKey{ +func (c *controller) GetPubKey() *commonv1.PubKey { + return &commonv1.PubKey{ KeyType: "ecdsa", - RawKey: &didv1.RawKey{ + RawKey: &commonv1.RawKey{ Algorithm: "secp256k1", Key: c.publicKey, }, diff --git a/x/did/controller/signer/actor.go b/x/did/controller/signer/actor.go new file mode 100644 index 000000000..f158c30fa --- /dev/null +++ b/x/did/controller/signer/actor.go @@ -0,0 +1 @@ +package signer diff --git a/x/did/controller/signer/context.go b/x/did/controller/signer/context.go new file mode 100644 index 000000000..f158c30fa --- /dev/null +++ b/x/did/controller/signer/context.go @@ -0,0 +1 @@ +package signer diff --git a/x/did/types/mpc/signer.go b/x/did/controller/signer/signer.go similarity index 97% rename from x/did/types/mpc/signer.go rename to x/did/controller/signer/signer.go index ad54e9c3b..5db3a24c7 100644 --- a/x/did/types/mpc/signer.go +++ b/x/did/controller/signer/signer.go @@ -1,4 +1,4 @@ -package mpc +package signer import ( "context" diff --git a/x/did/controller/table.go b/x/did/controller/table.go new file mode 100644 index 000000000..62ae0cfe6 --- /dev/null +++ b/x/did/controller/table.go @@ -0,0 +1,20 @@ +package controller + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common/hexutil" + + didv1 "github.com/onsonr/sonr/api/did/v1" +) + +func LoadFromTableEntry(ctx sdk.Context, entry *didv1.Controller) (ControllerI, error) { + k, err := hexutil.Decode(entry.PublicKeyHex) + if err != nil { + return nil, err + } + return &controller{ + address: entry.Did, + chainID: ctx.ChainID(), + publicKey: k, + }, nil +} diff --git a/x/did/controller/wallet/pubkey.go b/x/did/controller/wallet/pubkey.go new file mode 100644 index 000000000..509738b9a --- /dev/null +++ b/x/did/controller/wallet/pubkey.go @@ -0,0 +1,140 @@ +package wallet + +import ( + "bytes" + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/crypto/types" + "google.golang.org/protobuf/proto" + + commonv1 "github.com/onsonr/sonr/pkg/common/types" +) + +type PubKeyI interface { + GetRole() string + GetKeyType() string + GetRawKey() *commonv1.RawKey + GetJwk() *commonv1.JSONWebKey +} + +// PubKey defines a generic pubkey. +type PublicKey interface { + VerifySignature(msg, sig []byte) bool +} + +type PubKeyG[T any] interface { + *T + PublicKey +} + +type pubKeyImpl struct { + decode func(b []byte) (PublicKey, error) + validate func(key PublicKey) error +} + +// func WithSecp256K1PubKey() Option { +// return WithPubKeyWithValidationFunc(func(pt *secp256k1.PubKey) error { +// _, err := dcrd_secp256k1.ParsePubKey(pt.Key) +// return err +// }) +// } +// +// func WithPubKey[T any, PT PubKeyG[T]]() Option { +// return WithPubKeyWithValidationFunc[T, PT](func(_ PT) error { +// return nil +// }) +// } +// +// func WithPubKeyWithValidationFunc[T any, PT PubKeyG[T]](validateFn func(PT) error) Option { +// pkImpl := pubKeyImpl{ +// decode: func(b []byte) (PublicKey, error) { +// key := PT(new(T)) +// err := gogoproto.Unmarshal(b, key) +// if err != nil { +// return nil, err +// } +// return key, nil +// }, +// validate: func(k PublicKey) error { +// concrete, ok := k.(PT) +// if !ok { +// return fmt.Errorf( +// "invalid pubkey type passed for validation, wanted: %T, got: %T", +// concrete, +// k, +// ) +// } +// return validateFn(concrete) +// }, +// } +// return func(a *Account) { +// a.supportedPubKeys[gogoproto.MessageName(PT(new(T)))] = pkImpl +// } +// } +func nameFromTypeURL(url string) string { + name := url + if i := strings.LastIndexByte(url, '/'); i >= 0 { + name = name[i+len("/"):] + } + return name +} + +// CustomPubKey represents a custom secp256k1 public key. +type CustomPubKey struct { + proto.Message + + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` +} + +// NewCustomPubKeyFromRawBytes creates a new CustomPubKey from raw bytes. +func NewCustomPubKeyFromRawBytes(key []byte) (*CustomPubKey, error) { + // Validate the key length and format + if len(key) != 33 { + return nil, fmt.Errorf("invalid key length; expected 33 bytes, got %d", len(key)) + } + if key[0] != 0x02 && key[0] != 0x03 { + return nil, fmt.Errorf("invalid key format; expected 0x02 or 0x03 as the first byte, got 0x%02x", key[0]) + } + + return &CustomPubKey{Key: key}, nil +} + +// Bytes returns the byte representation of the public key. +func (pk *CustomPubKey) Bytes() []byte { + return pk.Key +} + +// Equals checks if two public keys are equal. +func (pk *CustomPubKey) Equals(other sdk.PubKey) bool { + return bytes.EqualFold(pk.Bytes(), other.Bytes()) +} + +// Type returns the type of the public key. +func (pk *CustomPubKey) Type() string { + return "custom-secp256k1" +} + +// Marshal implements the proto.Message interface. +func (pk *CustomPubKey) Marshal() ([]byte, error) { + return proto.Marshal(pk) +} + +// Unmarshal implements the proto.Message interface. +func (pk *CustomPubKey) Unmarshal(data []byte) error { + return proto.Unmarshal(data, pk) +} + +// Address returns the address derived from the public key. +func (pk *CustomPubKey) Address() []byte { + // Implement address derivation logic here + // For simplicity, this example uses a placeholder + return []byte("derived-address") +} + +// VerifySignature verifies a signature using the public key. +func (pk *CustomPubKey) VerifySignature(msg []byte, sig []byte) bool { + // Implement signature verification logic here + // For simplicity, this example uses a placeholder + return true +} diff --git a/x/did/controller/wallet/txns.go b/x/did/controller/wallet/txns.go new file mode 100644 index 000000000..23a750732 --- /dev/null +++ b/x/did/controller/wallet/txns.go @@ -0,0 +1 @@ +package wallet diff --git a/x/did/controller/wallet/wallet.go b/x/did/controller/wallet/wallet.go new file mode 100644 index 000000000..23a750732 --- /dev/null +++ b/x/did/controller/wallet/wallet.go @@ -0,0 +1 @@ +package wallet diff --git a/x/did/keeper/controller.go b/x/did/keeper/controller.go deleted file mode 100644 index fa792fbde..000000000 --- a/x/did/keeper/controller.go +++ /dev/null @@ -1,31 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/onsonr/crypto/mpc" - "github.com/onsonr/sonr/x/did/types" -) - -func (k Keeper) NewController(ctx sdk.Context) (types.ControllerI, error) { - shares, err := mpc.GenerateKeyshares() - if err != nil { - return nil, err - } - controller, err := types.NewController(shares) - if err != nil { - return nil, err - } - return controller, nil -} - -func (k Keeper) ResolveController(ctx sdk.Context, did string) (types.ControllerI, error) { - ct, err := k.OrmDB.ControllerTable().GetByDid(ctx, did) - if err != nil { - return nil, err - } - c, err := types.LoadControllerFromTableEntry(ctx, ct) - if err != nil { - return nil, err - } - return c, nil -} diff --git a/x/did/keeper/genesis.go b/x/did/keeper/genesis.go index 74ba610c4..1292523b6 100644 --- a/x/did/keeper/genesis.go +++ b/x/did/keeper/genesis.go @@ -4,11 +4,37 @@ import ( "context" "cosmossdk.io/log" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/onsonr/crypto/mpc" + + "github.com/onsonr/sonr/x/did/controller" "github.com/onsonr/sonr/x/did/types" ) +func (k Keeper) NewController(ctx sdk.Context) (controller.ControllerI, error) { + shares, err := mpc.GenerateKeyshares() + if err != nil { + return nil, err + } + controller, err := controller.New(shares) + if err != nil { + return nil, err + } + return controller, nil +} + +func (k Keeper) ResolveController(ctx sdk.Context, did string) (controller.ControllerI, error) { + ct, err := k.OrmDB.ControllerTable().GetByDid(ctx, did) + if err != nil { + return nil, err + } + c, err := controller.LoadFromTableEntry(ctx, ct) + if err != nil { + return nil, err + } + return c, nil +} + // Logger returns the logger func (k Keeper) Logger() log.Logger { return k.logger diff --git a/x/did/keeper/issuer.go b/x/did/keeper/issuer.go deleted file mode 100644 index ab8d5136e..000000000 --- a/x/did/keeper/issuer.go +++ /dev/null @@ -1,59 +0,0 @@ -package keeper - -import ( - "crypto/sha256" - "fmt" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - didtypes "github.com/onsonr/sonr/x/did/types" - "gopkg.in/macaroon.v2" -) - -var fourYears = time.Hour * 24 * 365 * 4 - -// IssueAdminMacaroon creates a macaroon with the specified parameters. -func (k Keeper) IssueAdminMacaroon(sdkctx sdk.Context, controller didtypes.ControllerI) (*macaroon.Macaroon, error) { - // Derive the root key by hashing the shared MPC public key - rootKey := sha256.Sum256([]byte(controller.RawPublicKey())) - // Create the macaroon - m, err := macaroon.New(rootKey[:], []byte(controller.SonrAddress()), controller.ChainID(), macaroon.LatestVersion) - if err != nil { - return nil, err - } - - // Add the block expiry caveat - caveat := fmt.Sprintf("block-expiry=%d", calculateBlockExpiry(sdkctx, fourYears)) - err = m.AddFirstPartyCaveat([]byte(caveat)) - if err != nil { - return nil, err - } - - return m, nil -} - -// IssueServiceMacaroon creates a macaroon with the specified parameters. -func (k Keeper) IssueServiceMacaroon(sdkctx sdk.Context, sharedMPCPubKey, location, id string, blockExpiry uint64) (*macaroon.Macaroon, error) { - // Derive the root key by hashing the shared MPC public key - rootKey := sha256.Sum256([]byte(sharedMPCPubKey)) - // Create the macaroon - m, err := macaroon.New(rootKey[:], []byte(id), location, macaroon.LatestVersion) - if err != nil { - return nil, err - } - - // Add the block expiry caveat - caveat := fmt.Sprintf("block-expiry=%d", blockExpiry) - err = m.AddFirstPartyCaveat([]byte(caveat)) - if err != nil { - return nil, err - } - - return m, nil -} - -func calculateBlockExpiry(sdkctx sdk.Context, duration time.Duration) uint64 { - blockTime := sdkctx.BlockTime() - avgBlockTime := float64(blockTime.Sub(blockTime).Seconds()) - return uint64(duration.Seconds() / avgBlockTime) -} diff --git a/x/did/types/account.go b/x/did/types/account.go deleted file mode 100644 index 16be5f447..000000000 --- a/x/did/types/account.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -type SonrAccount struct { - ID string - Name string - Address string - PublicKey string - ChainCode string - Index string - Controller string - CreatedAt string -} diff --git a/x/did/types/accstd/exports.go b/x/did/types/accstd/exports.go new file mode 100644 index 000000000..320c72c27 --- /dev/null +++ b/x/did/types/accstd/exports.go @@ -0,0 +1,166 @@ +// Package accountstd exports the types and functions that are used by developers to implement smart accounts. +package accstd + +import ( + "bytes" + "context" + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + + "github.com/onsonr/sonr/pkg/core/transaction" + "github.com/onsonr/sonr/x/did/types/accstd/internal/accounts" +) + +var ( + accountsModuleAddress = address.Module("accounts") + ErrInvalidType = errors.New("invalid type") +) + +// Interface is the exported interface of an Account. +type Interface = accounts.Account + +// ExecuteBuilder is the exported type of ExecuteBuilder. +type ExecuteBuilder = accounts.ExecuteBuilder + +// QueryBuilder is the exported type of QueryBuilder. +type QueryBuilder = accounts.QueryBuilder + +// InitBuilder is the exported type of InitBuilder. +type InitBuilder = accounts.InitBuilder + +// AccountCreatorFunc is the exported type of AccountCreatorFunc. +type AccountCreatorFunc = accounts.AccountCreatorFunc + +func DIAccount[A Interface](name string, constructor func(deps Dependencies) (A, error)) DepinjectAccount { + return DepinjectAccount{MakeAccount: AddAccount(name, constructor)} +} + +type DepinjectAccount struct { + MakeAccount AccountCreatorFunc +} + +func (DepinjectAccount) IsManyPerContainerType() {} + +// Dependencies is the exported type of Dependencies. +type Dependencies = accounts.Dependencies + +func RegisterExecuteHandler[ + Req any, ProtoReq accounts.ProtoMsgG[Req], Resp any, ProtoResp accounts.ProtoMsgG[Resp], +](router *ExecuteBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +) { + accounts.RegisterExecuteHandler(router, handler) +} + +// RegisterQueryHandler registers a query handler for a smart account that uses protobuf. +func RegisterQueryHandler[ + Req any, ProtoReq accounts.ProtoMsgG[Req], Resp any, ProtoResp accounts.ProtoMsgG[Resp], +](router *QueryBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +) { + accounts.RegisterQueryHandler(router, handler) +} + +// RegisterInitHandler registers an initialisation handler for a smart account that uses protobuf. +func RegisterInitHandler[ + Req any, ProtoReq accounts.ProtoMsgG[Req], Resp any, ProtoResp accounts.ProtoMsgG[Resp], +](router *InitBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +) { + accounts.RegisterInitHandler(router, handler) +} + +// AddAccount is a helper function to add a smart account to the list of smart accounts. +func AddAccount[A Interface](name string, constructor func(deps Dependencies) (A, error)) AccountCreatorFunc { + return func(deps accounts.Dependencies) (string, accounts.Account, error) { + acc, err := constructor(deps) + return name, acc, err + } +} + +// Whoami returns the address of the account being invoked. +func Whoami(ctx context.Context) []byte { + return accounts.Whoami(ctx) +} + +// Sender returns the sender of the execution request. +func Sender(ctx context.Context) []byte { + return accounts.Sender(ctx) +} + +// HasSender checks if the execution context was sent from the provided sender +func HasSender(ctx context.Context, wantSender []byte) bool { + return bytes.Equal(Sender(ctx), wantSender) +} + +// SenderIsSelf checks if the sender of the request is the account itself. +func SenderIsSelf(ctx context.Context) bool { return HasSender(ctx, Whoami(ctx)) } + +// SenderIsAccountsModule returns true if the sender of the execution request is the accounts module. +func SenderIsAccountsModule(ctx context.Context) bool { + return bytes.Equal(Sender(ctx), accountsModuleAddress) +} + +// Funds returns if any funds were sent during the execute or init request. In queries this +// returns nil. +func Funds(ctx context.Context) sdk.Coins { return accounts.Funds(ctx) } + +func ExecModule[MsgResp, Msg transaction.Msg](ctx context.Context, msg Msg) (resp MsgResp, err error) { + untyped, err := accounts.ExecModule(ctx, msg) + if err != nil { + return resp, err + } + return assertOrErr[MsgResp](untyped) +} + +// QueryModule can be used by an account to execute a module query. +func QueryModule[Resp, Req transaction.Msg](ctx context.Context, req Req) (resp Resp, err error) { + untyped, err := accounts.QueryModule(ctx, req) + if err != nil { + return resp, err + } + return assertOrErr[Resp](untyped) +} + +// UnpackAny unpacks a protobuf Any message generically. +func UnpackAny[Msg any, ProtoMsg accounts.ProtoMsgG[Msg]](any *accounts.Any) (*Msg, error) { + return accounts.UnpackAny[Msg, ProtoMsg](any) +} + +// PackAny packs a protobuf Any message generically. +func PackAny(msg transaction.Msg) (*accounts.Any, error) { + return accounts.PackAny(msg) +} + +// ExecModuleAnys can be used to execute a list of messages towards a module +// when those messages are packed in Any messages. The function returns a list +// of responses packed in Any messages. +func ExecModuleAnys(ctx context.Context, msgs []*accounts.Any) ([]*accounts.Any, error) { + responses := make([]*accounts.Any, len(msgs)) + for i, msg := range msgs { + concreteMessage, err := accounts.UnpackAnyRaw(msg) + if err != nil { + return nil, fmt.Errorf("error unpacking message %d: %w", i, err) + } + resp, err := accounts.ExecModule(ctx, concreteMessage) + if err != nil { + return nil, fmt.Errorf("error executing message %d: %w", i, err) + } + // pack again + respAnyPB, err := accounts.PackAny(resp) + if err != nil { + return nil, fmt.Errorf("error packing response %d: %w", i, err) + } + responses[i] = respAnyPB + } + return responses, nil +} + +// asserts the given any to the provided generic, returns ErrInvalidType if it can't. +func assertOrErr[T any](r any) (concrete T, err error) { + concrete, ok := r.(T) + if !ok { + return concrete, ErrInvalidType + } + return concrete, nil +} diff --git a/x/did/types/accstd/internal/accounts/api_builder.go b/x/did/types/accstd/internal/accounts/api_builder.go new file mode 100644 index 000000000..f7fcf66f6 --- /dev/null +++ b/x/did/types/accstd/internal/accounts/api_builder.go @@ -0,0 +1,112 @@ +package accounts + +import ( + "context" + "errors" + "fmt" + + "github.com/onsonr/sonr/pkg/core/transaction" +) + +var ( + errNoInitHandler = errors.New("no init handler") + errNoExecuteHandler = errors.New("account does not accept messages") + errInvalidMessage = errors.New("invalid message") +) + +// NewInitBuilder creates a new InitBuilder instance. +func NewInitBuilder() *InitBuilder { + return &InitBuilder{} +} + +// InitBuilder defines a smart account's initialisation handler builder. +type InitBuilder struct { + // handler is the handler function that will be called when the smart account is initialized. + // Although the function here is defined to take an any, the smart account will work + // with a typed version of it. + handler func(ctx context.Context, initRequest transaction.Msg) (initResponse transaction.Msg, err error) + + // schema is the schema of the message that will be passed to the handler function. + schema HandlerSchema +} + +// makeHandler returns the handler function that will be called when the smart account is initialized. +// It returns an error if no handler was registered. +func (i *InitBuilder) makeHandler() (func(ctx context.Context, initRequest transaction.Msg) (initResponse transaction.Msg, err error), error) { + if i.handler == nil { + return nil, errNoInitHandler + } + return i.handler, nil +} + +// NewExecuteBuilder creates a new ExecuteBuilder instance. +func NewExecuteBuilder() *ExecuteBuilder { + return &ExecuteBuilder{ + handlers: make(map[string]func(ctx context.Context, executeRequest transaction.Msg) (executeResponse transaction.Msg, err error)), + handlersSchema: make(map[string]HandlerSchema), + } +} + +// ExecuteBuilder defines a smart account's execution router, it will be used to map an execution message +// to a handler function for a specific account. +type ExecuteBuilder struct { + // handlers is a map of handler functions that will be called when the smart account is executed. + handlers map[string]func(ctx context.Context, executeRequest transaction.Msg) (executeResponse transaction.Msg, err error) + + // handlersSchema is a map of schemas for the messages that will be passed to the handler functions + // and the messages that will be returned by the handler functions. + handlersSchema map[string]HandlerSchema + + // err is the error that occurred before building the handler function. + err error +} + +func (r *ExecuteBuilder) makeHandler() (func(ctx context.Context, executeRequest transaction.Msg) (executeResponse transaction.Msg, err error), error) { + // if no handler is registered it's fine, it means the account will not be accepting execution or query messages. + if len(r.handlers) == 0 { + return func(ctx context.Context, _ transaction.Msg) (_ transaction.Msg, err error) { + return nil, errNoExecuteHandler + }, nil + } + + if r.err != nil { + return nil, r.err + } + + // build the real execution handler + return func(ctx context.Context, executeRequest transaction.Msg) (executeResponse transaction.Msg, err error) { + messageName := MessageName(executeRequest) + handler, ok := r.handlers[messageName] + if !ok { + return nil, fmt.Errorf("%w: no handler for message %s", errInvalidMessage, messageName) + } + return handler(ctx, executeRequest) + }, nil +} + +// NewQueryBuilder creates a new QueryBuilder instance. +func NewQueryBuilder() *QueryBuilder { + return &QueryBuilder{ + er: NewExecuteBuilder(), + } +} + +// QueryBuilder defines a smart account's query router, it will be used to map a query message +// to a handler function for a specific account. +type QueryBuilder struct { + // er is the ExecuteBuilder, since there's no difference between the execution and query handlers API. + er *ExecuteBuilder +} + +func (r *QueryBuilder) makeHandler() (func(ctx context.Context, queryRequest transaction.Msg) (queryResponse transaction.Msg, err error), error) { + return r.er.makeHandler() +} + +// IsRoutingError returns true if the error is a routing error, +// which typically occurs when a message cannot be matched to a handler. +func IsRoutingError(err error) bool { + if err == nil { + return false + } + return errors.Is(err, errInvalidMessage) +} diff --git a/x/did/types/accstd/internal/accounts/context.go b/x/did/types/accstd/internal/accounts/context.go new file mode 100644 index 000000000..9cc72f17a --- /dev/null +++ b/x/did/types/accstd/internal/accounts/context.go @@ -0,0 +1,124 @@ +package accounts + +import ( + "context" + "encoding/binary" + + "cosmossdk.io/collections" + "cosmossdk.io/core/store" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/onsonr/sonr/pkg/core/transaction" + "github.com/onsonr/sonr/x/did/types/accstd/internal/prefixstore" +) + +var AccountStatePrefix = collections.NewPrefix(255) + +type ( + ModuleExecFunc = func(ctx context.Context, sender []byte, msg transaction.Msg) (transaction.Msg, error) + ModuleQueryFunc = func(ctx context.Context, queryReq transaction.Msg) (transaction.Msg, error) +) + +type contextKey struct{} + +type contextValue struct { + store store.KVStore // store is the prefixed store for the account. + sender []byte // sender is the address of the entity invoking the account action. + whoami []byte // whoami is the address of the account being invoked. + funds sdk.Coins // funds reports the coins sent alongside the request. + parentContext context.Context // parentContext that was used to build the account context. + moduleExec ModuleExecFunc // moduleExec is a function that executes a module message, when the resp type is unknown. + moduleQuery ModuleQueryFunc // moduleQuery is a function that queries a module. +} + +func addCtx(ctx context.Context, value contextValue) context.Context { + return context.WithValue(ctx, contextKey{}, value) +} + +func getCtx(ctx context.Context) contextValue { + return ctx.Value(contextKey{}).(contextValue) +} + +// MakeAccountContext creates a new account execution context given: +// storeSvc: which fetches the x/accounts module store. +// accountAddr: the address of the account being invoked, which is used to give the +// account a prefixed storage. +// sender: the address of entity invoking the account action. +// moduleExec: a function that executes a module message. +// moduleQuery: a function that queries a module. +func MakeAccountContext( + ctx context.Context, + storeSvc store.KVStoreService, + accNumber uint64, + accountAddr []byte, + sender []byte, + funds sdk.Coins, + moduleExec ModuleExecFunc, + moduleQuery ModuleQueryFunc, +) context.Context { + return addCtx(ctx, contextValue{ + store: makeAccountStore(ctx, storeSvc, accNumber), + sender: sender, + whoami: accountAddr, + funds: funds, + parentContext: ctx, + moduleExec: moduleExec, + moduleQuery: moduleQuery, + }) +} + +func SetSender(ctx context.Context, sender []byte) context.Context { + v := getCtx(ctx) + v.sender = sender + return addCtx(v.parentContext, v) +} + +// makeAccountStore creates the prefixed store for the account. +// It uses the number of the account, this gives constant size +// bytes prefixes for the account state. +func makeAccountStore(ctx context.Context, storeSvc store.KVStoreService, accNum uint64) store.KVStore { + prefix := make([]byte, 8) + binary.BigEndian.PutUint64(prefix, accNum) + return prefixstore.New(storeSvc.OpenKVStore(ctx), append(AccountStatePrefix, prefix...)) +} + +// ExecModule can be used to execute a message towards a module, when the response type is unknown. +func ExecModule(ctx context.Context, msg transaction.Msg) (transaction.Msg, error) { + // get sender + v := getCtx(ctx) + + resp, err := v.moduleExec(v.parentContext, v.whoami, msg) + if err != nil { + return nil, err + } + + return resp, nil +} + +// QueryModule can be used by an account to execute a module query. +func QueryModule(ctx context.Context, req transaction.Msg) (transaction.Msg, error) { + // we do not need to check the sender in a query because it is not a state transition. + // we also unwrap the original context. + v := getCtx(ctx) + resp, err := v.moduleQuery(v.parentContext, req) + if err != nil { + return nil, err + } + return resp, nil +} + +// openKVStore returns the prefixed store for the account given the context. +func openKVStore(ctx context.Context) store.KVStore { return getCtx(ctx).store } + +// Sender returns the address of the entity invoking the account action. +func Sender(ctx context.Context) []byte { + return getCtx(ctx).sender +} + +// Whoami returns the address of the account being invoked. +func Whoami(ctx context.Context) []byte { + return getCtx(ctx).whoami +} + +// Funds returns the funds associated with the execution context. +func Funds(ctx context.Context) sdk.Coins { return getCtx(ctx).funds } diff --git a/x/did/types/accstd/internal/accounts/encoding.go b/x/did/types/accstd/internal/accounts/encoding.go new file mode 100644 index 000000000..aab7cf73e --- /dev/null +++ b/x/did/types/accstd/internal/accounts/encoding.go @@ -0,0 +1,66 @@ +package accounts + +import ( + "fmt" + "reflect" + "strings" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/gogoproto/proto" + + "github.com/onsonr/sonr/pkg/core/transaction" +) + +// ProtoMsgG is a generic interface for protobuf messages. +type ProtoMsgG[T any] interface { + *T + transaction.Msg +} + +type Any = codectypes.Any + +func FindMessageByName(name string) (transaction.Msg, error) { + typ := proto.MessageType(name) + if typ == nil { + return nil, fmt.Errorf("no message type found for %s", name) + } + return reflect.New(typ.Elem()).Interface().(transaction.Msg), nil +} + +func MessageName(msg transaction.Msg) string { + return proto.MessageName(msg) +} + +// PackAny packs a proto message into an anypb.Any. +func PackAny(msg transaction.Msg) (*Any, error) { + return codectypes.NewAnyWithValue(msg) +} + +// UnpackAny unpacks an anypb.Any into a proto message. +func UnpackAny[T any, PT ProtoMsgG[T]](anyPB *Any) (PT, error) { + to := new(T) + return to, UnpackAnyTo(anyPB, PT(to)) +} + +func UnpackAnyTo(anyPB *Any, to transaction.Msg) error { + return proto.Unmarshal(anyPB.Value, to) +} + +func UnpackAnyRaw(anyPB *Any) (proto.Message, error) { + split := strings.Split(anyPB.TypeUrl, "/") + name := split[len(split)-1] + typ := proto.MessageType(name) + if typ == nil { + return nil, fmt.Errorf("no message type found for %s", name) + } + to := reflect.New(typ.Elem()).Interface().(proto.Message) + return to, UnpackAnyTo(anyPB, to) +} + +func Merge(a, b transaction.Msg) { + proto.Merge(a, b) +} + +func Equal(a, b transaction.Msg) bool { + return proto.Equal(a, b) +} diff --git a/x/did/types/accstd/internal/accounts/implementation.go b/x/did/types/accstd/internal/accounts/implementation.go new file mode 100644 index 000000000..f19b3798d --- /dev/null +++ b/x/did/types/accstd/internal/accounts/implementation.go @@ -0,0 +1,157 @@ +package accounts + +import ( + "context" + "fmt" + + "cosmossdk.io/collections" + "cosmossdk.io/core/address" + "github.com/cosmos/cosmos-sdk/codec" + gogoproto "github.com/cosmos/gogoproto/proto" + + "github.com/onsonr/sonr/pkg/core/appmodule" + "github.com/onsonr/sonr/pkg/core/transaction" +) + +// Dependencies are passed to the constructor of a smart account. +type Dependencies struct { + SchemaBuilder *collections.SchemaBuilder + AddressCodec address.Codec + Environment appmodule.Environment + LegacyStateCodec interface { + Marshal(gogoproto.Message) ([]byte, error) + Unmarshal([]byte, gogoproto.Message) error + } +} + +// AccountCreatorFunc is a function that creates an account. +type AccountCreatorFunc = func(deps Dependencies) (string, Account, error) + +// MakeAccountsMap creates a map of account names to account implementations +// from a list of account creator functions. +func MakeAccountsMap( + cdc codec.Codec, + addressCodec address.Codec, + env appmodule.Environment, + accounts []AccountCreatorFunc, +) (map[string]Implementation, error) { + accountsMap := make(map[string]Implementation, len(accounts)) + for _, makeAccount := range accounts { + stateSchemaBuilder := collections.NewSchemaBuilderFromAccessor(openKVStore) + deps := Dependencies{ + SchemaBuilder: stateSchemaBuilder, + AddressCodec: addressCodec, + Environment: env, + LegacyStateCodec: cdc, + } + name, accountInterface, err := makeAccount(deps) + if err != nil { + return nil, fmt.Errorf("failed to create account %s: %w", name, err) + } + if _, ok := accountsMap[name]; ok { + return nil, fmt.Errorf("account %s is already registered", name) + } + impl, err := newImplementation(stateSchemaBuilder, accountInterface) + if err != nil { + return nil, fmt.Errorf("failed to create implementation for account %s: %w", name, err) + } + accountsMap[name] = impl + } + + return accountsMap, nil +} + +// newImplementation creates a new Implementation instance given an Account implementer. +func newImplementation(schemaBuilder *collections.SchemaBuilder, account Account) (Implementation, error) { + // make init handler + ir := NewInitBuilder() + account.RegisterInitHandler(ir) + initHandler, err := ir.makeHandler() + if err != nil { + return Implementation{}, err + } + + // make execute handler + er := NewExecuteBuilder() + account.RegisterExecuteHandlers(er) + executeHandler, err := er.makeHandler() + if err != nil { + return Implementation{}, err + } + + // make query handler + qr := NewQueryBuilder() + account.RegisterQueryHandlers(qr) + queryHandler, err := qr.makeHandler() + if err != nil { + return Implementation{}, err + } + + // build schema + schema, err := schemaBuilder.Build() + if err != nil { + return Implementation{}, err + } + return Implementation{ + Init: initHandler, + Execute: executeHandler, + Query: queryHandler, + CollectionsSchema: schema, + InitHandlerSchema: ir.schema, + QueryHandlersSchema: qr.er.handlersSchema, + ExecuteHandlersSchema: er.handlersSchema, + }, nil +} + +// Implementation wraps an Account implementer in order to provide a concrete +// and non-generic implementation usable by the x/accounts module. +type Implementation struct { + // Init defines the initialisation handler for the smart account. + Init func(ctx context.Context, msg transaction.Msg) (resp transaction.Msg, err error) + // Execute defines the execution handler for the smart account. + Execute func(ctx context.Context, msg transaction.Msg) (resp transaction.Msg, err error) + // Query defines the query handler for the smart account. + Query func(ctx context.Context, msg transaction.Msg) (resp transaction.Msg, err error) + // CollectionsSchema represents the state schema. + CollectionsSchema collections.Schema + // InitHandlerSchema represents the init handler schema. + InitHandlerSchema HandlerSchema + // QueryHandlersSchema is the schema of the query handlers. + QueryHandlersSchema map[string]HandlerSchema + // ExecuteHandlersSchema is the schema of the execute handlers. + ExecuteHandlersSchema map[string]HandlerSchema +} + +// HasExec returns true if the account can execute the given msg. +func (i Implementation) HasExec(m transaction.Msg) bool { + _, ok := i.ExecuteHandlersSchema[MessageName(m)] + return ok +} + +// HasQuery returns true if the account can execute the given request. +func (i Implementation) HasQuery(m transaction.Msg) bool { + _, ok := i.QueryHandlersSchema[MessageName(m)] + return ok +} + +// HasInit returns true if the account uses the provided init message. +func (i Implementation) HasInit(m transaction.Msg) bool { + return i.InitHandlerSchema.RequestSchema.Name == MessageName(m) +} + +// MessageSchema defines the schema of a message. +// A message can also define a state schema. +type MessageSchema struct { + // Name identifies the message name, this must be queryable from some reflection service. + Name string + // New is used to create a new message instance for the schema. + New func() transaction.Msg +} + +// HandlerSchema defines the schema of a handler. +type HandlerSchema struct { + // RequestSchema defines the schema of the request. + RequestSchema MessageSchema + // ResponseSchema defines the schema of the response. + ResponseSchema MessageSchema +} diff --git a/x/did/types/accstd/internal/accounts/interface.go b/x/did/types/accstd/internal/accounts/interface.go new file mode 100644 index 000000000..93d4a48c6 --- /dev/null +++ b/x/did/types/accstd/internal/accounts/interface.go @@ -0,0 +1,17 @@ +package accounts + +// Account defines a smart account interface. +type Account interface { + // RegisterInitHandler allows the smart account to register an initialisation handler, using + // the provided InitBuilder. The handler will be called when the smart account is initialized + // (deployed). + RegisterInitHandler(builder *InitBuilder) + + // RegisterExecuteHandlers allows the smart account to register execution handlers. + // The smart account might also decide to not register any execution handler. + RegisterExecuteHandlers(builder *ExecuteBuilder) + + // RegisterQueryHandlers allows the smart account to register query handlers. The smart account + // might also decide to not register any query handler. + RegisterQueryHandlers(builder *QueryBuilder) +} diff --git a/x/did/types/accstd/internal/accounts/protoaccount.go b/x/did/types/accstd/internal/accounts/protoaccount.go new file mode 100644 index 000000000..be859b4ca --- /dev/null +++ b/x/did/types/accstd/internal/accounts/protoaccount.go @@ -0,0 +1,78 @@ +package accounts + +import ( + "context" + "fmt" + + "google.golang.org/protobuf/proto" + + "github.com/onsonr/sonr/pkg/core/transaction" +) + +// RegisterInitHandler registers an initialisation handler for a smart account that uses protobuf. +func RegisterInitHandler[ + Req any, ProtoReq ProtoMsgG[Req], Resp any, ProtoResp ProtoMsgG[Resp], +](router *InitBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +) { + reqName := MessageName(ProtoReq(new(Req))) + + router.handler = func(ctx context.Context, initRequest transaction.Msg) (initResponse transaction.Msg, err error) { + concrete, ok := initRequest.(ProtoReq) + if !ok { + return nil, fmt.Errorf("%w: wanted %s, got %T", errInvalidMessage, reqName, initRequest) + } + return handler(ctx, concrete) + } + + router.schema = HandlerSchema{ + RequestSchema: *NewProtoMessageSchema[Req, ProtoReq](), + ResponseSchema: *NewProtoMessageSchema[Resp, ProtoResp](), + } +} + +// RegisterExecuteHandler registers an execution handler for a smart account that uses protobuf. +func RegisterExecuteHandler[ + Req any, ProtoReq ProtoMsgG[Req], Resp any, ProtoResp ProtoMsgG[Resp], +](router *ExecuteBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +) { + reqName := MessageName(ProtoReq(new(Req))) + // check if not registered already + if _, ok := router.handlers[reqName]; ok { + router.err = fmt.Errorf("handler already registered for message %s", reqName) + return + } + + router.handlers[reqName] = func(ctx context.Context, executeRequest transaction.Msg) (executeResponse transaction.Msg, err error) { + concrete, ok := executeRequest.(ProtoReq) + if !ok { + return nil, fmt.Errorf("%w: wanted %s, got %T", errInvalidMessage, reqName, executeRequest) + } + return handler(ctx, concrete) + } + + router.handlersSchema[reqName] = HandlerSchema{ + RequestSchema: *NewProtoMessageSchema[Req, ProtoReq](), + ResponseSchema: *NewProtoMessageSchema[Resp, ProtoResp](), + } +} + +// RegisterQueryHandler registers a query handler for a smart account that uses protobuf. +func RegisterQueryHandler[ + Req any, ProtoReq ProtoMsgG[Req], Resp any, ProtoResp ProtoMsgG[Resp], +](router *QueryBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +) { + RegisterExecuteHandler(router.er, handler) +} + +func NewProtoMessageSchema[T any, PT ProtoMsgG[T]]() *MessageSchema { + msg := PT(new(T)) + if _, ok := (interface{}(msg)).(proto.Message); ok { + panic("protov2 messages are not supported") + } + return &MessageSchema{ + Name: MessageName(msg), + New: func() transaction.Msg { + return PT(new(T)) + }, + } +} diff --git a/x/did/types/accstd/internal/prefixstore/prefixstore.go b/x/did/types/accstd/internal/prefixstore/prefixstore.go new file mode 100644 index 000000000..ef84b7070 --- /dev/null +++ b/x/did/types/accstd/internal/prefixstore/prefixstore.go @@ -0,0 +1,223 @@ +// Package prefixstore provides a store that prefixes all keys with a given +// prefix. It is used to isolate storage reads and writes for an account. +// Implementation taken from cosmossdk.io/store/prefix, and adapted to +// the cosmossdk.io/core/store.KVStore interface. +package prefixstore + +import ( + "bytes" + "errors" + + "cosmossdk.io/core/store" +) + +// New creates a new prefix store using the provided bytes prefix. +func New(store store.KVStore, prefix []byte) store.KVStore { + return Store{ + parent: store, + prefix: prefix, + } +} + +var _ store.KVStore = Store{} + +// Store is similar with cometbft/cometbft-db/blob/v1.0.1/prefixdb.go +// both gives access only to the limited subset of the store +// for convenience or safety +type Store struct { + parent store.KVStore + prefix []byte +} + +func cloneAppend(bz, tail []byte) (res []byte) { + res = make([]byte, len(bz)+len(tail)) + copy(res, bz) + copy(res[len(bz):], tail) + return +} + +func (s Store) key(key []byte) (res []byte) { + if key == nil { + panic("nil key on Store") + } + res = cloneAppend(s.prefix, key) + return +} + +// Implements KVStore +func (s Store) Get(key []byte) ([]byte, error) { + return s.parent.Get(s.key(key)) +} + +// Implements KVStore +func (s Store) Has(key []byte) (bool, error) { + return s.parent.Has(s.key(key)) +} + +// Implements KVStore +func (s Store) Set(key, value []byte) error { + return s.parent.Set(s.key(key), value) +} + +// Implements KVStore +func (s Store) Delete(key []byte) error { return s.parent.Delete(s.key(key)) } + +// Implements KVStore +// Check https://github.com/cometbft/cometbft-db/blob/v1.0.1/prefixdb.go#L109 +func (s Store) Iterator(start, end []byte) (store.Iterator, error) { + newstart := cloneAppend(s.prefix, start) + + var newend []byte + if end == nil { + newend = cpIncr(s.prefix) + } else { + newend = cloneAppend(s.prefix, end) + } + + iter, err := s.parent.Iterator(newstart, newend) + if err != nil { + return nil, err + } + + return newPrefixIterator(s.prefix, start, end, iter), nil +} + +// ReverseIterator implements KVStore +// Check https://github.com/cometbft/cometbft-db/blob/v1.0.1/prefixdb.go#L132 +func (s Store) ReverseIterator(start, end []byte) (store.Iterator, error) { + newstart := cloneAppend(s.prefix, start) + + var newend []byte + if end == nil { + newend = cpIncr(s.prefix) + } else { + newend = cloneAppend(s.prefix, end) + } + + iter, err := s.parent.ReverseIterator(newstart, newend) + if err != nil { + return nil, err + } + + return newPrefixIterator(s.prefix, start, end, iter), nil +} + +var _ store.Iterator = (*prefixIterator)(nil) + +type prefixIterator struct { + prefix []byte + start []byte + end []byte + iter store.Iterator + valid bool +} + +func newPrefixIterator(prefix, start, end []byte, parent store.Iterator) *prefixIterator { + return &prefixIterator{ + prefix: prefix, + start: start, + end: end, + iter: parent, + valid: parent.Valid() && bytes.HasPrefix(parent.Key(), prefix), + } +} + +// Implements Iterator +func (pi *prefixIterator) Domain() ([]byte, []byte) { + return pi.start, pi.end +} + +// Implements Iterator +func (pi *prefixIterator) Valid() bool { + return pi.valid && pi.iter.Valid() +} + +// Implements Iterator +func (pi *prefixIterator) Next() { + if !pi.valid { + panic("prefixIterator invalid, cannot call Next()") + } + + if pi.iter.Next(); !pi.iter.Valid() || !bytes.HasPrefix(pi.iter.Key(), pi.prefix) { + // TODO: shouldn't pi be set to nil instead? + pi.valid = false + } +} + +// Implements Iterator +func (pi *prefixIterator) Key() (key []byte) { + if !pi.valid { + panic("prefixIterator invalid, cannot call Key()") + } + + key = pi.iter.Key() + key = stripPrefix(key, pi.prefix) + + return +} + +// Implements Iterator +func (pi *prefixIterator) Value() []byte { + if !pi.valid { + panic("prefixIterator invalid, cannot call Value()") + } + + return pi.iter.Value() +} + +// Implements Iterator +func (pi *prefixIterator) Close() error { + return pi.iter.Close() +} + +// Error returns an error if the prefixIterator is invalid defined by the Valid +// method. +func (pi *prefixIterator) Error() error { + if !pi.Valid() { + return errors.New("invalid prefixIterator") + } + + return nil +} + +// copied from github.com/cometbft/cometbft-db/blob/v1.0.1/prefixdb.go +func stripPrefix(key, prefix []byte) []byte { + if len(key) < len(prefix) || !bytes.Equal(key[:len(prefix)], prefix) { + panic("should not happen") + } + + return key[len(prefix):] +} + +// wrapping types.PrefixEndBytes +func cpIncr(bz []byte) []byte { + return prefixEndBytes(bz) +} + +// prefixEndBytes returns the []byte that would end a +// range query for all []byte with a certain prefix +// Deals with last byte of prefix being FF without overflowing +func prefixEndBytes(prefix []byte) []byte { + if len(prefix) == 0 { + return nil + } + + end := make([]byte, len(prefix)) + copy(end, prefix) + + for { + if end[len(end)-1] != byte(255) { + end[len(end)-1]++ + break + } + + end = end[:len(end)-1] + + if len(end) == 0 { + end = nil + break + } + } + + return end +} diff --git a/x/did/types/address.go b/x/did/types/compute.go similarity index 72% rename from x/did/types/address.go rename to x/did/types/compute.go index faf63d532..8c9b78e1b 100644 --- a/x/did/types/address.go +++ b/x/did/types/compute.go @@ -9,8 +9,8 @@ import ( "golang.org/x/crypto/sha3" ) -// ComputeSonrAddress computes the Sonr address from a public key -func ComputeSonrAddress(pk []byte) (string, error) { +// ComputeSonrAddr computes the Sonr address from a public key +func ComputeSonrAddr(pk []byte) (string, error) { sonrAddr, err := bech32.ConvertAndEncode("idx", pk) if err != nil { return "", err @@ -18,8 +18,8 @@ func ComputeSonrAddress(pk []byte) (string, error) { return sonrAddr, nil } -// ComputeBitcoinAddress computes the Bitcoin address from a public key -func ComputeBitcoinAddress(pk []byte) (string, error) { +// ComputeBitcoinAddr computes the Bitcoin address from a public key +func ComputeBitcoinAddr(pk []byte) (string, error) { btcAddr, err := bech32.ConvertAndEncode("bc", pk) if err != nil { return "", err @@ -27,8 +27,8 @@ func ComputeBitcoinAddress(pk []byte) (string, error) { return btcAddr, nil } -// ComputeEthAddress computes the Ethereum address from a public key -func ComputeEthAddress(pk *ecdsa.PublicKey) string { +// ComputeEthereumAddr computes the Ethereum address from a public key +func ComputeEthereumAddr(pk *ecdsa.PublicKey) string { // Generate Ethereum address address := ethcrypto.PubkeyToAddress(*pk) diff --git a/x/did/types/genesis.pb.go b/x/did/types/genesis.pb.go index efc94527a..fdc02dfc4 100644 --- a/x/did/types/genesis.pb.go +++ b/x/did/types/genesis.pb.go @@ -70,27 +70,29 @@ func (m *GenesisState) GetParams() Params { return Params{} } -// Params defines the set of module parameters. -type Params struct { - // Whitelisted Key Types - AllowedPublicKeys map[string]*KeyInfo `protobuf:"bytes,2,rep,name=allowed_public_keys,json=allowedPublicKeys,proto3" json:"allowed_public_keys,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // ConveyancePreference defines the conveyance preference - ConveyancePreference string `protobuf:"bytes,3,opt,name=conveyance_preference,json=conveyancePreference,proto3" json:"conveyance_preference,omitempty"` - // AttestationFormats defines the attestation formats - AttestationFormats []string `protobuf:"bytes,4,rep,name=attestation_formats,json=attestationFormats,proto3" json:"attestation_formats,omitempty"` +// Document defines a DID document +type Document struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` + Authentication []string `protobuf:"bytes,3,rep,name=authentication,proto3" json:"authentication,omitempty"` + AssertionMethod []string `protobuf:"bytes,4,rep,name=assertion_method,json=assertionMethod,proto3" json:"assertion_method,omitempty"` + CapabilityDelegation []string `protobuf:"bytes,5,rep,name=capability_delegation,json=capabilityDelegation,proto3" json:"capability_delegation,omitempty"` + CapabilityInvocation []string `protobuf:"bytes,6,rep,name=capability_invocation,json=capabilityInvocation,proto3" json:"capability_invocation,omitempty"` + Service []string `protobuf:"bytes,7,rep,name=service,proto3" json:"service,omitempty"` } -func (m *Params) Reset() { *m = Params{} } -func (*Params) ProtoMessage() {} -func (*Params) Descriptor() ([]byte, []int) { +func (m *Document) Reset() { *m = Document{} } +func (m *Document) String() string { return proto.CompactTextString(m) } +func (*Document) ProtoMessage() {} +func (*Document) Descriptor() ([]byte, []int) { return fileDescriptor_fda181cae44f7c00, []int{1} } -func (m *Params) XXX_Unmarshal(b []byte) error { +func (m *Document) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *Document) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_Params.Marshal(b, m, deterministic) + return xxx_messageInfo_Document.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -100,488 +102,100 @@ func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *Params) XXX_Merge(src proto.Message) { - xxx_messageInfo_Params.Merge(m, src) +func (m *Document) XXX_Merge(src proto.Message) { + xxx_messageInfo_Document.Merge(m, src) } -func (m *Params) XXX_Size() int { +func (m *Document) XXX_Size() int { return m.Size() } -func (m *Params) XXX_DiscardUnknown() { - xxx_messageInfo_Params.DiscardUnknown(m) +func (m *Document) XXX_DiscardUnknown() { + xxx_messageInfo_Document.DiscardUnknown(m) } -var xxx_messageInfo_Params proto.InternalMessageInfo +var xxx_messageInfo_Document proto.InternalMessageInfo -func (m *Params) GetAllowedPublicKeys() map[string]*KeyInfo { +func (m *Document) GetId() string { if m != nil { - return m.AllowedPublicKeys + return m.Id + } + return "" +} + +func (m *Document) GetController() string { + if m != nil { + return m.Controller + } + return "" +} + +func (m *Document) GetAuthentication() []string { + if m != nil { + return m.Authentication } return nil } -func (m *Params) GetConveyancePreference() string { +func (m *Document) GetAssertionMethod() []string { if m != nil { - return m.ConveyancePreference - } - return "" -} - -func (m *Params) GetAttestationFormats() []string { - if m != nil { - return m.AttestationFormats + return m.AssertionMethod } return nil } -// KeyInfo defines information for accepted PubKey types -type KeyInfo struct { - Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` - Algorithm string `protobuf:"bytes,2,opt,name=algorithm,proto3" json:"algorithm,omitempty"` - Encoding string `protobuf:"bytes,3,opt,name=encoding,proto3" json:"encoding,omitempty"` - Curve string `protobuf:"bytes,4,opt,name=curve,proto3" json:"curve,omitempty"` -} - -func (m *KeyInfo) Reset() { *m = KeyInfo{} } -func (m *KeyInfo) String() string { return proto.CompactTextString(m) } -func (*KeyInfo) ProtoMessage() {} -func (*KeyInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_fda181cae44f7c00, []int{2} -} -func (m *KeyInfo) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *KeyInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_KeyInfo.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 *KeyInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_KeyInfo.Merge(m, src) -} -func (m *KeyInfo) XXX_Size() int { - return m.Size() -} -func (m *KeyInfo) XXX_DiscardUnknown() { - xxx_messageInfo_KeyInfo.DiscardUnknown(m) -} - -var xxx_messageInfo_KeyInfo proto.InternalMessageInfo - -func (m *KeyInfo) GetRole() string { +func (m *Document) GetCapabilityDelegation() []string { if m != nil { - return m.Role - } - return "" -} - -func (m *KeyInfo) GetAlgorithm() string { - if m != nil { - return m.Algorithm - } - return "" -} - -func (m *KeyInfo) GetEncoding() string { - if m != nil { - return m.Encoding - } - return "" -} - -func (m *KeyInfo) GetCurve() string { - if m != nil { - return m.Curve - } - return "" -} - -type Keyshares struct { - ValidatorCid string `protobuf:"bytes,1,opt,name=validator_cid,json=validatorCid,proto3" json:"validator_cid,omitempty"` - UserCid string `protobuf:"bytes,2,opt,name=user_cid,json=userCid,proto3" json:"user_cid,omitempty"` - LastUpdatedBlock int64 `protobuf:"varint,3,opt,name=last_updated_block,json=lastUpdatedBlock,proto3" json:"last_updated_block,omitempty"` -} - -func (m *Keyshares) Reset() { *m = Keyshares{} } -func (m *Keyshares) String() string { return proto.CompactTextString(m) } -func (*Keyshares) ProtoMessage() {} -func (*Keyshares) Descriptor() ([]byte, []int) { - return fileDescriptor_fda181cae44f7c00, []int{3} -} -func (m *Keyshares) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Keyshares) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Keyshares.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 *Keyshares) XXX_Merge(src proto.Message) { - xxx_messageInfo_Keyshares.Merge(m, src) -} -func (m *Keyshares) XXX_Size() int { - return m.Size() -} -func (m *Keyshares) XXX_DiscardUnknown() { - xxx_messageInfo_Keyshares.DiscardUnknown(m) -} - -var xxx_messageInfo_Keyshares proto.InternalMessageInfo - -func (m *Keyshares) GetValidatorCid() string { - if m != nil { - return m.ValidatorCid - } - return "" -} - -func (m *Keyshares) GetUserCid() string { - if m != nil { - return m.UserCid - } - return "" -} - -func (m *Keyshares) GetLastUpdatedBlock() int64 { - if m != nil { - return m.LastUpdatedBlock - } - return 0 -} - -// PubKey defines a public key for a did -type PubKey struct { - Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` - KeyType string `protobuf:"bytes,2,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` - RawKey *RawKey `protobuf:"bytes,3,opt,name=raw_key,json=rawKey,proto3" json:"raw_key,omitempty"` - Jwk *JSONWebKey `protobuf:"bytes,4,opt,name=jwk,proto3" json:"jwk,omitempty"` -} - -func (m *PubKey) Reset() { *m = PubKey{} } -func (m *PubKey) String() string { return proto.CompactTextString(m) } -func (*PubKey) ProtoMessage() {} -func (*PubKey) Descriptor() ([]byte, []int) { - return fileDescriptor_fda181cae44f7c00, []int{4} -} -func (m *PubKey) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PubKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PubKey.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 *PubKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_PubKey.Merge(m, src) -} -func (m *PubKey) XXX_Size() int { - return m.Size() -} -func (m *PubKey) XXX_DiscardUnknown() { - xxx_messageInfo_PubKey.DiscardUnknown(m) -} - -var xxx_messageInfo_PubKey proto.InternalMessageInfo - -func (m *PubKey) GetRole() string { - if m != nil { - return m.Role - } - return "" -} - -func (m *PubKey) GetKeyType() string { - if m != nil { - return m.KeyType - } - return "" -} - -func (m *PubKey) GetRawKey() *RawKey { - if m != nil { - return m.RawKey + return m.CapabilityDelegation } return nil } -func (m *PubKey) GetJwk() *JSONWebKey { +func (m *Document) GetCapabilityInvocation() []string { if m != nil { - return m.Jwk + return m.CapabilityInvocation } return nil } -// JWK represents a JSON Web Key -type JSONWebKey struct { - Kty string `protobuf:"bytes,1,opt,name=kty,proto3" json:"kty,omitempty"` - Crv string `protobuf:"bytes,2,opt,name=crv,proto3" json:"crv,omitempty"` - X string `protobuf:"bytes,3,opt,name=x,proto3" json:"x,omitempty"` - Y string `protobuf:"bytes,4,opt,name=y,proto3" json:"y,omitempty"` - N string `protobuf:"bytes,5,opt,name=n,proto3" json:"n,omitempty"` - E string `protobuf:"bytes,6,opt,name=e,proto3" json:"e,omitempty"` -} - -func (m *JSONWebKey) Reset() { *m = JSONWebKey{} } -func (m *JSONWebKey) String() string { return proto.CompactTextString(m) } -func (*JSONWebKey) ProtoMessage() {} -func (*JSONWebKey) Descriptor() ([]byte, []int) { - return fileDescriptor_fda181cae44f7c00, []int{5} -} -func (m *JSONWebKey) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *JSONWebKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_JSONWebKey.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 *JSONWebKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_JSONWebKey.Merge(m, src) -} -func (m *JSONWebKey) XXX_Size() int { - return m.Size() -} -func (m *JSONWebKey) XXX_DiscardUnknown() { - xxx_messageInfo_JSONWebKey.DiscardUnknown(m) -} - -var xxx_messageInfo_JSONWebKey proto.InternalMessageInfo - -func (m *JSONWebKey) GetKty() string { +func (m *Document) GetService() []string { if m != nil { - return m.Kty - } - return "" -} - -func (m *JSONWebKey) GetCrv() string { - if m != nil { - return m.Crv - } - return "" -} - -func (m *JSONWebKey) GetX() string { - if m != nil { - return m.X - } - return "" -} - -func (m *JSONWebKey) GetY() string { - if m != nil { - return m.Y - } - return "" -} - -func (m *JSONWebKey) GetN() string { - if m != nil { - return m.N - } - return "" -} - -func (m *JSONWebKey) GetE() string { - if m != nil { - return m.E - } - return "" -} - -type RawKey struct { - Algorithm string `protobuf:"bytes,1,opt,name=algorithm,proto3" json:"algorithm,omitempty"` - Encoding string `protobuf:"bytes,2,opt,name=encoding,proto3" json:"encoding,omitempty"` - Curve string `protobuf:"bytes,3,opt,name=curve,proto3" json:"curve,omitempty"` - Key []byte `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"` -} - -func (m *RawKey) Reset() { *m = RawKey{} } -func (m *RawKey) String() string { return proto.CompactTextString(m) } -func (*RawKey) ProtoMessage() {} -func (*RawKey) Descriptor() ([]byte, []int) { - return fileDescriptor_fda181cae44f7c00, []int{6} -} -func (m *RawKey) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RawKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_RawKey.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 *RawKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_RawKey.Merge(m, src) -} -func (m *RawKey) XXX_Size() int { - return m.Size() -} -func (m *RawKey) XXX_DiscardUnknown() { - xxx_messageInfo_RawKey.DiscardUnknown(m) -} - -var xxx_messageInfo_RawKey proto.InternalMessageInfo - -func (m *RawKey) GetAlgorithm() string { - if m != nil { - return m.Algorithm - } - return "" -} - -func (m *RawKey) GetEncoding() string { - if m != nil { - return m.Encoding - } - return "" -} - -func (m *RawKey) GetCurve() string { - if m != nil { - return m.Curve - } - return "" -} - -func (m *RawKey) GetKey() []byte { - if m != nil { - return m.Key + return m.Service } return nil } func init() { proto.RegisterType((*GenesisState)(nil), "did.v1.GenesisState") - proto.RegisterType((*Params)(nil), "did.v1.Params") - proto.RegisterMapType((map[string]*KeyInfo)(nil), "did.v1.Params.AllowedPublicKeysEntry") - proto.RegisterType((*KeyInfo)(nil), "did.v1.KeyInfo") - proto.RegisterType((*Keyshares)(nil), "did.v1.Keyshares") - proto.RegisterType((*PubKey)(nil), "did.v1.PubKey") - proto.RegisterType((*JSONWebKey)(nil), "did.v1.JSONWebKey") - proto.RegisterType((*RawKey)(nil), "did.v1.RawKey") + proto.RegisterType((*Document)(nil), "did.v1.Document") } func init() { proto.RegisterFile("did/v1/genesis.proto", fileDescriptor_fda181cae44f7c00) } var fileDescriptor_fda181cae44f7c00 = []byte{ - // 655 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0x4f, 0x4f, 0x13, 0x4f, - 0x18, 0xee, 0xb6, 0x65, 0xa1, 0x43, 0x7f, 0x3f, 0x61, 0xa8, 0xba, 0x34, 0xa6, 0x34, 0x55, 0x62, - 0x63, 0x48, 0x37, 0xc0, 0xc5, 0x10, 0x2e, 0x62, 0xd4, 0x68, 0x13, 0x6d, 0x16, 0x89, 0x89, 0x97, - 0xcd, 0x74, 0xf7, 0xa5, 0x5d, 0xba, 0x9d, 0x69, 0x66, 0xa7, 0x5b, 0xe6, 0x0b, 0x78, 0xf0, 0xe4, - 0xd1, 0x23, 0x1f, 0xc1, 0x8b, 0xdf, 0x81, 0x23, 0x47, 0x4f, 0xc6, 0xc0, 0x41, 0x3f, 0x86, 0x99, - 0x99, 0x2d, 0x05, 0x83, 0x5e, 0x66, 0xdf, 0xe7, 0x79, 0xde, 0xbc, 0xff, 0xb3, 0xa8, 0x12, 0x46, - 0xa1, 0x9b, 0x6e, 0xba, 0x3d, 0xa0, 0x90, 0x44, 0x49, 0x6b, 0xc4, 0x99, 0x60, 0xd8, 0x0e, 0xa3, - 0xb0, 0x95, 0x6e, 0x56, 0x97, 0xc9, 0x30, 0xa2, 0xcc, 0xd5, 0xaf, 0x91, 0xaa, 0x95, 0x1e, 0xeb, - 0x31, 0x6d, 0xba, 0xca, 0x32, 0x6c, 0x63, 0x17, 0x95, 0x5f, 0x98, 0x08, 0xfb, 0x82, 0x08, 0xc0, - 0x1b, 0xc8, 0x1e, 0x11, 0x4e, 0x86, 0x89, 0x63, 0xd5, 0xad, 0xe6, 0xe2, 0xd6, 0xff, 0x2d, 0x13, - 0xb1, 0xd5, 0xd1, 0xec, 0x5e, 0xf1, 0xf4, 0xfb, 0x5a, 0xce, 0xcb, 0x7c, 0x1a, 0x5f, 0xf3, 0xc8, - 0x36, 0x02, 0x3e, 0x40, 0x2b, 0x24, 0x8e, 0xd9, 0x04, 0x42, 0x7f, 0x34, 0xee, 0xc6, 0x51, 0xe0, - 0x0f, 0x40, 0x26, 0x4e, 0xbe, 0x5e, 0x68, 0x2e, 0x6e, 0xad, 0x5f, 0x8f, 0xd2, 0x7a, 0x62, 0x3c, - 0x3b, 0xda, 0xb1, 0x0d, 0x32, 0x79, 0x46, 0x05, 0x97, 0xde, 0x32, 0xf9, 0x93, 0xc7, 0xdb, 0xe8, - 0x76, 0xc0, 0x68, 0x0a, 0x92, 0xd0, 0x00, 0xfc, 0x11, 0x87, 0x43, 0xe0, 0x40, 0x03, 0x70, 0x0a, - 0x75, 0xab, 0x59, 0xf2, 0x2a, 0x33, 0xb1, 0x73, 0xa9, 0x61, 0x17, 0xad, 0x10, 0x21, 0x20, 0x11, - 0x44, 0x44, 0x8c, 0xfa, 0x87, 0x8c, 0x0f, 0x89, 0x48, 0x9c, 0x62, 0xbd, 0xd0, 0x2c, 0x79, 0xf8, - 0x8a, 0xf4, 0xdc, 0x28, 0xd5, 0x03, 0x74, 0xe7, 0xe6, 0x92, 0xf0, 0x12, 0x2a, 0x0c, 0x40, 0xea, - 0x61, 0x94, 0x3c, 0x65, 0xe2, 0x75, 0x34, 0x97, 0x92, 0x78, 0x0c, 0x4e, 0x5e, 0x0f, 0xe8, 0xd6, - 0xb4, 0xb5, 0x36, 0xc8, 0x97, 0xf4, 0x90, 0x79, 0x46, 0xdd, 0xc9, 0x3f, 0xb6, 0x76, 0xee, 0x7e, - 0x3e, 0x59, 0xcb, 0xfd, 0x3a, 0x59, 0xb3, 0x3e, 0xfe, 0xfc, 0xf2, 0x08, 0xa9, 0x85, 0x65, 0x73, - 0x1b, 0xa2, 0xf9, 0xcc, 0x1d, 0x63, 0x54, 0xe4, 0x2c, 0x86, 0x2c, 0x83, 0xb6, 0xf1, 0x3d, 0x54, - 0x22, 0x71, 0x8f, 0xf1, 0x48, 0xf4, 0x87, 0x3a, 0x4d, 0xc9, 0x9b, 0x11, 0xb8, 0x8a, 0x16, 0x80, - 0x06, 0x2c, 0x8c, 0x68, 0x2f, 0x9b, 0xc2, 0x25, 0xc6, 0x15, 0x34, 0x17, 0x8c, 0x79, 0x0a, 0x4e, - 0x51, 0x0b, 0x06, 0x34, 0x24, 0x2a, 0xa9, 0x8e, 0xfa, 0x84, 0x43, 0x82, 0xef, 0xa3, 0xff, 0x52, - 0x12, 0x47, 0x21, 0x11, 0x8c, 0xfb, 0x41, 0x14, 0x66, 0x99, 0xcb, 0x97, 0xe4, 0xd3, 0x28, 0xc4, - 0xab, 0x68, 0x61, 0x9c, 0x80, 0xd1, 0x4d, 0x01, 0xf3, 0x0a, 0x2b, 0x69, 0x03, 0xe1, 0x98, 0x24, - 0xc2, 0x1f, 0x8f, 0x42, 0x22, 0x20, 0xf4, 0xbb, 0x31, 0x0b, 0x06, 0xba, 0x90, 0x82, 0xb7, 0xa4, - 0x94, 0x03, 0x23, 0xec, 0x29, 0xbe, 0xf1, 0xc1, 0x42, 0x76, 0x67, 0xdc, 0x6d, 0x83, 0xbc, 0xb1, - 0xd3, 0x55, 0xb4, 0x30, 0x00, 0xe9, 0x0b, 0x39, 0x82, 0x69, 0x9e, 0x01, 0xc8, 0xb7, 0x72, 0x04, - 0xf8, 0x21, 0x9a, 0xe7, 0x64, 0xa2, 0xae, 0x48, 0x07, 0xbf, 0x72, 0x8a, 0x1e, 0x99, 0xb4, 0x41, - 0x7a, 0x36, 0xd7, 0x5f, 0xfc, 0x00, 0x15, 0x8e, 0x26, 0x03, 0xdd, 0xf1, 0xe2, 0x16, 0x9e, 0x3a, - 0xbd, 0xda, 0x7f, 0xf3, 0xfa, 0x1d, 0xa8, 0xc4, 0x9e, 0x92, 0x1b, 0x7d, 0x84, 0x66, 0x94, 0x5e, - 0xab, 0x98, 0xad, 0x55, 0x68, 0x26, 0xe0, 0x69, 0x56, 0x84, 0x32, 0x71, 0x19, 0x59, 0xc7, 0xd9, - 0x80, 0xad, 0x63, 0x85, 0x64, 0x36, 0x55, 0x4b, 0x2a, 0x44, 0x9d, 0x39, 0x83, 0xa8, 0x42, 0xe0, - 0xd8, 0x06, 0x41, 0xe3, 0x08, 0xd9, 0xa6, 0xc2, 0xeb, 0x7b, 0xb4, 0xfe, 0xb5, 0xc7, 0xfc, 0xdf, - 0xf6, 0x58, 0xb8, 0xb2, 0xc7, 0xe9, 0x31, 0xaa, 0x2a, 0xca, 0xfa, 0x18, 0xf7, 0x76, 0x4f, 0xcf, - 0x6b, 0xd6, 0xd9, 0x79, 0xcd, 0xfa, 0x71, 0x5e, 0xb3, 0x3e, 0x5d, 0xd4, 0x72, 0x67, 0x17, 0xb5, - 0xdc, 0xb7, 0x8b, 0x5a, 0xee, 0x7d, 0xa3, 0x17, 0x89, 0xfe, 0xb8, 0xdb, 0x0a, 0xd8, 0xd0, 0x65, - 0x34, 0x61, 0x94, 0xbb, 0xfa, 0x39, 0x76, 0xd5, 0x1d, 0xaa, 0x81, 0x27, 0x5d, 0x5b, 0xff, 0x03, - 0xb6, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x19, 0xe9, 0x6d, 0x4c, 0x04, 0x00, 0x00, + // 344 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x91, 0xc1, 0x6a, 0xea, 0x40, + 0x14, 0x86, 0x93, 0xe8, 0x8d, 0xd7, 0xb9, 0x17, 0xdb, 0x4e, 0x2d, 0x04, 0x17, 0xa9, 0xb8, 0x28, + 0x16, 0x4a, 0x06, 0xeb, 0xd6, 0x95, 0x08, 0xa5, 0x8b, 0x42, 0xb1, 0xbb, 0x6e, 0x64, 0xcc, 0x0c, + 0x71, 0x20, 0x99, 0x13, 0x66, 0xc6, 0x50, 0xdf, 0xa2, 0x7d, 0x2b, 0x97, 0x2e, 0xbb, 0x2a, 0x45, + 0x5f, 0xa4, 0x38, 0x49, 0x6d, 0x71, 0x73, 0x38, 0xe7, 0xfb, 0xff, 0xff, 0xcc, 0xc0, 0x41, 0x6d, + 0x26, 0x18, 0x29, 0x06, 0x24, 0xe1, 0x92, 0x6b, 0xa1, 0xa3, 0x5c, 0x81, 0x01, 0xec, 0x33, 0xc1, + 0xa2, 0x62, 0xd0, 0x39, 0xa3, 0x99, 0x90, 0x40, 0x6c, 0x2d, 0xa5, 0xce, 0x79, 0x15, 0xc8, 0xa9, + 0xa2, 0x59, 0xe5, 0xef, 0xb4, 0x13, 0x48, 0xc0, 0xb6, 0x64, 0xdf, 0x95, 0xb4, 0x37, 0x42, 0xff, + 0xef, 0xca, 0xb5, 0x4f, 0x86, 0x1a, 0x8e, 0x6f, 0x90, 0x5f, 0xa6, 0x02, 0xb7, 0xeb, 0xf6, 0xff, + 0xdd, 0xb6, 0xa2, 0xf2, 0x99, 0xe8, 0xd1, 0xd2, 0x71, 0x7d, 0xfd, 0x71, 0xe9, 0x4c, 0x2b, 0x4f, + 0xef, 0xcd, 0x43, 0x7f, 0x27, 0x10, 0x2f, 0x33, 0x2e, 0x0d, 0x6e, 0x21, 0x4f, 0x30, 0x1b, 0x6b, + 0x4e, 0x3d, 0xc1, 0x70, 0x88, 0x50, 0x0c, 0xd2, 0x28, 0x48, 0x53, 0xae, 0x02, 0xcf, 0xf2, 0x5f, + 0x04, 0x5f, 0xa1, 0x16, 0x5d, 0x9a, 0x05, 0x97, 0x46, 0xc4, 0xd4, 0x08, 0x90, 0x41, 0xad, 0x5b, + 0xeb, 0x37, 0xa7, 0x47, 0x14, 0x5f, 0xa3, 0x53, 0xaa, 0x35, 0x57, 0xfb, 0x61, 0x96, 0x71, 0xb3, + 0x00, 0x16, 0xd4, 0xad, 0xf3, 0xe4, 0xc0, 0x1f, 0x2c, 0xc6, 0x43, 0x74, 0x11, 0xd3, 0x9c, 0xce, + 0x45, 0x2a, 0xcc, 0x6a, 0xc6, 0x78, 0xca, 0x93, 0x72, 0xf3, 0x1f, 0xeb, 0x6f, 0xff, 0x88, 0x93, + 0x83, 0x76, 0x14, 0x12, 0xb2, 0x80, 0xea, 0x3b, 0xfe, 0x71, 0xe8, 0xfe, 0xa0, 0xe1, 0x00, 0x35, + 0x34, 0x57, 0x85, 0x88, 0x79, 0xd0, 0xb0, 0xb6, 0xef, 0x71, 0x3c, 0x5a, 0x6f, 0x43, 0x77, 0xb3, + 0x0d, 0xdd, 0xcf, 0x6d, 0xe8, 0xbe, 0xee, 0x42, 0x67, 0xb3, 0x0b, 0x9d, 0xf7, 0x5d, 0xe8, 0x3c, + 0xf7, 0x12, 0x61, 0x16, 0xcb, 0x79, 0x14, 0x43, 0x46, 0x40, 0x6a, 0x90, 0x8a, 0xd8, 0xf2, 0x42, + 0xf6, 0xf7, 0x32, 0xab, 0x9c, 0xeb, 0xb9, 0x6f, 0xcf, 0x32, 0xfc, 0x0a, 0x00, 0x00, 0xff, 0xff, + 0x44, 0xa7, 0x3d, 0xf3, 0xf4, 0x01, 0x00, 0x00, } -func (this *Params) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*Params) - if !ok { - that2, ok := that.(Params) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if len(this.AllowedPublicKeys) != len(that1.AllowedPublicKeys) { - return false - } - for i := range this.AllowedPublicKeys { - if !this.AllowedPublicKeys[i].Equal(that1.AllowedPublicKeys[i]) { - return false - } - } - if this.ConveyancePreference != that1.ConveyancePreference { - return false - } - if len(this.AttestationFormats) != len(that1.AttestationFormats) { - return false - } - for i := range this.AttestationFormats { - if this.AttestationFormats[i] != that1.AttestationFormats[i] { - return false - } - } - return true -} func (m *GenesisState) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -615,7 +229,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *Params) Marshal() (dAtA []byte, err error) { +func (m *Document) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -625,325 +239,72 @@ func (m *Params) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Params) MarshalTo(dAtA []byte) (int, error) { +func (m *Document) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Document) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.AttestationFormats) > 0 { - for iNdEx := len(m.AttestationFormats) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AttestationFormats[iNdEx]) - copy(dAtA[i:], m.AttestationFormats[iNdEx]) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.AttestationFormats[iNdEx]))) + if len(m.Service) > 0 { + for iNdEx := len(m.Service) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Service[iNdEx]) + copy(dAtA[i:], m.Service[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Service[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if len(m.CapabilityInvocation) > 0 { + for iNdEx := len(m.CapabilityInvocation) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.CapabilityInvocation[iNdEx]) + copy(dAtA[i:], m.CapabilityInvocation[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.CapabilityInvocation[iNdEx]))) + i-- + dAtA[i] = 0x32 + } + } + if len(m.CapabilityDelegation) > 0 { + for iNdEx := len(m.CapabilityDelegation) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.CapabilityDelegation[iNdEx]) + copy(dAtA[i:], m.CapabilityDelegation[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.CapabilityDelegation[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + if len(m.AssertionMethod) > 0 { + for iNdEx := len(m.AssertionMethod) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AssertionMethod[iNdEx]) + copy(dAtA[i:], m.AssertionMethod[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.AssertionMethod[iNdEx]))) i-- dAtA[i] = 0x22 } } - if len(m.ConveyancePreference) > 0 { - i -= len(m.ConveyancePreference) - copy(dAtA[i:], m.ConveyancePreference) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.ConveyancePreference))) - i-- - dAtA[i] = 0x1a - } - if len(m.AllowedPublicKeys) > 0 { - for k := range m.AllowedPublicKeys { - v := m.AllowedPublicKeys[k] - baseI := i - if v != nil { - { - size, err := v.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarintGenesis(dAtA, i, uint64(len(k))) + if len(m.Authentication) > 0 { + for iNdEx := len(m.Authentication) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Authentication[iNdEx]) + copy(dAtA[i:], m.Authentication[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Authentication[iNdEx]))) i-- - dAtA[i] = 0xa - i = encodeVarintGenesis(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a } } - return len(dAtA) - i, nil -} - -func (m *KeyInfo) 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 *KeyInfo) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *KeyInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Curve) > 0 { - i -= len(m.Curve) - copy(dAtA[i:], m.Curve) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Curve))) - i-- - dAtA[i] = 0x22 - } - if len(m.Encoding) > 0 { - i -= len(m.Encoding) - copy(dAtA[i:], m.Encoding) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Encoding))) - i-- - dAtA[i] = 0x1a - } - if len(m.Algorithm) > 0 { - i -= len(m.Algorithm) - copy(dAtA[i:], m.Algorithm) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Algorithm))) + if len(m.Controller) > 0 { + i -= len(m.Controller) + copy(dAtA[i:], m.Controller) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Controller))) i-- dAtA[i] = 0x12 } - if len(m.Role) > 0 { - i -= len(m.Role) - copy(dAtA[i:], m.Role) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Role))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Keyshares) 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 *Keyshares) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Keyshares) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.LastUpdatedBlock != 0 { - i = encodeVarintGenesis(dAtA, i, uint64(m.LastUpdatedBlock)) - i-- - dAtA[i] = 0x18 - } - if len(m.UserCid) > 0 { - i -= len(m.UserCid) - copy(dAtA[i:], m.UserCid) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.UserCid))) - i-- - dAtA[i] = 0x12 - } - if len(m.ValidatorCid) > 0 { - i -= len(m.ValidatorCid) - copy(dAtA[i:], m.ValidatorCid) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.ValidatorCid))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *PubKey) 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 *PubKey) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PubKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Jwk != nil { - { - size, err := m.Jwk.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.RawKey != nil { - { - size, err := m.RawKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if len(m.KeyType) > 0 { - i -= len(m.KeyType) - copy(dAtA[i:], m.KeyType) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.KeyType))) - i-- - dAtA[i] = 0x12 - } - if len(m.Role) > 0 { - i -= len(m.Role) - copy(dAtA[i:], m.Role) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Role))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *JSONWebKey) 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 *JSONWebKey) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *JSONWebKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.E) > 0 { - i -= len(m.E) - copy(dAtA[i:], m.E) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.E))) - i-- - dAtA[i] = 0x32 - } - if len(m.N) > 0 { - i -= len(m.N) - copy(dAtA[i:], m.N) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.N))) - i-- - dAtA[i] = 0x2a - } - if len(m.Y) > 0 { - i -= len(m.Y) - copy(dAtA[i:], m.Y) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Y))) - i-- - dAtA[i] = 0x22 - } - if len(m.X) > 0 { - i -= len(m.X) - copy(dAtA[i:], m.X) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.X))) - i-- - dAtA[i] = 0x1a - } - if len(m.Crv) > 0 { - i -= len(m.Crv) - copy(dAtA[i:], m.Crv) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Crv))) - i-- - dAtA[i] = 0x12 - } - if len(m.Kty) > 0 { - i -= len(m.Kty) - copy(dAtA[i:], m.Kty) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Kty))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *RawKey) 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 *RawKey) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RawKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Key) > 0 { - i -= len(m.Key) - copy(dAtA[i:], m.Key) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Key))) - i-- - dAtA[i] = 0x22 - } - if len(m.Curve) > 0 { - i -= len(m.Curve) - copy(dAtA[i:], m.Curve) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Curve))) - i-- - dAtA[i] = 0x1a - } - if len(m.Encoding) > 0 { - i -= len(m.Encoding) - copy(dAtA[i:], m.Encoding) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Encoding))) - i-- - dAtA[i] = 0x12 - } - if len(m.Algorithm) > 0 { - i -= len(m.Algorithm) - copy(dAtA[i:], m.Algorithm) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Algorithm))) + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Id))) i-- dAtA[i] = 0xa } @@ -972,162 +333,49 @@ func (m *GenesisState) Size() (n int) { return n } -func (m *Params) Size() (n int) { +func (m *Document) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.AllowedPublicKeys) > 0 { - for k, v := range m.AllowedPublicKeys { - _ = k - _ = v - l = 0 - if v != nil { - l = v.Size() - l += 1 + sovGenesis(uint64(l)) - } - mapEntrySize := 1 + len(k) + sovGenesis(uint64(len(k))) + l - n += mapEntrySize + 1 + sovGenesis(uint64(mapEntrySize)) - } - } - l = len(m.ConveyancePreference) + l = len(m.Id) if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - if len(m.AttestationFormats) > 0 { - for _, s := range m.AttestationFormats { + l = len(m.Controller) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if len(m.Authentication) > 0 { + for _, s := range m.Authentication { l = len(s) n += 1 + l + sovGenesis(uint64(l)) } } - return n -} - -func (m *KeyInfo) Size() (n int) { - if m == nil { - return 0 + if len(m.AssertionMethod) > 0 { + for _, s := range m.AssertionMethod { + l = len(s) + n += 1 + l + sovGenesis(uint64(l)) + } } - var l int - _ = l - l = len(m.Role) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) + if len(m.CapabilityDelegation) > 0 { + for _, s := range m.CapabilityDelegation { + l = len(s) + n += 1 + l + sovGenesis(uint64(l)) + } } - l = len(m.Algorithm) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) + if len(m.CapabilityInvocation) > 0 { + for _, s := range m.CapabilityInvocation { + l = len(s) + n += 1 + l + sovGenesis(uint64(l)) + } } - l = len(m.Encoding) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.Curve) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - return n -} - -func (m *Keyshares) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ValidatorCid) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.UserCid) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - if m.LastUpdatedBlock != 0 { - n += 1 + sovGenesis(uint64(m.LastUpdatedBlock)) - } - return n -} - -func (m *PubKey) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Role) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.KeyType) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - if m.RawKey != nil { - l = m.RawKey.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - if m.Jwk != nil { - l = m.Jwk.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - return n -} - -func (m *JSONWebKey) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Kty) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.Crv) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.X) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.Y) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.N) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.E) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - return n -} - -func (m *RawKey) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Algorithm) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.Encoding) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.Curve) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } - l = len(m.Key) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) + if len(m.Service) > 0 { + for _, s := range m.Service { + l = len(s) + n += 1 + l + sovGenesis(uint64(l)) + } } return n } @@ -1221,7 +469,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } return nil } -func (m *Params) Unmarshal(dAtA []byte) error { +func (m *Document) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1244,258 +492,15 @@ func (m *Params) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Params: wiretype end group for non-group") + return fmt.Errorf("proto: Document: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedPublicKeys", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.AllowedPublicKeys == nil { - m.AllowedPublicKeys = make(map[string]*KeyInfo) - } - var mapkey string - var mapvalue *KeyInfo - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenesis - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenesis - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthGenesis - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthGenesis - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &KeyInfo{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.AllowedPublicKeys[mapkey] = mapvalue - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConveyancePreference", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConveyancePreference = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AttestationFormats", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AttestationFormats = append(m.AttestationFormats, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *KeyInfo) 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 ErrIntOverflowGenesis - } - 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: KeyInfo: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: KeyInfo: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Document: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1523,11 +528,11 @@ func (m *KeyInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Role = string(dAtA[iNdEx:postIndex]) + m.Id = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Algorithm", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1555,11 +560,11 @@ func (m *KeyInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Algorithm = string(dAtA[iNdEx:postIndex]) + m.Controller = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Encoding", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Authentication", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1587,11 +592,11 @@ func (m *KeyInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Encoding = string(dAtA[iNdEx:postIndex]) + m.Authentication = append(m.Authentication, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Curve", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AssertionMethod", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1619,508 +624,11 @@ func (m *KeyInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Curve = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Keyshares) 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 ErrIntOverflowGenesis - } - 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: Keyshares: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Keyshares: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ValidatorCid", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ValidatorCid = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserCid", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UserCid = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LastUpdatedBlock", wireType) - } - m.LastUpdatedBlock = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.LastUpdatedBlock |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PubKey) 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 ErrIntOverflowGenesis - } - 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: PubKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PubKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Role = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KeyType", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.KeyType = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RawKey", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.RawKey == nil { - m.RawKey = &RawKey{} - } - if err := m.RawKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Jwk", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Jwk == nil { - m.Jwk = &JSONWebKey{} - } - if err := m.Jwk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *JSONWebKey) 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 ErrIntOverflowGenesis - } - 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: JSONWebKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JSONWebKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kty", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Kty = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Crv", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Crv = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field X", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.X = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Y", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Y = string(dAtA[iNdEx:postIndex]) + m.AssertionMethod = append(m.AssertionMethod, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field N", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CapabilityDelegation", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2148,11 +656,11 @@ func (m *JSONWebKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.N = string(dAtA[iNdEx:postIndex]) + m.CapabilityDelegation = append(m.CapabilityDelegation, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field E", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CapabilityInvocation", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2180,61 +688,11 @@ func (m *JSONWebKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.E = string(dAtA[iNdEx:postIndex]) + m.CapabilityInvocation = append(m.CapabilityInvocation, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RawKey) 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 ErrIntOverflowGenesis - } - 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: RawKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RawKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Algorithm", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2262,105 +720,7 @@ func (m *RawKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Algorithm = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Encoding", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Encoding = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Curve", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - 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 ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Curve = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) - if m.Key == nil { - m.Key = []byte{} - } + m.Service = append(m.Service, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/did/types/mpc/secp256k1_pk.go b/x/did/types/mpc/secp256k1_pk.go deleted file mode 100644 index dbebfa45e..000000000 --- a/x/did/types/mpc/secp256k1_pk.go +++ /dev/null @@ -1,68 +0,0 @@ -package mpc - -import ( - "bytes" - "fmt" - - "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/golang/protobuf/proto" -) - -// CustomPubKey represents a custom secp256k1 public key. -type CustomPubKey struct { - proto.Message - - Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` -} - -// NewCustomPubKeyFromRawBytes creates a new CustomPubKey from raw bytes. -func NewCustomPubKeyFromRawBytes(key []byte) (*CustomPubKey, error) { - // Validate the key length and format - if len(key) != 33 { - return nil, fmt.Errorf("invalid key length; expected 33 bytes, got %d", len(key)) - } - if key[0] != 0x02 && key[0] != 0x03 { - return nil, fmt.Errorf("invalid key format; expected 0x02 or 0x03 as the first byte, got 0x%02x", key[0]) - } - - return &CustomPubKey{Key: key}, nil -} - -// Bytes returns the byte representation of the public key. -func (pk *CustomPubKey) Bytes() []byte { - return pk.Key -} - -// Equals checks if two public keys are equal. -func (pk *CustomPubKey) Equals(other types.PubKey) bool { - return bytes.EqualFold(pk.Bytes(), other.Bytes()) -} - -// Type returns the type of the public key. -func (pk *CustomPubKey) Type() string { - return "custom-secp256k1" -} - -// Marshal implements the proto.Message interface. -func (pk *CustomPubKey) Marshal() ([]byte, error) { - return proto.Marshal(pk) -} - -// Unmarshal implements the proto.Message interface. -func (pk *CustomPubKey) Unmarshal(data []byte) error { - return proto.Unmarshal(data, pk) -} - -// Address returns the address derived from the public key. -func (pk *CustomPubKey) Address() []byte { - // Implement address derivation logic here - // For simplicity, this example uses a placeholder - return []byte("derived-address") -} - -// VerifySignature verifies a signature using the public key. -func (pk *CustomPubKey) VerifySignature(msg []byte, sig []byte) bool { - // Implement signature verification logic here - // For simplicity, this example uses a placeholder - return true -} diff --git a/x/did/types/params.go b/x/did/types/params.go index af24005a5..a88f388d9 100644 --- a/x/did/types/params.go +++ b/x/did/types/params.go @@ -4,10 +4,10 @@ import ( "encoding/json" fmt "fmt" - "github.com/onsonr/sonr/internal/orm/keyalgorithm" - "github.com/onsonr/sonr/internal/orm/keycurve" - "github.com/onsonr/sonr/internal/orm/keyencoding" - "github.com/onsonr/sonr/internal/orm/keyrole" + "github.com/onsonr/sonr/pkg/motr/types/orm/keyalgorithm" + "github.com/onsonr/sonr/pkg/motr/types/orm/keycurve" + "github.com/onsonr/sonr/pkg/motr/types/orm/keyencoding" + "github.com/onsonr/sonr/pkg/motr/types/orm/keyrole" ) // DefaultParams returns default module parameters. diff --git a/x/did/types/params.pb.go b/x/did/types/params.pb.go new file mode 100644 index 000000000..5f551f6e0 --- /dev/null +++ b/x/did/types/params.pb.go @@ -0,0 +1,931 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: did/v1/params.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/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.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Params defines the set of module parameters. +type Params struct { + // Whitelisted Key Types + AllowedPublicKeys map[string]*KeyInfo `protobuf:"bytes,2,rep,name=allowed_public_keys,json=allowedPublicKeys,proto3" json:"allowed_public_keys,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // ConveyancePreference defines the conveyance preference + ConveyancePreference string `protobuf:"bytes,3,opt,name=conveyance_preference,json=conveyancePreference,proto3" json:"conveyance_preference,omitempty"` + // AttestationFormats defines the attestation formats + AttestationFormats []string `protobuf:"bytes,4,rep,name=attestation_formats,json=attestationFormats,proto3" json:"attestation_formats,omitempty"` +} + +func (m *Params) Reset() { *m = Params{} } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_9d62d07335ae093e, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetAllowedPublicKeys() map[string]*KeyInfo { + if m != nil { + return m.AllowedPublicKeys + } + return nil +} + +func (m *Params) GetConveyancePreference() string { + if m != nil { + return m.ConveyancePreference + } + return "" +} + +func (m *Params) GetAttestationFormats() []string { + if m != nil { + return m.AttestationFormats + } + return nil +} + +// KeyInfo defines information for accepted PubKey types +type KeyInfo struct { + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` + Algorithm string `protobuf:"bytes,2,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + Encoding string `protobuf:"bytes,3,opt,name=encoding,proto3" json:"encoding,omitempty"` + Curve string `protobuf:"bytes,4,opt,name=curve,proto3" json:"curve,omitempty"` +} + +func (m *KeyInfo) Reset() { *m = KeyInfo{} } +func (m *KeyInfo) String() string { return proto.CompactTextString(m) } +func (*KeyInfo) ProtoMessage() {} +func (*KeyInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_9d62d07335ae093e, []int{1} +} +func (m *KeyInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *KeyInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_KeyInfo.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 *KeyInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_KeyInfo.Merge(m, src) +} +func (m *KeyInfo) XXX_Size() int { + return m.Size() +} +func (m *KeyInfo) XXX_DiscardUnknown() { + xxx_messageInfo_KeyInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_KeyInfo proto.InternalMessageInfo + +func (m *KeyInfo) GetRole() string { + if m != nil { + return m.Role + } + return "" +} + +func (m *KeyInfo) GetAlgorithm() string { + if m != nil { + return m.Algorithm + } + return "" +} + +func (m *KeyInfo) GetEncoding() string { + if m != nil { + return m.Encoding + } + return "" +} + +func (m *KeyInfo) GetCurve() string { + if m != nil { + return m.Curve + } + return "" +} + +func init() { + proto.RegisterType((*Params)(nil), "did.v1.Params") + proto.RegisterMapType((map[string]*KeyInfo)(nil), "did.v1.Params.AllowedPublicKeysEntry") + proto.RegisterType((*KeyInfo)(nil), "did.v1.KeyInfo") +} + +func init() { proto.RegisterFile("did/v1/params.proto", fileDescriptor_9d62d07335ae093e) } + +var fileDescriptor_9d62d07335ae093e = []byte{ + // 412 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x31, 0x6f, 0xd3, 0x40, + 0x14, 0xc7, 0x73, 0x49, 0x1a, 0xc8, 0x75, 0x80, 0x5e, 0x02, 0x58, 0x11, 0x72, 0xa3, 0x48, 0x95, + 0x2c, 0x06, 0x9f, 0xda, 0x2e, 0xa8, 0x62, 0x01, 0x09, 0x24, 0xd4, 0x25, 0xb2, 0xd4, 0x85, 0xc5, + 0xba, 0xd8, 0x2f, 0xee, 0xa9, 0xf6, 0x3d, 0xeb, 0x7c, 0x36, 0xf8, 0x2b, 0x30, 0x31, 0x32, 0xf6, + 0x23, 0xb0, 0xf0, 0x1d, 0x18, 0x3b, 0x32, 0xa2, 0x64, 0x80, 0x8f, 0x81, 0x7c, 0x17, 0x5a, 0x84, + 0x58, 0x9e, 0xfe, 0xef, 0xfd, 0xfe, 0x7a, 0xef, 0xdd, 0x3b, 0x3a, 0x49, 0x65, 0xca, 0x9b, 0x63, + 0x5e, 0x0a, 0x2d, 0x8a, 0x2a, 0x2c, 0x35, 0x1a, 0x64, 0xa3, 0x54, 0xa6, 0x61, 0x73, 0x3c, 0x3b, + 0x10, 0x85, 0x54, 0xc8, 0x6d, 0x74, 0x68, 0x36, 0xcd, 0x30, 0x43, 0x2b, 0x79, 0xa7, 0x5c, 0x75, + 0xf1, 0xb5, 0x4f, 0x47, 0x4b, 0xdb, 0x81, 0x5d, 0xd0, 0x89, 0xc8, 0x73, 0x7c, 0x0f, 0x69, 0x5c, + 0xd6, 0xab, 0x5c, 0x26, 0xf1, 0x15, 0xb4, 0x95, 0xd7, 0x9f, 0x0f, 0x82, 0xfd, 0x93, 0xa3, 0xd0, + 0x75, 0x0e, 0x9d, 0x39, 0x7c, 0xe9, 0x9c, 0x4b, 0x6b, 0x3c, 0x87, 0xb6, 0x7a, 0xad, 0x8c, 0x6e, + 0xa3, 0x03, 0xf1, 0x6f, 0x9d, 0x9d, 0xd2, 0x47, 0x09, 0xaa, 0x06, 0x5a, 0xa1, 0x12, 0x88, 0x4b, + 0x0d, 0x6b, 0xd0, 0xa0, 0x12, 0xf0, 0x06, 0x73, 0x12, 0x8c, 0xa3, 0xe9, 0x1d, 0x5c, 0xde, 0x32, + 0xc6, 0xe9, 0x44, 0x18, 0x03, 0x95, 0x11, 0x46, 0xa2, 0x8a, 0xd7, 0xa8, 0x0b, 0x61, 0x2a, 0x6f, + 0x38, 0x1f, 0x04, 0xe3, 0x88, 0xfd, 0x85, 0xde, 0x38, 0x32, 0xbb, 0xa0, 0x8f, 0xff, 0xbf, 0x12, + 0x7b, 0x48, 0x07, 0x57, 0xd0, 0x7a, 0xc4, 0x4e, 0xeb, 0x24, 0x3b, 0xa2, 0x7b, 0x8d, 0xc8, 0x6b, + 0xf0, 0xfa, 0x73, 0x12, 0xec, 0x9f, 0x3c, 0xf8, 0xf3, 0xb4, 0x73, 0x68, 0xdf, 0xaa, 0x35, 0x46, + 0x8e, 0x9e, 0xf5, 0x9f, 0x93, 0xb3, 0x27, 0x9f, 0xaf, 0x0f, 0x7b, 0xbf, 0xae, 0x0f, 0xc9, 0xc7, + 0x9f, 0x5f, 0x9e, 0xd1, 0xee, 0xe2, 0xee, 0xdc, 0x8b, 0x82, 0xde, 0xdb, 0xd9, 0x19, 0xa3, 0x43, + 0x8d, 0x39, 0xec, 0x26, 0x58, 0xcd, 0x9e, 0xd2, 0xb1, 0xc8, 0x33, 0xd4, 0xd2, 0x5c, 0x16, 0x76, + 0xcc, 0x38, 0xba, 0x2b, 0xb0, 0x19, 0xbd, 0x0f, 0x2a, 0xc1, 0x54, 0xaa, 0x6c, 0x77, 0x85, 0xdb, + 0x9c, 0x4d, 0xe9, 0x5e, 0x52, 0xeb, 0x06, 0xbc, 0xa1, 0x05, 0x2e, 0x79, 0xf5, 0xe2, 0xdb, 0xc6, + 0x27, 0x37, 0x1b, 0x9f, 0xfc, 0xd8, 0xf8, 0xe4, 0xd3, 0xd6, 0xef, 0xdd, 0x6c, 0xfd, 0xde, 0xf7, + 0xad, 0xdf, 0x7b, 0xb7, 0xc8, 0xa4, 0xb9, 0xac, 0x57, 0x61, 0x82, 0x05, 0x47, 0x55, 0xa1, 0xd2, + 0xdc, 0x86, 0x0f, 0xbc, 0xdb, 0xd6, 0xb4, 0x25, 0x54, 0xab, 0x91, 0xfd, 0xeb, 0xd3, 0xdf, 0x01, + 0x00, 0x00, 0xff, 0xff, 0xd2, 0xa2, 0x88, 0x53, 0x33, 0x02, 0x00, 0x00, +} + +func (this *Params) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Params) + if !ok { + that2, ok := that.(Params) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.AllowedPublicKeys) != len(that1.AllowedPublicKeys) { + return false + } + for i := range this.AllowedPublicKeys { + if !this.AllowedPublicKeys[i].Equal(that1.AllowedPublicKeys[i]) { + return false + } + } + if this.ConveyancePreference != that1.ConveyancePreference { + return false + } + if len(this.AttestationFormats) != len(that1.AttestationFormats) { + return false + } + for i := range this.AttestationFormats { + if this.AttestationFormats[i] != that1.AttestationFormats[i] { + return false + } + } + return true +} +func (m *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AttestationFormats) > 0 { + for iNdEx := len(m.AttestationFormats) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AttestationFormats[iNdEx]) + copy(dAtA[i:], m.AttestationFormats[iNdEx]) + i = encodeVarintParams(dAtA, i, uint64(len(m.AttestationFormats[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if len(m.ConveyancePreference) > 0 { + i -= len(m.ConveyancePreference) + copy(dAtA[i:], m.ConveyancePreference) + i = encodeVarintParams(dAtA, i, uint64(len(m.ConveyancePreference))) + i-- + dAtA[i] = 0x1a + } + if len(m.AllowedPublicKeys) > 0 { + for k := range m.AllowedPublicKeys { + v := m.AllowedPublicKeys[k] + baseI := i + if v != nil { + { + size, err := v.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintParams(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintParams(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x12 + } + } + return len(dAtA) - i, nil +} + +func (m *KeyInfo) 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 *KeyInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *KeyInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Curve) > 0 { + i -= len(m.Curve) + copy(dAtA[i:], m.Curve) + i = encodeVarintParams(dAtA, i, uint64(len(m.Curve))) + i-- + dAtA[i] = 0x22 + } + if len(m.Encoding) > 0 { + i -= len(m.Encoding) + copy(dAtA[i:], m.Encoding) + i = encodeVarintParams(dAtA, i, uint64(len(m.Encoding))) + i-- + dAtA[i] = 0x1a + } + if len(m.Algorithm) > 0 { + i -= len(m.Algorithm) + copy(dAtA[i:], m.Algorithm) + i = encodeVarintParams(dAtA, i, uint64(len(m.Algorithm))) + i-- + dAtA[i] = 0x12 + } + if len(m.Role) > 0 { + i -= len(m.Role) + copy(dAtA[i:], m.Role) + i = encodeVarintParams(dAtA, i, uint64(len(m.Role))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.AllowedPublicKeys) > 0 { + for k, v := range m.AllowedPublicKeys { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovParams(uint64(l)) + } + mapEntrySize := 1 + len(k) + sovParams(uint64(len(k))) + l + n += mapEntrySize + 1 + sovParams(uint64(mapEntrySize)) + } + } + l = len(m.ConveyancePreference) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + if len(m.AttestationFormats) > 0 { + for _, s := range m.AttestationFormats { + l = len(s) + n += 1 + l + sovParams(uint64(l)) + } + } + return n +} + +func (m *KeyInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Role) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + l = len(m.Algorithm) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + l = len(m.Encoding) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + l = len(m.Curve) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) 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 ErrIntOverflowParams + } + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowedPublicKeys", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AllowedPublicKeys == nil { + m.AllowedPublicKeys = make(map[string]*KeyInfo) + } + var mapkey string + var mapvalue *KeyInfo + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthParams + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthParams + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthParams + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthParams + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &KeyInfo{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.AllowedPublicKeys[mapkey] = mapvalue + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConveyancePreference", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConveyancePreference = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AttestationFormats", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AttestationFormats = append(m.AttestationFormats, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KeyInfo) 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 ErrIntOverflowParams + } + 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: KeyInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KeyInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Role = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Algorithm", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Algorithm = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Encoding", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Encoding = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Curve", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Curve = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/did/types/pubkey/pubkey.go b/x/did/types/pubkey/pubkey.go deleted file mode 100644 index 2cfd2866e..000000000 --- a/x/did/types/pubkey/pubkey.go +++ /dev/null @@ -1,76 +0,0 @@ -package pubkey - -import ( - "strings" - - didv1 "github.com/onsonr/sonr/api/did/v1" -) - -type PubKeyI interface { - GetRole() string - GetKeyType() string - GetRawKey() *didv1.RawKey - GetJwk() *didv1.JSONWebKey -} - -// PubKey defines a generic pubkey. -type PublicKey interface { - VerifySignature(msg, sig []byte) bool -} - -type PubKeyG[T any] interface { - *T - PublicKey -} - -type pubKeyImpl struct { - decode func(b []byte) (PublicKey, error) - validate func(key PublicKey) error -} - -// func WithSecp256K1PubKey() Option { -// return WithPubKeyWithValidationFunc(func(pt *secp256k1.PubKey) error { -// _, err := dcrd_secp256k1.ParsePubKey(pt.Key) -// return err -// }) -// } -// -// func WithPubKey[T any, PT PubKeyG[T]]() Option { -// return WithPubKeyWithValidationFunc[T, PT](func(_ PT) error { -// return nil -// }) -// } -// -// func WithPubKeyWithValidationFunc[T any, PT PubKeyG[T]](validateFn func(PT) error) Option { -// pkImpl := pubKeyImpl{ -// decode: func(b []byte) (PublicKey, error) { -// key := PT(new(T)) -// err := gogoproto.Unmarshal(b, key) -// if err != nil { -// return nil, err -// } -// return key, nil -// }, -// validate: func(k PublicKey) error { -// concrete, ok := k.(PT) -// if !ok { -// return fmt.Errorf( -// "invalid pubkey type passed for validation, wanted: %T, got: %T", -// concrete, -// k, -// ) -// } -// return validateFn(concrete) -// }, -// } -// return func(a *Account) { -// a.supportedPubKeys[gogoproto.MessageName(PT(new(T)))] = pkImpl -// } -// } -func nameFromTypeURL(url string) string { - name := url - if i := strings.LastIndexByte(url, '/'); i >= 0 { - name = name[i+len("/"):] - } - return name -} diff --git a/x/did/types/query.pb.go b/x/did/types/query.pb.go index 8c2d96202..d9681537c 100644 --- a/x/did/types/query.pb.go +++ b/x/did/types/query.pb.go @@ -443,99 +443,6 @@ func (m *QueryVerifyResponse) GetValid() bool { return false } -// Document defines a DID document -type Document struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - Authentication []string `protobuf:"bytes,3,rep,name=authentication,proto3" json:"authentication,omitempty"` - AssertionMethod []string `protobuf:"bytes,4,rep,name=assertion_method,json=assertionMethod,proto3" json:"assertion_method,omitempty"` - CapabilityDelegation []string `protobuf:"bytes,5,rep,name=capability_delegation,json=capabilityDelegation,proto3" json:"capability_delegation,omitempty"` - CapabilityInvocation []string `protobuf:"bytes,6,rep,name=capability_invocation,json=capabilityInvocation,proto3" json:"capability_invocation,omitempty"` - Service []string `protobuf:"bytes,7,rep,name=service,proto3" json:"service,omitempty"` -} - -func (m *Document) Reset() { *m = Document{} } -func (m *Document) String() string { return proto.CompactTextString(m) } -func (*Document) ProtoMessage() {} -func (*Document) Descriptor() ([]byte, []int) { - return fileDescriptor_ae1fa9bb626e2869, []int{7} -} -func (m *Document) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Document) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Document.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 *Document) XXX_Merge(src proto.Message) { - xxx_messageInfo_Document.Merge(m, src) -} -func (m *Document) XXX_Size() int { - return m.Size() -} -func (m *Document) XXX_DiscardUnknown() { - xxx_messageInfo_Document.DiscardUnknown(m) -} - -var xxx_messageInfo_Document proto.InternalMessageInfo - -func (m *Document) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *Document) GetController() string { - if m != nil { - return m.Controller - } - return "" -} - -func (m *Document) GetAuthentication() []string { - if m != nil { - return m.Authentication - } - return nil -} - -func (m *Document) GetAssertionMethod() []string { - if m != nil { - return m.AssertionMethod - } - return nil -} - -func (m *Document) GetCapabilityDelegation() []string { - if m != nil { - return m.CapabilityDelegation - } - return nil -} - -func (m *Document) GetCapabilityInvocation() []string { - if m != nil { - return m.CapabilityInvocation - } - return nil -} - -func (m *Document) GetService() []string { - if m != nil { - return m.Service - } - return nil -} - func init() { proto.RegisterType((*QueryRequest)(nil), "did.v1.QueryRequest") proto.RegisterType((*QueryParamsResponse)(nil), "did.v1.QueryParamsResponse") @@ -544,53 +451,42 @@ func init() { proto.RegisterType((*QuerySignResponse)(nil), "did.v1.QuerySignResponse") proto.RegisterType((*QueryVerifyRequest)(nil), "did.v1.QueryVerifyRequest") proto.RegisterType((*QueryVerifyResponse)(nil), "did.v1.QueryVerifyResponse") - proto.RegisterType((*Document)(nil), "did.v1.Document") } func init() { proto.RegisterFile("did/v1/query.proto", fileDescriptor_ae1fa9bb626e2869) } var fileDescriptor_ae1fa9bb626e2869 = []byte{ - // 625 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0x41, 0x6f, 0xd3, 0x4c, - 0x10, 0x6d, 0x92, 0xc6, 0x6d, 0xe7, 0xfb, 0x48, 0xc3, 0xe2, 0x56, 0x26, 0x44, 0x56, 0xb5, 0x87, - 0xaa, 0x08, 0x14, 0xab, 0xed, 0x15, 0x2e, 0xa8, 0x17, 0x0e, 0x48, 0x90, 0x22, 0x90, 0xb8, 0x94, - 0x6d, 0x76, 0x70, 0x57, 0x75, 0x76, 0x53, 0xef, 0xc6, 0x22, 0x42, 0x70, 0xe0, 0x17, 0x80, 0xb8, - 0xf3, 0x7b, 0x38, 0x56, 0xe2, 0xc2, 0x11, 0xb5, 0x1c, 0xf9, 0x11, 0xc8, 0xeb, 0x75, 0x1a, 0x5b, - 0x70, 0x44, 0x5c, 0xa2, 0xcc, 0x9b, 0x99, 0xb7, 0x6f, 0x76, 0xdf, 0x18, 0x08, 0x17, 0x3c, 0xca, - 0x76, 0xa3, 0xb3, 0x29, 0xa6, 0xb3, 0xc1, 0x24, 0x55, 0x46, 0x11, 0x8f, 0x0b, 0x3e, 0xc8, 0x76, - 0x7b, 0xbe, 0xcb, 0xc5, 0x28, 0x51, 0x0b, 0x5d, 0x64, 0x7b, 0xfd, 0x58, 0xa9, 0x38, 0xc1, 0x88, - 0x4d, 0x44, 0xc4, 0xa4, 0x54, 0x86, 0x19, 0xa1, 0xa4, 0xcb, 0xd2, 0x97, 0xf0, 0xff, 0x93, 0x9c, - 0x6a, 0x88, 0x67, 0x53, 0xd4, 0x86, 0x74, 0xa1, 0xc5, 0x05, 0x0f, 0x1a, 0x5b, 0x8d, 0x9d, 0xb5, - 0x61, 0xfe, 0x97, 0x6c, 0x82, 0xa7, 0x52, 0x11, 0x0b, 0x19, 0x34, 0x2d, 0xe8, 0xa2, 0xbc, 0xf2, - 0x14, 0x67, 0x41, 0xab, 0xa8, 0x3c, 0xc5, 0x19, 0xf1, 0xa1, 0xcd, 0xb4, 0x46, 0x13, 0x2c, 0x5b, - 0xac, 0x08, 0xe8, 0x7d, 0xb8, 0x61, 0x4f, 0x78, 0xcc, 0x52, 0x36, 0xd6, 0x43, 0xd4, 0x13, 0x25, - 0x35, 0x92, 0x6d, 0xf0, 0x26, 0x16, 0xb1, 0x67, 0xfd, 0xb7, 0xd7, 0x19, 0x14, 0x53, 0x0c, 0x5c, - 0x9d, 0xcb, 0xd2, 0x03, 0xf0, 0x9d, 0x40, 0xad, 0x92, 0x0c, 0xe7, 0xfd, 0x77, 0x61, 0x95, 0xab, - 0xd1, 0x74, 0x8c, 0xd2, 0x38, 0x86, 0x6e, 0xc9, 0x70, 0xe0, 0xf0, 0xe1, 0xbc, 0x82, 0xbe, 0x83, - 0xae, 0x65, 0x39, 0x14, 0xb1, 0xfc, 0x6b, 0xa3, 0x92, 0x00, 0x56, 0xc6, 0xa8, 0x35, 0x8b, 0x31, - 0x68, 0x5b, 0xbc, 0x0c, 0xe9, 0x2e, 0x5c, 0x5f, 0x38, 0xdf, 0x8d, 0xd0, 0x87, 0x35, 0x2d, 0x62, - 0xc9, 0xcc, 0x34, 0x45, 0x27, 0xe3, 0x0a, 0xa0, 0x9f, 0x1b, 0x40, 0x6c, 0xcf, 0x33, 0x4c, 0xc5, - 0xab, 0xd9, 0x3f, 0x50, 0x5d, 0x15, 0xe8, 0xd5, 0x05, 0xde, 0x71, 0x0f, 0x5b, 0xea, 0x73, 0x53, - 0xf9, 0xd0, 0xce, 0x58, 0xe2, 0x24, 0xae, 0x0e, 0x8b, 0x80, 0x7e, 0x6c, 0xc2, 0x6a, 0xf9, 0x2e, - 0xa4, 0x03, 0xcd, 0xf9, 0x08, 0x4d, 0xc1, 0x49, 0x08, 0x30, 0x52, 0xd2, 0xa4, 0x2a, 0x49, 0x30, - 0x75, 0x53, 0x2c, 0x20, 0x64, 0x1b, 0x3a, 0x6c, 0x6a, 0x4e, 0x50, 0x1a, 0x31, 0xb2, 0xee, 0x0d, - 0x5a, 0x5b, 0xad, 0x9d, 0xb5, 0x61, 0x0d, 0x25, 0xb7, 0xa1, 0x9b, 0x8f, 0x94, 0xe6, 0xc1, 0xd1, - 0x18, 0xcd, 0x89, 0xe2, 0xc1, 0xb2, 0xad, 0x5c, 0x9f, 0xe3, 0x8f, 0x2c, 0x4c, 0xf6, 0x61, 0x63, - 0xc4, 0x26, 0xec, 0x58, 0x24, 0xc2, 0xcc, 0x8e, 0x38, 0x26, 0x18, 0x17, 0xcc, 0x6d, 0x5b, 0xef, - 0x5f, 0x25, 0x0f, 0xe6, 0xb9, 0x5a, 0x93, 0x90, 0x99, 0x72, 0x72, 0xbc, 0x7a, 0xd3, 0xc3, 0x79, - 0x2e, 0xbf, 0x5e, 0x8d, 0x69, 0x26, 0x46, 0x18, 0xac, 0xd8, 0xb2, 0x32, 0xdc, 0xfb, 0xd9, 0x84, - 0xb6, 0xbd, 0x41, 0x72, 0x08, 0x5e, 0x61, 0x7b, 0xe2, 0x97, 0x26, 0x5e, 0xdc, 0xca, 0xde, 0xad, - 0x0a, 0x5a, 0xdd, 0x24, 0xba, 0xf9, 0xfe, 0xeb, 0x8f, 0x4f, 0xcd, 0x2e, 0xe9, 0x44, 0x6e, 0xff, - 0x8b, 0xcd, 0x21, 0x4f, 0x61, 0xc5, 0x2d, 0xcd, 0x1f, 0x58, 0xfb, 0x35, 0xb4, 0xb2, 0x60, 0x74, - 0xc3, 0xd2, 0xae, 0x93, 0x6b, 0x25, 0xed, 0x1b, 0x2e, 0xf8, 0x5b, 0xf2, 0x1c, 0x96, 0x73, 0x13, - 0x93, 0xa0, 0xd2, 0xbc, 0xb0, 0x57, 0xbd, 0x9b, 0xbf, 0xc9, 0x38, 0xce, 0x9e, 0xe5, 0xf4, 0x29, - 0xa9, 0x70, 0x46, 0xb9, 0xa7, 0xc8, 0x11, 0x78, 0x85, 0x93, 0x48, 0xaf, 0x42, 0x50, 0xb1, 0x7f, - 0xed, 0x26, 0xaa, 0xd6, 0xa3, 0x7d, 0x4b, 0xbf, 0x49, 0xfd, 0x2a, 0x7d, 0x66, 0xab, 0x1e, 0xdc, - 0xfb, 0x72, 0x11, 0x36, 0xce, 0x2f, 0xc2, 0xc6, 0xf7, 0x8b, 0xb0, 0xf1, 0xe1, 0x32, 0x5c, 0x3a, - 0xbf, 0x0c, 0x97, 0xbe, 0x5d, 0x86, 0x4b, 0x2f, 0x68, 0x2c, 0xcc, 0xc9, 0xf4, 0x78, 0x30, 0x52, - 0xe3, 0x48, 0x49, 0xad, 0x64, 0x1a, 0xd9, 0x9f, 0xd7, 0x96, 0xc7, 0xcc, 0x26, 0xa8, 0x8f, 0x3d, - 0xfb, 0xbd, 0xdc, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, 0xb9, 0xc1, 0x21, 0x0f, 0x81, 0x05, 0x00, - 0x00, + // 478 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x53, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0x8d, 0x53, 0xe2, 0xb6, 0x03, 0x94, 0xb0, 0x35, 0x91, 0x15, 0x22, 0x0b, 0xed, 0x01, 0x21, + 0x81, 0x6c, 0xa5, 0x5c, 0xe1, 0x82, 0xfa, 0x01, 0xe0, 0x22, 0x0e, 0x5c, 0xc0, 0xed, 0x0e, 0x66, + 0xd5, 0x64, 0xd7, 0xf5, 0xae, 0x2d, 0x2c, 0x04, 0x07, 0xbe, 0x00, 0xa9, 0x77, 0xbe, 0x87, 0x63, + 0x25, 0x2e, 0x1c, 0x51, 0xc2, 0x87, 0xa0, 0xac, 0xd7, 0x25, 0x1b, 0x89, 0x23, 0xea, 0xc5, 0xf2, + 0xbc, 0x79, 0xf3, 0xe6, 0x8d, 0x67, 0x0c, 0x84, 0x71, 0x96, 0xd4, 0xd3, 0xe4, 0xac, 0xc2, 0xb2, + 0x89, 0x8b, 0x52, 0x6a, 0x49, 0x7c, 0xc6, 0x59, 0x5c, 0x4f, 0xc7, 0x81, 0xcd, 0xe5, 0x28, 0x50, + 0x71, 0xd5, 0x66, 0xc7, 0xfb, 0x16, 0x2d, 0xb2, 0x32, 0x9b, 0x77, 0xe0, 0x24, 0x97, 0x32, 0x9f, + 0x61, 0x92, 0x15, 0x3c, 0xc9, 0x84, 0x90, 0x3a, 0xd3, 0x5c, 0x0a, 0x9b, 0xa5, 0x6f, 0xe1, 0xc6, + 0x8b, 0x95, 0x7e, 0x8a, 0x67, 0x15, 0x2a, 0x4d, 0x86, 0xb0, 0xc5, 0x38, 0x0b, 0xbd, 0x7b, 0xde, + 0x83, 0xdd, 0x74, 0xf5, 0x4a, 0x46, 0xe0, 0xcb, 0x92, 0xe7, 0x5c, 0x84, 0x7d, 0x03, 0xda, 0x68, + 0xc5, 0x3c, 0xc5, 0x26, 0xdc, 0x6a, 0x99, 0xa7, 0xd8, 0x90, 0x00, 0x06, 0x99, 0x52, 0xa8, 0xc3, + 0x6b, 0x06, 0x6b, 0x03, 0xfa, 0x14, 0xf6, 0x4d, 0x87, 0xe7, 0xc6, 0x54, 0x8a, 0xaa, 0x90, 0x42, + 0x21, 0xb9, 0x0f, 0x7e, 0x6b, 0xd3, 0xf4, 0xba, 0x7e, 0xb0, 0x17, 0xb7, 0xa3, 0xc5, 0x96, 0x67, + 0xb3, 0xf4, 0x10, 0x02, 0x6b, 0x50, 0xc9, 0x59, 0x8d, 0x97, 0xf5, 0x8f, 0x60, 0x87, 0xc9, 0x93, + 0x6a, 0x8e, 0x42, 0x5b, 0x85, 0x61, 0xa7, 0x70, 0x68, 0xf1, 0xf4, 0x92, 0x41, 0x3f, 0xc3, 0xd0, + 0xa8, 0x1c, 0xf1, 0x5c, 0xfc, 0xb7, 0x51, 0x49, 0x08, 0xdb, 0x73, 0x54, 0x2a, 0xcb, 0x31, 0x1c, + 0x18, 0xbc, 0x0b, 0xe9, 0x14, 0x6e, 0xaf, 0xf5, 0xb7, 0x23, 0x4c, 0x60, 0x57, 0xf1, 0x5c, 0x64, + 0xba, 0x2a, 0xd1, 0xda, 0xf8, 0x0b, 0xd0, 0x6f, 0x1e, 0x10, 0x53, 0xf3, 0x0a, 0x4b, 0xfe, 0xae, + 0xb9, 0x02, 0xd7, 0xae, 0x41, 0x7f, 0xd3, 0xe0, 0x43, 0xbb, 0xd8, 0xce, 0x9f, 0x9d, 0x2a, 0x80, + 0x41, 0x9d, 0xcd, 0xac, 0xc5, 0x9d, 0xb4, 0x0d, 0x0e, 0xce, 0xfb, 0x30, 0x30, 0x6c, 0x72, 0x04, + 0x7e, 0xbb, 0x62, 0x12, 0x74, 0x0b, 0x5b, 0xbf, 0xc0, 0xf1, 0x5d, 0x07, 0x75, 0xaf, 0x86, 0x8e, + 0xbe, 0xfc, 0xf8, 0x7d, 0xde, 0x1f, 0x92, 0xbd, 0xc4, 0x39, 0x75, 0xf2, 0x12, 0xb6, 0xed, 0x81, + 0xfc, 0x43, 0x75, 0xb2, 0x81, 0x3a, 0xc7, 0x44, 0xef, 0x18, 0xd9, 0x5b, 0xe4, 0x66, 0x27, 0xfb, + 0x91, 0x71, 0xf6, 0x89, 0xbc, 0x01, 0xbf, 0x1d, 0x8e, 0x8c, 0x9d, 0x72, 0x67, 0x23, 0x1b, 0x86, + 0xdd, 0xaf, 0x41, 0x27, 0x46, 0x79, 0x44, 0x03, 0x47, 0x39, 0xa9, 0x0d, 0xeb, 0xd9, 0x93, 0xef, + 0x8b, 0xc8, 0xbb, 0x58, 0x44, 0xde, 0xaf, 0x45, 0xe4, 0x7d, 0x5d, 0x46, 0xbd, 0x8b, 0x65, 0xd4, + 0xfb, 0xb9, 0x8c, 0x7a, 0xaf, 0x69, 0xce, 0xf5, 0xfb, 0xea, 0x38, 0x3e, 0x91, 0xf3, 0x44, 0x0a, + 0x25, 0x45, 0x99, 0x98, 0xc7, 0x07, 0xa3, 0xa3, 0x9b, 0x02, 0xd5, 0xb1, 0x6f, 0x7e, 0xe1, 0xc7, + 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x63, 0xf5, 0x0e, 0x9a, 0x29, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -609,8 +505,6 @@ type QueryClient interface { Params(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) // Resolve queries the DID document by its id. Resolve(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryResolveResponse, error) - // Sign signs a message with the DID document - Sign(ctx context.Context, in *QuerySignRequest, opts ...grpc.CallOption) (*QuerySignResponse, error) // Verify verifies a message with the DID document Verify(ctx context.Context, in *QueryVerifyRequest, opts ...grpc.CallOption) (*QueryVerifyResponse, error) } @@ -641,15 +535,6 @@ func (c *queryClient) Resolve(ctx context.Context, in *QueryRequest, opts ...grp return out, nil } -func (c *queryClient) Sign(ctx context.Context, in *QuerySignRequest, opts ...grpc.CallOption) (*QuerySignResponse, error) { - out := new(QuerySignResponse) - err := c.cc.Invoke(ctx, "/did.v1.Query/Sign", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *queryClient) Verify(ctx context.Context, in *QueryVerifyRequest, opts ...grpc.CallOption) (*QueryVerifyResponse, error) { out := new(QueryVerifyResponse) err := c.cc.Invoke(ctx, "/did.v1.Query/Verify", in, out, opts...) @@ -665,8 +550,6 @@ type QueryServer interface { Params(context.Context, *QueryRequest) (*QueryParamsResponse, error) // Resolve queries the DID document by its id. Resolve(context.Context, *QueryRequest) (*QueryResolveResponse, error) - // Sign signs a message with the DID document - Sign(context.Context, *QuerySignRequest) (*QuerySignResponse, error) // Verify verifies a message with the DID document Verify(context.Context, *QueryVerifyRequest) (*QueryVerifyResponse, error) } @@ -681,9 +564,6 @@ func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryRequest) func (*UnimplementedQueryServer) Resolve(ctx context.Context, req *QueryRequest) (*QueryResolveResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Resolve not implemented") } -func (*UnimplementedQueryServer) Sign(ctx context.Context, req *QuerySignRequest) (*QuerySignResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Sign not implemented") -} func (*UnimplementedQueryServer) Verify(ctx context.Context, req *QueryVerifyRequest) (*QueryVerifyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Verify not implemented") } @@ -728,24 +608,6 @@ func _Query_Resolve_Handler(srv interface{}, ctx context.Context, dec func(inter return interceptor(ctx, in, info, handler) } -func _Query_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QuerySignRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Sign(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/did.v1.Query/Sign", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Sign(ctx, req.(*QuerySignRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _Query_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryVerifyRequest) if err := dec(in); err != nil { @@ -777,10 +639,6 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Resolve", Handler: _Query_Resolve_Handler, }, - { - MethodName: "Sign", - Handler: _Query_Sign_Handler, - }, { MethodName: "Verify", Handler: _Query_Verify_Handler, @@ -1097,88 +955,6 @@ func (m *QueryVerifyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *Document) 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 *Document) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Document) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Service) > 0 { - for iNdEx := len(m.Service) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Service[iNdEx]) - copy(dAtA[i:], m.Service[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Service[iNdEx]))) - i-- - dAtA[i] = 0x3a - } - } - if len(m.CapabilityInvocation) > 0 { - for iNdEx := len(m.CapabilityInvocation) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.CapabilityInvocation[iNdEx]) - copy(dAtA[i:], m.CapabilityInvocation[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.CapabilityInvocation[iNdEx]))) - i-- - dAtA[i] = 0x32 - } - } - if len(m.CapabilityDelegation) > 0 { - for iNdEx := len(m.CapabilityDelegation) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.CapabilityDelegation[iNdEx]) - copy(dAtA[i:], m.CapabilityDelegation[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.CapabilityDelegation[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } - if len(m.AssertionMethod) > 0 { - for iNdEx := len(m.AssertionMethod) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AssertionMethod[iNdEx]) - copy(dAtA[i:], m.AssertionMethod[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.AssertionMethod[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } - if len(m.Authentication) > 0 { - for iNdEx := len(m.Authentication) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Authentication[iNdEx]) - copy(dAtA[i:], m.Authentication[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Authentication[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.Controller) > 0 { - i -= len(m.Controller) - copy(dAtA[i:], m.Controller) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Controller))) - i-- - dAtA[i] = 0x12 - } - if len(m.Id) > 0 { - i -= len(m.Id) - copy(dAtA[i:], m.Id) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Id))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -1328,53 +1104,6 @@ func (m *QueryVerifyResponse) Size() (n int) { return n } -func (m *Document) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Id) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - l = len(m.Controller) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if len(m.Authentication) > 0 { - for _, s := range m.Authentication { - l = len(s) - n += 1 + l + sovQuery(uint64(l)) - } - } - if len(m.AssertionMethod) > 0 { - for _, s := range m.AssertionMethod { - l = len(s) - n += 1 + l + sovQuery(uint64(l)) - } - } - if len(m.CapabilityDelegation) > 0 { - for _, s := range m.CapabilityDelegation { - l = len(s) - n += 1 + l + sovQuery(uint64(l)) - } - } - if len(m.CapabilityInvocation) > 0 { - for _, s := range m.CapabilityInvocation { - l = len(s) - n += 1 + l + sovQuery(uint64(l)) - } - } - if len(m.Service) > 0 { - for _, s := range m.Service { - l = len(s) - n += 1 + l + sovQuery(uint64(l)) - } - } - return n -} - func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2335,280 +2064,6 @@ func (m *QueryVerifyResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *Document) 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 ErrIntOverflowQuery - } - 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: Document: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Document: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Authentication", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Authentication = append(m.Authentication, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AssertionMethod", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AssertionMethod = append(m.AssertionMethod, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CapabilityDelegation", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CapabilityDelegation = append(m.CapabilityDelegation, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CapabilityInvocation", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CapabilityInvocation = append(m.CapabilityInvocation, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Service = append(m.Service, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/did/types/query.pb.gw.go b/x/did/types/query.pb.gw.go index b43c6c14d..7a30f0396 100644 --- a/x/did/types/query.pb.gw.go +++ b/x/did/types/query.pb.gw.go @@ -141,78 +141,6 @@ func local_request_Query_Resolve_0(ctx context.Context, marshaler runtime.Marsha } -var ( - filter_Query_Sign_0 = &utilities.DoubleArray{Encoding: map[string]int{"did": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} -) - -func request_Query_Sign_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QuerySignRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["did"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "did") - } - - protoReq.Did, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "did", err) - } - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Sign_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.Sign(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_Sign_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QuerySignRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["did"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "did") - } - - protoReq.Did, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "did", err) - } - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Sign_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.Sign(ctx, &protoReq) - return msg, metadata, err - -} - var ( filter_Query_Verify_0 = &utilities.DoubleArray{Encoding: map[string]int{"did": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) @@ -337,29 +265,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("POST", pattern_Query_Sign_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_Sign_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Sign_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - mux.Handle("POST", pattern_Query_Verify_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -464,26 +369,6 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("POST", pattern_Query_Sign_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_Sign_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Sign_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - mux.Handle("POST", pattern_Query_Verify_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -512,8 +397,6 @@ var ( pattern_Query_Resolve_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 0}, []string{"did", "v1"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Sign_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 0, 2, 2}, []string{"did", "v1", "sign"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Verify_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 0, 2, 2}, []string{"did", "v1", "verify"}, "", runtime.AssumeColonVerbOpt(false))) ) @@ -522,7 +405,5 @@ var ( forward_Query_Resolve_0 = runtime.ForwardResponseMessage - forward_Query_Sign_0 = runtime.ForwardResponseMessage - forward_Query_Verify_0 = runtime.ForwardResponseMessage ) diff --git a/x/did/types/state.pb.go b/x/did/types/state.pb.go index a28a0d272..5699701fa 100644 --- a/x/did/types/state.pb.go +++ b/x/did/types/state.pb.go @@ -30,8 +30,8 @@ type Assertion struct { Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` // Origin of the authentication Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - // PubKey is the verification method - PublicKey *PubKey `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // string is the verification method + PublicKeyHex string `protobuf:"bytes,4,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` // AssertionType is the assertion type AssertionType string `protobuf:"bytes,5,opt,name=assertion_type,json=assertionType,proto3" json:"assertion_type,omitempty"` // Metadata of the authentication @@ -94,11 +94,11 @@ func (m *Assertion) GetSubject() string { return "" } -func (m *Assertion) GetPublicKey() *PubKey { +func (m *Assertion) GetPublicKeyHex() string { if m != nil { - return m.PublicKey + return m.PublicKeyHex } - return nil + return "" } func (m *Assertion) GetAssertionType() string { @@ -129,8 +129,8 @@ type Authentication struct { Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` // Origin of the authentication Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - // PubKey is the verification method - PublicKey *PubKey `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // string is the verification method + PublicKeyHex string `protobuf:"bytes,4,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` // CredentialID is the byte representation of the credential ID CredentialId []byte `protobuf:"bytes,5,opt,name=credential_id,json=credentialId,proto3" json:"credential_id,omitempty"` // Metadata of the authentication @@ -193,11 +193,11 @@ func (m *Authentication) GetSubject() string { return "" } -func (m *Authentication) GetPublicKey() *PubKey { +func (m *Authentication) GetPublicKeyHex() string { if m != nil { - return m.PublicKey + return m.PublicKeyHex } - return nil + return "" } func (m *Authentication) GetCredentialId() []byte { @@ -221,6 +221,91 @@ func (m *Authentication) GetCreationBlock() int64 { return 0 } +// Macaroon is a Macaroon message type. +type Biscuit struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` + Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` + Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` + ExpiryHeight int64 `protobuf:"varint,5,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` + Macaroon string `protobuf:"bytes,6,opt,name=macaroon,proto3" json:"macaroon,omitempty"` +} + +func (m *Biscuit) Reset() { *m = Biscuit{} } +func (m *Biscuit) String() string { return proto.CompactTextString(m) } +func (*Biscuit) ProtoMessage() {} +func (*Biscuit) Descriptor() ([]byte, []int) { + return fileDescriptor_f44bb702879c34b4, []int{2} +} +func (m *Biscuit) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Biscuit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Biscuit.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 *Biscuit) XXX_Merge(src proto.Message) { + xxx_messageInfo_Biscuit.Merge(m, src) +} +func (m *Biscuit) XXX_Size() int { + return m.Size() +} +func (m *Biscuit) XXX_DiscardUnknown() { + xxx_messageInfo_Biscuit.DiscardUnknown(m) +} + +var xxx_messageInfo_Biscuit proto.InternalMessageInfo + +func (m *Biscuit) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Biscuit) GetController() string { + if m != nil { + return m.Controller + } + return "" +} + +func (m *Biscuit) GetSubject() string { + if m != nil { + return m.Subject + } + return "" +} + +func (m *Biscuit) GetOrigin() string { + if m != nil { + return m.Origin + } + return "" +} + +func (m *Biscuit) GetExpiryHeight() int64 { + if m != nil { + return m.ExpiryHeight + } + return 0 +} + +func (m *Biscuit) GetMacaroon() string { + if m != nil { + return m.Macaroon + } + return "" +} + // Controller represents a Sonr DWN Vault type Controller struct { // The unique identifier of the controller @@ -233,8 +318,8 @@ type Controller struct { EthAddress string `protobuf:"bytes,4,opt,name=eth_address,json=ethAddress,proto3" json:"eth_address,omitempty"` // The DID of the controller BtcAddress string `protobuf:"bytes,5,opt,name=btc_address,json=btcAddress,proto3" json:"btc_address,omitempty"` - // PubKey is the verification method - PublicKey *PubKey `protobuf:"bytes,6,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // string is the verification method + PublicKeyHex string `protobuf:"bytes,6,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` // Pointer to the Keyshares KsVal string `protobuf:"bytes,7,opt,name=ks_val,json=ksVal,proto3" json:"ks_val,omitempty"` // The block number of when a user claimed the controller @@ -247,7 +332,7 @@ func (m *Controller) Reset() { *m = Controller{} } func (m *Controller) String() string { return proto.CompactTextString(m) } func (*Controller) ProtoMessage() {} func (*Controller) Descriptor() ([]byte, []int) { - return fileDescriptor_f44bb702879c34b4, []int{2} + return fileDescriptor_f44bb702879c34b4, []int{3} } func (m *Controller) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -311,11 +396,11 @@ func (m *Controller) GetBtcAddress() string { return "" } -func (m *Controller) GetPublicKey() *PubKey { +func (m *Controller) GetPublicKeyHex() string { if m != nil { - return m.PublicKey + return m.PublicKeyHex } - return nil + return "" } func (m *Controller) GetKsVal() string { @@ -339,168 +424,6 @@ func (m *Controller) GetCreationBlock() int64 { return 0 } -// Grant is a Grant message type. -type Grant struct { - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` - ExpiryHeight int64 `protobuf:"varint,5,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` -} - -func (m *Grant) Reset() { *m = Grant{} } -func (m *Grant) String() string { return proto.CompactTextString(m) } -func (*Grant) ProtoMessage() {} -func (*Grant) Descriptor() ([]byte, []int) { - return fileDescriptor_f44bb702879c34b4, []int{3} -} -func (m *Grant) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Grant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Grant.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 *Grant) XXX_Merge(src proto.Message) { - xxx_messageInfo_Grant.Merge(m, src) -} -func (m *Grant) XXX_Size() int { - return m.Size() -} -func (m *Grant) XXX_DiscardUnknown() { - xxx_messageInfo_Grant.DiscardUnknown(m) -} - -var xxx_messageInfo_Grant proto.InternalMessageInfo - -func (m *Grant) GetId() uint64 { - if m != nil { - return m.Id - } - return 0 -} - -func (m *Grant) GetController() string { - if m != nil { - return m.Controller - } - return "" -} - -func (m *Grant) GetSubject() string { - if m != nil { - return m.Subject - } - return "" -} - -func (m *Grant) GetOrigin() string { - if m != nil { - return m.Origin - } - return "" -} - -func (m *Grant) GetExpiryHeight() int64 { - if m != nil { - return m.ExpiryHeight - } - return 0 -} - -// Macaroon is a Macaroon message type. -type Macaroon struct { - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` - ExpiryHeight int64 `protobuf:"varint,5,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` - Macaroon string `protobuf:"bytes,6,opt,name=macaroon,proto3" json:"macaroon,omitempty"` -} - -func (m *Macaroon) Reset() { *m = Macaroon{} } -func (m *Macaroon) String() string { return proto.CompactTextString(m) } -func (*Macaroon) ProtoMessage() {} -func (*Macaroon) Descriptor() ([]byte, []int) { - return fileDescriptor_f44bb702879c34b4, []int{4} -} -func (m *Macaroon) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Macaroon) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Macaroon.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 *Macaroon) XXX_Merge(src proto.Message) { - xxx_messageInfo_Macaroon.Merge(m, src) -} -func (m *Macaroon) XXX_Size() int { - return m.Size() -} -func (m *Macaroon) XXX_DiscardUnknown() { - xxx_messageInfo_Macaroon.DiscardUnknown(m) -} - -var xxx_messageInfo_Macaroon proto.InternalMessageInfo - -func (m *Macaroon) GetId() uint64 { - if m != nil { - return m.Id - } - return 0 -} - -func (m *Macaroon) GetController() string { - if m != nil { - return m.Controller - } - return "" -} - -func (m *Macaroon) GetSubject() string { - if m != nil { - return m.Subject - } - return "" -} - -func (m *Macaroon) GetOrigin() string { - if m != nil { - return m.Origin - } - return "" -} - -func (m *Macaroon) GetExpiryHeight() int64 { - if m != nil { - return m.ExpiryHeight - } - return 0 -} - -func (m *Macaroon) GetMacaroon() string { - if m != nil { - return m.Macaroon - } - return "" -} - // Verification represents a verification method type Verification struct { // The unique identifier of the verification @@ -514,7 +437,7 @@ type Verification struct { // The subject of the verification Subject string `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"` // The public key of the verification - PublicKey *PubKey `protobuf:"bytes,6,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + PublicKeyHex string `protobuf:"bytes,6,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` // The verification method type VerificationType string `protobuf:"bytes,7,opt,name=verification_type,json=verificationType,proto3" json:"verification_type,omitempty"` // Metadata of the verification @@ -527,7 +450,7 @@ func (m *Verification) Reset() { *m = Verification{} } func (m *Verification) String() string { return proto.CompactTextString(m) } func (*Verification) ProtoMessage() {} func (*Verification) Descriptor() ([]byte, []int) { - return fileDescriptor_f44bb702879c34b4, []int{5} + return fileDescriptor_f44bb702879c34b4, []int{4} } func (m *Verification) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -591,11 +514,11 @@ func (m *Verification) GetSubject() string { return "" } -func (m *Verification) GetPublicKey() *PubKey { +func (m *Verification) GetPublicKeyHex() string { if m != nil { - return m.PublicKey + return m.PublicKeyHex } - return nil + return "" } func (m *Verification) GetVerificationType() string { @@ -624,9 +547,8 @@ func init() { proto.RegisterMapType((map[string][]byte)(nil), "did.v1.Assertion.AccumulatorEntry") proto.RegisterType((*Authentication)(nil), "did.v1.Authentication") proto.RegisterMapType((map[string]string)(nil), "did.v1.Authentication.MetadataEntry") + proto.RegisterType((*Biscuit)(nil), "did.v1.Biscuit") proto.RegisterType((*Controller)(nil), "did.v1.Controller") - proto.RegisterType((*Grant)(nil), "did.v1.Grant") - proto.RegisterType((*Macaroon)(nil), "did.v1.Macaroon") proto.RegisterType((*Verification)(nil), "did.v1.Verification") proto.RegisterMapType((map[string]string)(nil), "did.v1.Verification.MetadataEntry") } @@ -634,61 +556,59 @@ func init() { func init() { proto.RegisterFile("did/v1/state.proto", fileDescriptor_f44bb702879c34b4) } var fileDescriptor_f44bb702879c34b4 = []byte{ - // 849 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x96, 0x61, 0x8b, 0xe3, 0x44, - 0x18, 0xc7, 0x77, 0x9a, 0x36, 0xd7, 0x3c, 0xed, 0x96, 0xdc, 0xb0, 0x9e, 0x61, 0xd1, 0x5a, 0x73, - 0x7a, 0xac, 0xb8, 0xb6, 0xdc, 0xf9, 0x46, 0x56, 0x39, 0xdc, 0x53, 0x51, 0x39, 0x16, 0x24, 0xca, - 0x81, 0xbe, 0x29, 0x93, 0xcc, 0xd8, 0x8e, 0x4d, 0x32, 0x75, 0x32, 0x29, 0xd7, 0x97, 0x82, 0x82, - 0xaf, 0xc4, 0x4f, 0xe0, 0xc7, 0xf0, 0x33, 0xf8, 0xf2, 0x40, 0x04, 0x5f, 0xca, 0xee, 0x37, 0xf0, - 0x13, 0xc8, 0xcc, 0x24, 0x6d, 0xaa, 0x87, 0x7b, 0xae, 0x82, 0xf7, 0xa6, 0x74, 0xfe, 0x79, 0xf2, - 0xe4, 0x79, 0x7e, 0xff, 0xcc, 0x33, 0x01, 0x4c, 0x39, 0x9d, 0xac, 0x6e, 0x4f, 0x0a, 0x45, 0x14, - 0x1b, 0x2f, 0xa5, 0x50, 0x02, 0xbb, 0x94, 0xd3, 0xf1, 0xea, 0xf6, 0xe1, 0xb3, 0x89, 0x28, 0x32, - 0x51, 0x4c, 0x84, 0xcc, 0x74, 0x88, 0x90, 0x99, 0x0d, 0x38, 0x3c, 0xa8, 0x6e, 0x9a, 0xb1, 0x9c, - 0x15, 0xbc, 0xb0, 0x6a, 0xf8, 0x8d, 0x03, 0xde, 0x69, 0x51, 0x30, 0xa9, 0xb8, 0xc8, 0xb1, 0x0f, - 0x0e, 0xe5, 0x34, 0x40, 0x23, 0x74, 0xe4, 0x45, 0xfa, 0x2f, 0x1e, 0x02, 0x24, 0x22, 0x57, 0x52, - 0xa4, 0x29, 0x93, 0x41, 0xcb, 0x5c, 0x68, 0x28, 0x38, 0x80, 0x6b, 0x45, 0x19, 0x7f, 0xc1, 0x12, - 0x15, 0x38, 0xe6, 0x62, 0xbd, 0xc4, 0xaf, 0x01, 0x2c, 0xcb, 0x38, 0xe5, 0xc9, 0x74, 0xc1, 0xd6, - 0x41, 0x7b, 0x84, 0x8e, 0x7a, 0x77, 0x06, 0x63, 0x5b, 0xe5, 0xf8, 0xa3, 0x32, 0xbe, 0xcf, 0xd6, - 0x91, 0x67, 0x23, 0xee, 0xb3, 0x35, 0x7e, 0x19, 0x06, 0xa4, 0xae, 0x63, 0xaa, 0xd6, 0x4b, 0x16, - 0x74, 0x4c, 0xbe, 0xfd, 0x8d, 0xfa, 0xc9, 0x7a, 0xc9, 0xf0, 0xbb, 0xd0, 0x23, 0x49, 0x52, 0x66, - 0x65, 0x4a, 0x94, 0x90, 0x81, 0x3b, 0x72, 0x8e, 0x7a, 0x77, 0xc2, 0x3a, 0xed, 0xa6, 0x93, 0xf1, - 0xe9, 0x36, 0xe8, 0xbd, 0x5c, 0xc9, 0x75, 0xd4, 0xbc, 0x4d, 0x3f, 0x2c, 0x91, 0x8c, 0x98, 0x67, - 0xc5, 0xa9, 0x48, 0x16, 0xc1, 0xb5, 0x11, 0x3a, 0x72, 0xa2, 0xfd, 0x5a, 0xbd, 0xa7, 0xc5, 0xc3, - 0xbb, 0xe0, 0xff, 0x39, 0x8f, 0x46, 0xa4, 0xfb, 0xa9, 0x10, 0x2d, 0xd8, 0x1a, 0x1f, 0x40, 0x67, - 0x45, 0xd2, 0x92, 0x19, 0x3a, 0xfd, 0xc8, 0x2e, 0x4e, 0x5a, 0x6f, 0xa0, 0x93, 0x57, 0x7e, 0xff, - 0xe1, 0xe7, 0xef, 0x9c, 0x9b, 0xd0, 0x31, 0x58, 0x71, 0x00, 0x78, 0x4b, 0xee, 0xb8, 0xe2, 0xe4, - 0xa3, 0x00, 0x05, 0x28, 0xfc, 0xca, 0x81, 0xc1, 0x69, 0xa9, 0xe6, 0x2c, 0x57, 0x3c, 0x21, 0xff, - 0xb7, 0x19, 0x37, 0x41, 0x93, 0xa0, 0xba, 0x18, 0x92, 0x4e, 0x39, 0x35, 0x5e, 0xf4, 0xa3, 0xfe, - 0x56, 0xfc, 0x90, 0xe2, 0xb7, 0xa1, 0x9b, 0x31, 0x45, 0x28, 0x51, 0xa4, 0xf2, 0xe1, 0xa5, 0x8d, - 0x0f, 0x3b, 0x9d, 0x8c, 0xcf, 0xaa, 0x30, 0xeb, 0xc4, 0xe6, 0xae, 0x27, 0xb5, 0xe1, 0x4d, 0xd8, - 0xdf, 0xc9, 0x70, 0x99, 0x07, 0xde, 0x95, 0x3c, 0x68, 0x85, 0xdf, 0x3a, 0x00, 0xef, 0x6c, 0x69, - 0xde, 0x00, 0x37, 0x2f, 0xb3, 0x98, 0x49, 0xf3, 0xa0, 0x76, 0x54, 0xad, 0x6a, 0x5f, 0x5a, 0x5b, - 0x5f, 0x5e, 0x84, 0x7e, 0x21, 0x72, 0x39, 0x25, 0x94, 0x4a, 0x56, 0x14, 0x15, 0xfc, 0x9e, 0xd6, - 0x4e, 0xad, 0x84, 0x5f, 0x80, 0x1e, 0x53, 0xf3, 0x4d, 0x44, 0xdb, 0x7a, 0xc7, 0xd4, 0xbc, 0x11, - 0x10, 0xab, 0x64, 0x13, 0x60, 0x5f, 0x7e, 0x88, 0x55, 0x52, 0x07, 0xec, 0x5a, 0xe8, 0x5e, 0x66, - 0xe1, 0x33, 0xe0, 0x2e, 0x8a, 0xe9, 0x8a, 0xa4, 0x86, 0xa9, 0x17, 0x75, 0x16, 0xc5, 0x03, 0x92, - 0x1a, 0x67, 0x53, 0xc2, 0x33, 0x46, 0x2b, 0xe2, 0x5d, 0x43, 0xbc, 0x5f, 0x89, 0x06, 0xf8, 0x63, - 0x7c, 0xf1, 0x1e, 0xe3, 0xcb, 0xc9, 0xa7, 0x06, 0xed, 0xc7, 0x00, 0x35, 0x28, 0x1f, 0x61, 0xbc, - 0x8b, 0x42, 0x93, 0xc5, 0xd7, 0x77, 0x7a, 0xf7, 0x5b, 0x56, 0x6a, 0x74, 0xeb, 0x3b, 0x01, 0xc2, - 0x9e, 0xc1, 0xea, 0xb7, 0x03, 0x14, 0x38, 0xe1, 0x8f, 0x08, 0x3a, 0xef, 0x4b, 0x92, 0x2b, 0x3c, - 0x80, 0x56, 0xb5, 0x09, 0xda, 0x51, 0xeb, 0x5f, 0xed, 0x81, 0x1b, 0xe0, 0x0a, 0xc9, 0x67, 0x3c, - 0xaf, 0xe8, 0x57, 0x2b, 0x8d, 0x84, 0x3d, 0x5c, 0x72, 0xb9, 0x9e, 0xce, 0x19, 0x9f, 0xcd, 0x95, - 0x61, 0xef, 0x44, 0x7d, 0x2b, 0x7e, 0x60, 0xb4, 0x93, 0x5b, 0xa6, 0xd7, 0x11, 0xb8, 0xba, 0x1c, - 0x1f, 0xe1, 0x03, 0x18, 0x54, 0x79, 0x8f, 0x6d, 0x1a, 0xf3, 0x0e, 0xb5, 0xc3, 0x5f, 0x10, 0x74, - 0xcf, 0x48, 0x42, 0xa4, 0x10, 0xf9, 0x53, 0x52, 0x3b, 0x3e, 0x84, 0x6e, 0x56, 0x95, 0x64, 0xde, - 0x1b, 0x2f, 0xda, 0xac, 0x9f, 0xb0, 0xaf, 0x4e, 0xf8, 0x75, 0x1b, 0xfa, 0x0f, 0x98, 0xe4, 0x9f, - 0x5f, 0x7d, 0x3a, 0x3d, 0x0f, 0x40, 0x39, 0x9d, 0x66, 0x4c, 0xcd, 0x05, 0xad, 0x1a, 0xf4, 0x28, - 0xa7, 0x67, 0x46, 0xd0, 0x2d, 0xf2, 0xa2, 0x28, 0x99, 0xac, 0x5b, 0xb4, 0xab, 0x26, 0x94, 0xce, - 0xdf, 0x0d, 0xb5, 0x4b, 0x77, 0xc4, 0xab, 0x70, 0x7d, 0xd5, 0xe8, 0xc0, 0x1e, 0x32, 0x76, 0x73, - 0xf8, 0xcd, 0x0b, 0xe6, 0x9c, 0xb9, 0xdb, 0x18, 0x6e, 0xdd, 0xdd, 0x43, 0xa6, 0x89, 0xe1, 0x1f, - 0x8c, 0x36, 0xef, 0x3f, 0x1f, 0x6d, 0x5f, 0x1a, 0xef, 0x16, 0xf5, 0x68, 0x3b, 0x80, 0x81, 0x45, - 0xd6, 0x1c, 0x6b, 0x38, 0x84, 0xe7, 0x1a, 0x03, 0x6f, 0x6b, 0xc0, 0xb1, 0x8d, 0x35, 0xbb, 0xf1, - 0x16, 0x8c, 0xfe, 0x42, 0xa6, 0x4e, 0x52, 0xc7, 0x39, 0x01, 0x0a, 0xdc, 0x7b, 0x6f, 0xfd, 0x74, - 0x3e, 0x44, 0x8f, 0xce, 0x87, 0xe8, 0xb7, 0xf3, 0x21, 0xfa, 0xfe, 0x62, 0xb8, 0xf7, 0xe8, 0x62, - 0xb8, 0xf7, 0xeb, 0xc5, 0x70, 0xef, 0xb3, 0x70, 0xc6, 0xd5, 0xbc, 0x8c, 0xc7, 0x89, 0xc8, 0x26, - 0x22, 0xd7, 0x33, 0x60, 0x62, 0x7e, 0x1e, 0x4e, 0xf4, 0x77, 0x87, 0xce, 0x58, 0xc4, 0xae, 0xf9, - 0xe6, 0x78, 0xfd, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xac, 0xdb, 0xa3, 0xc0, 0x08, 0x00, - 0x00, + // 821 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x95, 0xdf, 0x8a, 0x23, 0x45, + 0x14, 0xc6, 0xa7, 0xba, 0x27, 0x3d, 0x93, 0x33, 0x99, 0xd0, 0x5b, 0x8c, 0x6b, 0x31, 0x68, 0x8c, + 0xd9, 0x75, 0x19, 0x71, 0x48, 0x58, 0xbd, 0x91, 0x51, 0x16, 0x67, 0x54, 0x58, 0x91, 0xbd, 0x89, + 0xb2, 0xa0, 0x37, 0xa1, 0xba, 0xab, 0x9c, 0x94, 0xe9, 0xee, 0x8a, 0x55, 0xd5, 0x61, 0xf2, 0x12, + 0xe2, 0x13, 0xf8, 0x3c, 0x5e, 0x2e, 0xe8, 0x85, 0x97, 0x32, 0xf3, 0x06, 0x5e, 0x09, 0x0a, 0x4a, + 0x55, 0x75, 0x27, 0x1d, 0x37, 0xb0, 0xba, 0x0a, 0x7b, 0x13, 0x72, 0xbe, 0x3e, 0xf5, 0xe7, 0xfc, + 0xce, 0xd7, 0xa7, 0x01, 0x33, 0xc1, 0x46, 0x8b, 0xfb, 0x23, 0x6d, 0xa8, 0xe1, 0xc3, 0xb9, 0x92, + 0x46, 0xe2, 0x88, 0x09, 0x36, 0x5c, 0xdc, 0x3f, 0x7e, 0x39, 0x95, 0x3a, 0x97, 0x7a, 0x24, 0x55, + 0x6e, 0x53, 0xa4, 0xca, 0x7d, 0xc2, 0xf1, 0x51, 0xb5, 0xe8, 0x92, 0x17, 0x5c, 0x0b, 0xed, 0xd5, + 0xc1, 0x1f, 0x01, 0xb4, 0xcf, 0xb5, 0xe6, 0xca, 0x08, 0x59, 0xe0, 0x18, 0x42, 0x26, 0x18, 0x41, + 0x7d, 0x74, 0xd2, 0x1e, 0xdb, 0xbf, 0xb8, 0x07, 0x90, 0xca, 0xc2, 0x28, 0x99, 0x65, 0x5c, 0x91, + 0xc0, 0x3d, 0x68, 0x28, 0x98, 0xc0, 0x9e, 0x2e, 0x93, 0xaf, 0x79, 0x6a, 0x48, 0xe8, 0x1e, 0xd6, + 0x21, 0xbe, 0x0b, 0xdd, 0x79, 0x99, 0x64, 0x22, 0x9d, 0xcc, 0xf8, 0x72, 0x32, 0xe5, 0x57, 0x64, + 0xd7, 0x25, 0x74, 0xbc, 0xfa, 0x29, 0x5f, 0x3e, 0xe4, 0x57, 0xf8, 0x0d, 0xe8, 0xd2, 0xfa, 0xf8, + 0x89, 0x59, 0xce, 0x39, 0x69, 0xb9, 0xac, 0xc3, 0x95, 0xfa, 0xf9, 0x72, 0xce, 0xf1, 0x47, 0x70, + 0x40, 0xd3, 0xb4, 0xcc, 0xcb, 0x8c, 0x1a, 0xa9, 0x48, 0xd4, 0x0f, 0x4f, 0x0e, 0xde, 0x1e, 0x0c, + 0x7d, 0xcd, 0xc3, 0x55, 0x01, 0xc3, 0xf3, 0x75, 0xd2, 0xc7, 0x85, 0x51, 0xcb, 0x71, 0x73, 0x99, + 0x3d, 0x2c, 0x55, 0x9c, 0xba, 0xb3, 0x92, 0x4c, 0xa6, 0x33, 0xb2, 0xd7, 0x47, 0x27, 0xe1, 0xf8, + 0xb0, 0x56, 0x2f, 0xac, 0x78, 0xfc, 0x00, 0xe2, 0xbf, 0xef, 0x63, 0xc9, 0xcc, 0xf8, 0xb2, 0x26, + 0x33, 0xe3, 0x4b, 0x7c, 0x04, 0xad, 0x05, 0xcd, 0x4a, 0xee, 0xa0, 0x74, 0xc6, 0x3e, 0x38, 0x0b, + 0xde, 0x45, 0x67, 0x6f, 0xfe, 0xfa, 0xfd, 0x8f, 0xdf, 0x86, 0x77, 0xa0, 0xe5, 0x68, 0x62, 0x02, + 0x78, 0x0d, 0xec, 0xb4, 0xc2, 0x13, 0x23, 0x82, 0x08, 0x1a, 0xfc, 0x16, 0x40, 0xf7, 0xbc, 0x34, + 0x53, 0x5e, 0x18, 0x91, 0xd2, 0x17, 0xd4, 0x83, 0x3b, 0x60, 0x01, 0x30, 0x7b, 0x07, 0x9a, 0x4d, + 0x04, 0x73, 0x2d, 0xe8, 0x8c, 0x3b, 0x6b, 0xf1, 0x13, 0x86, 0x3f, 0x80, 0xfd, 0x9c, 0x1b, 0xca, + 0xa8, 0xa1, 0x15, 0xfe, 0xbb, 0x2b, 0xfc, 0x1b, 0x05, 0x0c, 0x1f, 0x55, 0x69, 0xbe, 0x01, 0xab, + 0x55, 0xff, 0x94, 0xfe, 0x7b, 0x70, 0xb8, 0xb1, 0xc3, 0xb3, 0xd0, 0xb7, 0x9f, 0x0b, 0x7d, 0x30, + 0xf8, 0x09, 0xc1, 0xde, 0x85, 0xd0, 0x69, 0x29, 0x0c, 0xee, 0x42, 0x50, 0x21, 0xdf, 0x1d, 0x07, + 0xff, 0x89, 0xf8, 0x6d, 0x88, 0xa4, 0x12, 0x97, 0xa2, 0xa8, 0x48, 0x57, 0x91, 0x65, 0xcc, 0xaf, + 0xe6, 0x42, 0xd9, 0x2e, 0x88, 0xcb, 0xa9, 0x71, 0x8c, 0xc3, 0x71, 0xc7, 0x8b, 0x0f, 0x9d, 0x86, + 0x8f, 0x61, 0x3f, 0xa7, 0x29, 0x55, 0x52, 0x16, 0x24, 0x72, 0xcb, 0x57, 0xf1, 0xd9, 0x3d, 0x57, + 0x59, 0x1f, 0x22, 0x7b, 0xd5, 0x18, 0xe1, 0x23, 0xe8, 0x56, 0x67, 0x9e, 0xfa, 0x23, 0x5c, 0x59, + 0xad, 0xc1, 0x9f, 0x01, 0xc0, 0x87, 0xeb, 0x9b, 0xde, 0x86, 0xa8, 0x28, 0xf3, 0x84, 0xab, 0xaa, + 0xba, 0x2a, 0xaa, 0x5d, 0x16, 0xac, 0x5d, 0xf6, 0x3a, 0x74, 0xb4, 0x2c, 0xd4, 0x84, 0x32, 0xa6, + 0xb8, 0xd6, 0x55, 0x61, 0x07, 0x56, 0x3b, 0xf7, 0x12, 0x7e, 0x0d, 0x0e, 0xb8, 0x99, 0xae, 0x32, + 0x7c, 0x85, 0xc0, 0xcd, 0xb4, 0x91, 0x90, 0x98, 0x74, 0x95, 0xe0, 0x5f, 0x65, 0x48, 0x4c, 0x5a, + 0x27, 0x3c, 0x6d, 0xc8, 0x68, 0x8b, 0x21, 0x5f, 0x82, 0x68, 0xa6, 0x27, 0x0b, 0x9a, 0x39, 0x87, + 0xb4, 0xc7, 0xad, 0x99, 0x7e, 0x4c, 0x33, 0xe7, 0xd3, 0x8c, 0x8a, 0x9c, 0xb3, 0xca, 0x3f, 0xfb, + 0x9e, 0x61, 0x25, 0x3a, 0xfb, 0x6c, 0x71, 0x59, 0x7b, 0x8b, 0xcb, 0xce, 0xbe, 0x70, 0x38, 0x3f, + 0x03, 0xa8, 0xf9, 0xc4, 0x08, 0xe3, 0x4d, 0x02, 0x16, 0x28, 0xbe, 0xb5, 0x51, 0x72, 0x1c, 0x78, + 0xa9, 0x51, 0x64, 0x1c, 0x12, 0x84, 0xdb, 0x8e, 0x66, 0xbc, 0x4b, 0x10, 0x09, 0x07, 0xbf, 0x87, + 0xd0, 0x79, 0xcc, 0x95, 0xf8, 0xea, 0xf9, 0xdf, 0xe8, 0x57, 0x01, 0x98, 0x60, 0x93, 0x9c, 0x9b, + 0xa9, 0x64, 0x55, 0x27, 0xda, 0x4c, 0xb0, 0x47, 0x4e, 0xb0, 0x4d, 0x15, 0x5a, 0x97, 0x5c, 0xd5, + 0x26, 0xf3, 0x51, 0xd3, 0x96, 0xad, 0x67, 0x0d, 0x82, 0x6d, 0xdc, 0xdf, 0x82, 0x5b, 0x8b, 0xc6, + 0xc5, 0xfd, 0x3c, 0xf6, 0x2d, 0x88, 0x9b, 0x0f, 0xdc, 0x48, 0x7e, 0xd0, 0x18, 0x08, 0xfb, 0x9b, + 0xf3, 0xb8, 0x59, 0xfd, 0xbf, 0x18, 0x07, 0xed, 0xff, 0x7d, 0x1c, 0x7c, 0xe3, 0xba, 0x3c, 0xab, + 0xc7, 0xc1, 0x11, 0x74, 0x3d, 0xa9, 0xe6, 0x28, 0xc0, 0x03, 0x78, 0xa5, 0x31, 0x24, 0xd6, 0xdc, + 0x4f, 0x7d, 0xae, 0xeb, 0xf9, 0x3d, 0xe8, 0x3f, 0x45, 0xa6, 0xde, 0xa4, 0xce, 0x0b, 0x09, 0x22, + 0xd1, 0xc5, 0xfb, 0x3f, 0x5c, 0xf7, 0xd0, 0x93, 0xeb, 0x1e, 0xfa, 0xe5, 0xba, 0x87, 0xbe, 0xbb, + 0xe9, 0xed, 0x3c, 0xb9, 0xe9, 0xed, 0xfc, 0x7c, 0xd3, 0xdb, 0xf9, 0x72, 0x70, 0x29, 0xcc, 0xb4, + 0x4c, 0x86, 0xa9, 0xcc, 0x47, 0xb2, 0xb0, 0x4e, 0x1b, 0xb9, 0x9f, 0xab, 0x91, 0xfd, 0x32, 0xdb, + 0x1d, 0x75, 0x12, 0xb9, 0xaf, 0xf2, 0x3b, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xce, 0xd1, 0x02, + 0x2a, 0xe2, 0x07, 0x00, 0x00, } func (m *Assertion) Marshal() (dAtA []byte, err error) { @@ -744,15 +664,10 @@ func (m *Assertion) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x2a } - if m.PublicKey != nil { - { - size, err := m.PublicKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintState(dAtA, i, uint64(size)) - } + if len(m.PublicKeyHex) > 0 { + i -= len(m.PublicKeyHex) + copy(dAtA[i:], m.PublicKeyHex) + i = encodeVarintState(dAtA, i, uint64(len(m.PublicKeyHex))) i-- dAtA[i] = 0x22 } @@ -831,15 +746,10 @@ func (m *Authentication) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x2a } - if m.PublicKey != nil { - { - size, err := m.PublicKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintState(dAtA, i, uint64(size)) - } + if len(m.PublicKeyHex) > 0 { + i -= len(m.PublicKeyHex) + copy(dAtA[i:], m.PublicKeyHex) + i = encodeVarintState(dAtA, i, uint64(len(m.PublicKeyHex))) i-- dAtA[i] = 0x22 } @@ -867,6 +777,67 @@ func (m *Authentication) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Biscuit) 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 *Biscuit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Biscuit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Macaroon) > 0 { + i -= len(m.Macaroon) + copy(dAtA[i:], m.Macaroon) + i = encodeVarintState(dAtA, i, uint64(len(m.Macaroon))) + i-- + dAtA[i] = 0x32 + } + if m.ExpiryHeight != 0 { + i = encodeVarintState(dAtA, i, uint64(m.ExpiryHeight)) + i-- + dAtA[i] = 0x28 + } + if len(m.Origin) > 0 { + i -= len(m.Origin) + copy(dAtA[i:], m.Origin) + i = encodeVarintState(dAtA, i, uint64(len(m.Origin))) + i-- + dAtA[i] = 0x22 + } + if len(m.Subject) > 0 { + i -= len(m.Subject) + copy(dAtA[i:], m.Subject) + i = encodeVarintState(dAtA, i, uint64(len(m.Subject))) + i-- + dAtA[i] = 0x1a + } + if len(m.Controller) > 0 { + i -= len(m.Controller) + copy(dAtA[i:], m.Controller) + i = encodeVarintState(dAtA, i, uint64(len(m.Controller))) + i-- + dAtA[i] = 0x12 + } + if m.Id != 0 { + i = encodeVarintState(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *Controller) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -904,15 +875,10 @@ func (m *Controller) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x3a } - if m.PublicKey != nil { - { - size, err := m.PublicKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintState(dAtA, i, uint64(size)) - } + if len(m.PublicKeyHex) > 0 { + i -= len(m.PublicKeyHex) + copy(dAtA[i:], m.PublicKeyHex) + i = encodeVarintState(dAtA, i, uint64(len(m.PublicKeyHex))) i-- dAtA[i] = 0x32 } @@ -952,121 +918,6 @@ func (m *Controller) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *Grant) 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 *Grant) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Grant) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ExpiryHeight != 0 { - i = encodeVarintState(dAtA, i, uint64(m.ExpiryHeight)) - i-- - dAtA[i] = 0x28 - } - if len(m.Origin) > 0 { - i -= len(m.Origin) - copy(dAtA[i:], m.Origin) - i = encodeVarintState(dAtA, i, uint64(len(m.Origin))) - i-- - dAtA[i] = 0x22 - } - if len(m.Subject) > 0 { - i -= len(m.Subject) - copy(dAtA[i:], m.Subject) - i = encodeVarintState(dAtA, i, uint64(len(m.Subject))) - i-- - dAtA[i] = 0x1a - } - if len(m.Controller) > 0 { - i -= len(m.Controller) - copy(dAtA[i:], m.Controller) - i = encodeVarintState(dAtA, i, uint64(len(m.Controller))) - i-- - dAtA[i] = 0x12 - } - if m.Id != 0 { - i = encodeVarintState(dAtA, i, uint64(m.Id)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *Macaroon) 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 *Macaroon) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Macaroon) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Macaroon) > 0 { - i -= len(m.Macaroon) - copy(dAtA[i:], m.Macaroon) - i = encodeVarintState(dAtA, i, uint64(len(m.Macaroon))) - i-- - dAtA[i] = 0x32 - } - if m.ExpiryHeight != 0 { - i = encodeVarintState(dAtA, i, uint64(m.ExpiryHeight)) - i-- - dAtA[i] = 0x28 - } - if len(m.Origin) > 0 { - i -= len(m.Origin) - copy(dAtA[i:], m.Origin) - i = encodeVarintState(dAtA, i, uint64(len(m.Origin))) - i-- - dAtA[i] = 0x22 - } - if len(m.Subject) > 0 { - i -= len(m.Subject) - copy(dAtA[i:], m.Subject) - i = encodeVarintState(dAtA, i, uint64(len(m.Subject))) - i-- - dAtA[i] = 0x1a - } - if len(m.Controller) > 0 { - i -= len(m.Controller) - copy(dAtA[i:], m.Controller) - i = encodeVarintState(dAtA, i, uint64(len(m.Controller))) - i-- - dAtA[i] = 0x12 - } - if m.Id != 0 { - i = encodeVarintState(dAtA, i, uint64(m.Id)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - func (m *Verification) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1118,15 +969,10 @@ func (m *Verification) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x3a } - if m.PublicKey != nil { - { - size, err := m.PublicKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintState(dAtA, i, uint64(size)) - } + if len(m.PublicKeyHex) > 0 { + i -= len(m.PublicKeyHex) + copy(dAtA[i:], m.PublicKeyHex) + i = encodeVarintState(dAtA, i, uint64(len(m.PublicKeyHex))) i-- dAtA[i] = 0x32 } @@ -1197,8 +1043,8 @@ func (m *Assertion) Size() (n int) { if l > 0 { n += 1 + l + sovState(uint64(l)) } - if m.PublicKey != nil { - l = m.PublicKey.Size() + l = len(m.PublicKeyHex) + if l > 0 { n += 1 + l + sovState(uint64(l)) } l = len(m.AssertionType) @@ -1241,8 +1087,8 @@ func (m *Authentication) Size() (n int) { if l > 0 { n += 1 + l + sovState(uint64(l)) } - if m.PublicKey != nil { - l = m.PublicKey.Size() + l = len(m.PublicKeyHex) + if l > 0 { n += 1 + l + sovState(uint64(l)) } l = len(m.CredentialId) @@ -1263,76 +1109,7 @@ func (m *Authentication) Size() (n int) { return n } -func (m *Controller) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Number != 0 { - n += 1 + sovState(uint64(m.Number)) - } - l = len(m.Did) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.SonrAddress) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.EthAddress) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.BtcAddress) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - if m.PublicKey != nil { - l = m.PublicKey.Size() - n += 1 + l + sovState(uint64(l)) - } - l = len(m.KsVal) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - if m.ClaimedBlock != 0 { - n += 1 + sovState(uint64(m.ClaimedBlock)) - } - if m.CreationBlock != 0 { - n += 1 + sovState(uint64(m.CreationBlock)) - } - return n -} - -func (m *Grant) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Id != 0 { - n += 1 + sovState(uint64(m.Id)) - } - l = len(m.Controller) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.Subject) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.Origin) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - if m.ExpiryHeight != 0 { - n += 1 + sovState(uint64(m.ExpiryHeight)) - } - return n -} - -func (m *Macaroon) Size() (n int) { +func (m *Biscuit) Size() (n int) { if m == nil { return 0 } @@ -1363,6 +1140,48 @@ func (m *Macaroon) Size() (n int) { return n } +func (m *Controller) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Number != 0 { + n += 1 + sovState(uint64(m.Number)) + } + l = len(m.Did) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + l = len(m.SonrAddress) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + l = len(m.EthAddress) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + l = len(m.BtcAddress) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + l = len(m.PublicKeyHex) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + l = len(m.KsVal) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + if m.ClaimedBlock != 0 { + n += 1 + sovState(uint64(m.ClaimedBlock)) + } + if m.CreationBlock != 0 { + n += 1 + sovState(uint64(m.CreationBlock)) + } + return n +} + func (m *Verification) Size() (n int) { if m == nil { return 0 @@ -1389,8 +1208,8 @@ func (m *Verification) Size() (n int) { if l > 0 { n += 1 + l + sovState(uint64(l)) } - if m.PublicKey != nil { - l = m.PublicKey.Size() + l = len(m.PublicKeyHex) + if l > 0 { n += 1 + l + sovState(uint64(l)) } l = len(m.VerificationType) @@ -1544,9 +1363,9 @@ func (m *Assertion) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowState @@ -1556,27 +1375,23 @@ func (m *Assertion) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthState } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthState } if postIndex > l { return io.ErrUnexpectedEOF } - if m.PublicKey == nil { - m.PublicKey = &PubKey{} - } - if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.PublicKeyHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { @@ -1905,9 +1720,9 @@ func (m *Authentication) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowState @@ -1917,27 +1732,23 @@ func (m *Authentication) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthState } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthState } if postIndex > l { return io.ErrUnexpectedEOF } - if m.PublicKey == nil { - m.PublicKey = &PubKey{} - } - if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.PublicKeyHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { @@ -2140,6 +1951,222 @@ func (m *Authentication) Unmarshal(dAtA []byte) error { } return nil } +func (m *Biscuit) 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 ErrIntOverflowState + } + 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: Biscuit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Biscuit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + 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 ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Controller = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + 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 ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subject = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + 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 ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Origin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) + } + m.ExpiryHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExpiryHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Macaroon", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + 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 ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Macaroon = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipState(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Controller) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -2318,9 +2345,9 @@ func (m *Controller) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowState @@ -2330,27 +2357,23 @@ func (m *Controller) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthState } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthState } if postIndex > l { return io.ErrUnexpectedEOF } - if m.PublicKey == nil { - m.PublicKey = &PubKey{} - } - if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.PublicKeyHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 2 { @@ -2443,406 +2466,6 @@ func (m *Controller) Unmarshal(dAtA []byte) error { } return nil } -func (m *Grant) 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 ErrIntOverflowState - } - 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: Grant: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Grant: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - m.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) - } - m.ExpiryHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ExpiryHeight |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipState(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthState - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Macaroon) 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 ErrIntOverflowState - } - 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: Macaroon: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Macaroon: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - m.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) - } - m.ExpiryHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ExpiryHeight |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Macaroon", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Macaroon = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipState(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthState - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *Verification) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -3034,9 +2657,9 @@ func (m *Verification) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowState @@ -3046,27 +2669,23 @@ func (m *Verification) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthState } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthState } if postIndex > l { return io.ErrUnexpectedEOF } - if m.PublicKey == nil { - m.PublicKey = &PubKey{} - } - if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.PublicKeyHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 2 { diff --git a/x/did/types/tx.pb.go b/x/did/types/tx.pb.go index 3e25a3a4f..c1d6c5817 100644 --- a/x/did/types/tx.pb.go +++ b/x/did/types/tx.pb.go @@ -783,55 +783,56 @@ func init() { func init() { proto.RegisterFile("did/v1/tx.proto", fileDescriptor_d73284df019ff211) } var fileDescriptor_d73284df019ff211 = []byte{ - // 767 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x4e, 0xdb, 0x4c, - 0x14, 0xcd, 0x10, 0x08, 0xe4, 0x92, 0x10, 0xbe, 0x51, 0x3e, 0xc5, 0x58, 0x90, 0x44, 0x46, 0xa8, - 0x08, 0x95, 0x44, 0x50, 0xa9, 0x42, 0xb4, 0x6a, 0x05, 0x2a, 0x15, 0x88, 0x46, 0x6a, 0x5d, 0xba, - 0x61, 0x93, 0x1a, 0x7b, 0xe4, 0xb8, 0x24, 0x9e, 0xc8, 0x33, 0x41, 0xc9, 0xae, 0xea, 0x13, 0xf4, - 0x05, 0xfa, 0x04, 0xdd, 0xb0, 0xe8, 0xaa, 0xea, 0x03, 0xb0, 0x44, 0x5d, 0x75, 0x55, 0x55, 0x20, - 0x95, 0x27, 0xe8, 0xb2, 0x52, 0x35, 0x76, 0xe2, 0xd8, 0xf9, 0x29, 0x08, 0x50, 0x37, 0x91, 0xef, - 0x3d, 0xf7, 0x9e, 0x39, 0xf7, 0x78, 0x66, 0x62, 0x48, 0x19, 0x96, 0x51, 0x3c, 0x5a, 0x29, 0xf2, - 0x66, 0xa1, 0xee, 0x50, 0x4e, 0x71, 0xcc, 0xb0, 0x8c, 0xc2, 0xd1, 0x8a, 0x9c, 0xd1, 0x29, 0xab, - 0x51, 0x56, 0xac, 0x31, 0x53, 0xe0, 0x35, 0x66, 0x7a, 0x05, 0xf2, 0x8c, 0x07, 0x94, 0xdd, 0xa8, - 0xe8, 0x05, 0x6d, 0x28, 0xdd, 0x26, 0x33, 0x89, 0x4d, 0x98, 0xe5, 0x67, 0x4d, 0x6a, 0x52, 0xaf, - 0x5a, 0x3c, 0x79, 0x59, 0xe5, 0x27, 0x82, 0xff, 0x4b, 0xcc, 0x7c, 0x66, 0xd9, 0x87, 0x1b, 0x0d, - 0x5e, 0x21, 0x36, 0xb7, 0x74, 0x8d, 0x5b, 0xd4, 0xc6, 0x6b, 0x00, 0x3a, 0xb5, 0xb9, 0x43, 0xab, - 0x55, 0xe2, 0x48, 0x28, 0x8f, 0x16, 0xe3, 0x9b, 0xd2, 0xd7, 0x4f, 0xcb, 0xe9, 0xf6, 0x5a, 0x1b, - 0x86, 0xe1, 0x10, 0xc6, 0x5e, 0x72, 0xc7, 0xb2, 0x4d, 0x35, 0x50, 0x8b, 0x25, 0x18, 0x67, 0x8d, - 0x83, 0x37, 0x44, 0xe7, 0xd2, 0x88, 0x68, 0x53, 0x3b, 0x21, 0x9e, 0x85, 0xb8, 0xc6, 0x18, 0x71, - 0xc4, 0x02, 0x52, 0xd4, 0xc5, 0xba, 0x09, 0x3c, 0x0f, 0x49, 0xdd, 0x21, 0x86, 0xd0, 0xa0, 0x55, - 0xcb, 0x96, 0x21, 0x8d, 0xe6, 0xd1, 0x62, 0x42, 0x4d, 0x74, 0x93, 0x3b, 0x06, 0x5e, 0x80, 0xa9, - 0x9a, 0xa6, 0x6b, 0x0e, 0xa5, 0x76, 0x99, 0xd3, 0x43, 0x62, 0x4b, 0x63, 0x2e, 0x4f, 0xb2, 0x93, - 0xdd, 0x13, 0xc9, 0xf5, 0xd4, 0xbb, 0x8b, 0xe3, 0xa5, 0x80, 0x28, 0x65, 0x17, 0xe6, 0x06, 0xce, - 0xa9, 0x12, 0x56, 0xa7, 0x36, 0x23, 0x9e, 0x6a, 0x5d, 0x27, 0x8c, 0xb9, 0xc3, 0x4e, 0xa8, 0x9d, - 0x10, 0x4f, 0x43, 0xd4, 0xb0, 0x8c, 0xf6, 0x2c, 0xe2, 0x51, 0xf9, 0x82, 0x60, 0xba, 0xc3, 0xe6, - 0xcb, 0xff, 0xf7, 0x86, 0xf5, 0x7b, 0x31, 0x7a, 0x25, 0x2f, 0x9e, 0x82, 0xd4, 0xab, 0xfe, 0x5a, - 0x36, 0xfc, 0x46, 0x90, 0x28, 0x31, 0x73, 0xab, 0x49, 0xf4, 0x06, 0x27, 0x7b, 0xcd, 0x1b, 0x58, - 0xf0, 0x08, 0x26, 0x6a, 0x84, 0x31, 0xcd, 0x24, 0x4c, 0x1a, 0xc9, 0x47, 0x17, 0x27, 0x57, 0x95, - 0x82, 0x77, 0x04, 0x0a, 0xc1, 0x15, 0x0a, 0xa5, 0x76, 0xd1, 0x96, 0xcd, 0x9d, 0x96, 0xea, 0xf7, - 0x0c, 0xb0, 0x22, 0x3a, 0xc0, 0x0a, 0xf9, 0x01, 0x24, 0x43, 0x0c, 0x62, 0xa8, 0x43, 0xd2, 0xf2, - 0xa4, 0xaa, 0xe2, 0x11, 0xa7, 0x61, 0xec, 0x48, 0xab, 0x36, 0x88, 0x3b, 0x68, 0x42, 0xf5, 0x82, - 0xf5, 0x91, 0x35, 0xd4, 0xef, 0xe3, 0x0e, 0xa4, 0x83, 0xe2, 0xae, 0xe0, 0x61, 0x06, 0xc6, 0x79, - 0xb3, 0x5c, 0xd1, 0x58, 0xa5, 0xed, 0x63, 0x8c, 0x37, 0xb7, 0x35, 0x56, 0x51, 0x3e, 0x22, 0xc0, - 0x25, 0x66, 0xbe, 0xb2, 0xab, 0xb7, 0xb4, 0xa7, 0xe6, 0x21, 0xe9, 0x6f, 0x94, 0x72, 0xf7, 0xbd, - 0x25, 0xfc, 0xe4, 0x13, 0xcb, 0xb8, 0xa2, 0x6b, 0xfd, 0x83, 0x6f, 0x83, 0xdc, 0x2f, 0xf6, 0x5a, - 0x5b, 0xe8, 0x33, 0x82, 0x4c, 0x97, 0xea, 0xb6, 0x6e, 0xa0, 0x65, 0xc0, 0x5a, 0x88, 0x2b, 0xe0, - 0xc0, 0x7f, 0x61, 0xe4, 0x26, 0x36, 0x94, 0x20, 0x37, 0x44, 0xfb, 0xb5, 0xbc, 0xf8, 0x80, 0x20, - 0x25, 0xf8, 0xea, 0x86, 0xc6, 0xc9, 0x73, 0xcd, 0xd1, 0x6a, 0x0c, 0xdf, 0x87, 0xb8, 0xd0, 0x4b, - 0x1d, 0x8b, 0xb7, 0x2e, 0xb5, 0xa0, 0x5b, 0x8a, 0xef, 0x42, 0xac, 0xee, 0x32, 0xb8, 0x0b, 0x4c, - 0xae, 0x4e, 0x75, 0x4e, 0x93, 0xc7, 0xbb, 0x39, 0x7a, 0xf2, 0x3d, 0x17, 0x51, 0xdb, 0x35, 0x62, - 0xcf, 0x07, 0xe7, 0xf6, 0x82, 0xf5, 0x29, 0x31, 0x6f, 0x97, 0x53, 0x99, 0xf1, 0x5e, 0x55, 0x40, - 0x5e, 0x67, 0xcc, 0xd5, 0x5f, 0x51, 0x88, 0x96, 0x98, 0x89, 0x1f, 0x43, 0xbc, 0x7b, 0x1b, 0xa4, - 0x07, 0x9d, 0x60, 0x79, 0x76, 0x50, 0xd6, 0xf7, 0x6b, 0x17, 0x92, 0xe1, 0x5b, 0x55, 0x0a, 0x94, - 0x87, 0x10, 0x39, 0x3f, 0x0c, 0xf1, 0xc9, 0xf6, 0x01, 0x0f, 0xf8, 0x63, 0x9b, 0xeb, 0xed, 0x0b, - 0xc1, 0xf2, 0xc2, 0x5f, 0x61, 0x9f, 0xfb, 0x05, 0xa4, 0x7a, 0x0f, 0xab, 0x1c, 0xe8, 0xec, 0xc1, - 0x64, 0x65, 0x38, 0xe6, 0x53, 0xbe, 0x86, 0xf4, 0xc0, 0x73, 0x90, 0xeb, 0xef, 0x0d, 0x4b, 0xbe, - 0x73, 0x49, 0x81, 0xbf, 0xc2, 0x36, 0x24, 0x42, 0xbb, 0x2b, 0x13, 0x6c, 0x0c, 0x00, 0x72, 0x6e, - 0x08, 0xd0, 0x61, 0x92, 0xc7, 0xde, 0x5e, 0x1c, 0x2f, 0xa1, 0xcd, 0x87, 0x27, 0x67, 0x59, 0x74, - 0x7a, 0x96, 0x45, 0x3f, 0xce, 0xb2, 0xe8, 0xfd, 0x79, 0x36, 0x72, 0x7a, 0x9e, 0x8d, 0x7c, 0x3b, - 0xcf, 0x46, 0xf6, 0x15, 0xd3, 0xe2, 0x95, 0xc6, 0x41, 0x41, 0xa7, 0xb5, 0x22, 0xb5, 0x19, 0xb5, - 0x9d, 0xa2, 0xfb, 0xd3, 0x2c, 0x8a, 0xaf, 0x13, 0xde, 0xaa, 0x13, 0x76, 0x10, 0x73, 0xbf, 0x41, - 0xee, 0xfd, 0x09, 0x00, 0x00, 0xff, 0xff, 0x93, 0x06, 0x64, 0x08, 0xfe, 0x08, 0x00, 0x00, + // 775 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x4e, 0xdb, 0x4a, + 0x14, 0x8e, 0x09, 0x04, 0x72, 0x48, 0x08, 0x77, 0x6e, 0xae, 0x62, 0x2c, 0x48, 0x22, 0x23, 0x74, + 0x11, 0x2a, 0x89, 0xa0, 0x52, 0x85, 0x68, 0xd5, 0x0a, 0x54, 0x2a, 0x10, 0x8d, 0xd4, 0xba, 0x74, + 0xc3, 0x26, 0x35, 0xf6, 0xc8, 0x71, 0x49, 0x3c, 0x91, 0x67, 0x82, 0x92, 0x5d, 0xd5, 0x27, 0xe8, + 0x0b, 0xf4, 0x09, 0xba, 0x61, 0xd1, 0x55, 0xd5, 0x07, 0x60, 0x89, 0xba, 0xea, 0xaa, 0xaa, 0x40, + 0x2a, 0x4f, 0xd0, 0x65, 0xa5, 0x6a, 0xfc, 0x17, 0x3b, 0x3f, 0x05, 0x01, 0xea, 0x26, 0xf2, 0x39, + 0xdf, 0x39, 0xdf, 0x7c, 0xe7, 0xf3, 0xcc, 0xc4, 0x90, 0xd1, 0x4d, 0xbd, 0x7c, 0xb4, 0x52, 0x66, + 0xed, 0x52, 0xd3, 0x26, 0x8c, 0xa0, 0x84, 0x6e, 0xea, 0xa5, 0xa3, 0x15, 0x29, 0xa7, 0x11, 0xda, + 0x20, 0xb4, 0xdc, 0xa0, 0x06, 0xc7, 0x1b, 0xd4, 0x70, 0x0b, 0xa4, 0x19, 0x17, 0xa8, 0x3a, 0x51, + 0xd9, 0x0d, 0x3c, 0x28, 0xeb, 0x91, 0x19, 0xd8, 0xc2, 0xd4, 0xf4, 0xb3, 0xff, 0x7a, 0xd9, 0xa6, + 0x6a, 0xab, 0x8d, 0xa0, 0xd4, 0x20, 0x06, 0x71, 0x29, 0xf8, 0x93, 0x9b, 0x95, 0x7f, 0x08, 0xf0, + 0x5f, 0x85, 0x1a, 0x4f, 0x4d, 0xeb, 0x70, 0xa3, 0xc5, 0x6a, 0xd8, 0x62, 0xa6, 0xa6, 0x32, 0x93, + 0x58, 0x68, 0x0d, 0x40, 0x23, 0x16, 0xb3, 0x49, 0xbd, 0x8e, 0x6d, 0x51, 0x28, 0x0a, 0x8b, 0xc9, + 0x4d, 0xf1, 0xcb, 0xc7, 0xe5, 0xac, 0x27, 0x60, 0x43, 0xd7, 0x6d, 0x4c, 0xe9, 0x0b, 0x66, 0x9b, + 0x96, 0xa1, 0x84, 0x6a, 0x91, 0x08, 0xe3, 0xb4, 0x75, 0xf0, 0x1a, 0x6b, 0x4c, 0x1c, 0xe1, 0x6d, + 0x8a, 0x1f, 0xa2, 0x59, 0x48, 0xaa, 0x94, 0x62, 0x9b, 0x2f, 0x20, 0xc6, 0x1d, 0xac, 0x9b, 0x40, + 0xf3, 0x90, 0xd6, 0x6c, 0xac, 0x73, 0x0d, 0x6a, 0xbd, 0x6a, 0xea, 0xe2, 0x68, 0x51, 0x58, 0x4c, + 0x29, 0xa9, 0x6e, 0x72, 0x47, 0x47, 0x0b, 0x30, 0xd5, 0x50, 0x35, 0xd5, 0x26, 0xc4, 0xaa, 0x32, + 0x72, 0x88, 0x2d, 0x71, 0xcc, 0xe1, 0x49, 0xfb, 0xd9, 0x3d, 0x9e, 0x5c, 0xcf, 0xbc, 0xbd, 0x38, + 0x5e, 0x0a, 0x89, 0x92, 0x77, 0x61, 0x6e, 0xe0, 0x9c, 0x0a, 0xa6, 0x4d, 0x62, 0x51, 0xec, 0xaa, + 0xd6, 0x34, 0x4c, 0xa9, 0x33, 0xec, 0x84, 0xe2, 0x87, 0x68, 0x1a, 0xe2, 0xba, 0xa9, 0x7b, 0xb3, + 0xf0, 0x47, 0xf9, 0xb3, 0x00, 0xd3, 0x3e, 0x5b, 0x20, 0xff, 0xef, 0x1b, 0xd6, 0xef, 0xc5, 0xe8, + 0x95, 0xbc, 0x78, 0x02, 0x62, 0xaf, 0xfa, 0x6b, 0xd9, 0xf0, 0x4b, 0x80, 0x54, 0x85, 0x1a, 0x5b, + 0x6d, 0xac, 0xb5, 0x18, 0xde, 0x6b, 0xdf, 0xc0, 0x82, 0x87, 0x30, 0xd1, 0xc0, 0x94, 0xaa, 0x06, + 0xa6, 0xe2, 0x48, 0x31, 0xbe, 0x38, 0xb9, 0x2a, 0x97, 0xdc, 0x73, 0x51, 0x0a, 0xaf, 0x50, 0xaa, + 0x78, 0x45, 0x5b, 0x16, 0xb3, 0x3b, 0x4a, 0xd0, 0x33, 0xc0, 0x8a, 0xf8, 0x00, 0x2b, 0xa4, 0xfb, + 0x90, 0x8e, 0x30, 0xf0, 0xa1, 0x0e, 0x71, 0xc7, 0x95, 0xaa, 0xf0, 0x47, 0x94, 0x85, 0xb1, 0x23, + 0xb5, 0xde, 0xc2, 0xce, 0xa0, 0x29, 0xc5, 0x0d, 0xd6, 0x47, 0xd6, 0x84, 0x7e, 0x1f, 0x77, 0x20, + 0x1b, 0x16, 0x77, 0x05, 0x0f, 0x73, 0x30, 0xce, 0xda, 0xd5, 0x9a, 0x4a, 0x6b, 0x9e, 0x8f, 0x09, + 0xd6, 0xde, 0x56, 0x69, 0x4d, 0xfe, 0x20, 0x00, 0xaa, 0x50, 0xe3, 0xa5, 0x55, 0xbf, 0xa5, 0x3d, + 0x35, 0x0f, 0xe9, 0x60, 0xa3, 0x54, 0xbb, 0xef, 0x2d, 0x15, 0x24, 0x1f, 0x9b, 0xfa, 0x15, 0x5d, + 0xeb, 0x1f, 0x7c, 0x1b, 0xa4, 0x7e, 0xb1, 0xd7, 0xda, 0x42, 0x9f, 0x04, 0xc8, 0x75, 0xa9, 0x6e, + 0xeb, 0x06, 0x5a, 0x06, 0xa4, 0x46, 0xb8, 0x42, 0x0e, 0xfc, 0x13, 0x45, 0x6e, 0x62, 0x43, 0x05, + 0x0a, 0x43, 0xb4, 0x5f, 0xcb, 0x8b, 0xf7, 0x02, 0x64, 0x38, 0x5f, 0x53, 0x57, 0x19, 0x7e, 0xe6, + 0xdc, 0xdd, 0xe8, 0x1e, 0x24, 0xb9, 0x5e, 0x62, 0x9b, 0xac, 0x73, 0xa9, 0x05, 0xdd, 0x52, 0x74, + 0x07, 0x12, 0xee, 0xed, 0xef, 0x2c, 0x30, 0xb9, 0x3a, 0xe5, 0x9f, 0x26, 0x97, 0x77, 0x73, 0xf4, + 0xe4, 0x5b, 0x21, 0xa6, 0x78, 0x35, 0x7c, 0xcf, 0x87, 0xe7, 0x76, 0x83, 0xf5, 0x29, 0x3e, 0x6f, + 0x97, 0x53, 0x9e, 0x71, 0x5f, 0x55, 0x48, 0x9e, 0x3f, 0xe6, 0xea, 0xcf, 0x38, 0xc4, 0x2b, 0xd4, + 0x40, 0x8f, 0x20, 0xd9, 0xbd, 0x0d, 0xb2, 0x83, 0x4e, 0xb0, 0x34, 0x3b, 0x28, 0x1b, 0xf8, 0xb5, + 0x0b, 0xe9, 0xe8, 0xad, 0x2a, 0x86, 0xca, 0x23, 0x88, 0x54, 0x1c, 0x86, 0x04, 0x64, 0xfb, 0x80, + 0x06, 0xfc, 0xb1, 0xcd, 0xf5, 0xf6, 0x45, 0x60, 0x69, 0xe1, 0x8f, 0x70, 0xc0, 0xfd, 0x1c, 0x32, + 0xbd, 0x87, 0x55, 0x0a, 0x75, 0xf6, 0x60, 0x92, 0x3c, 0x1c, 0x0b, 0x28, 0x5f, 0x41, 0x76, 0xe0, + 0x39, 0x28, 0xf4, 0xf7, 0x46, 0x25, 0xff, 0x7f, 0x49, 0x41, 0xb0, 0xc2, 0x36, 0xa4, 0x22, 0xbb, + 0x2b, 0x17, 0x6e, 0x0c, 0x01, 0x52, 0x61, 0x08, 0xe0, 0x33, 0x49, 0x63, 0x6f, 0x2e, 0x8e, 0x97, + 0x84, 0xcd, 0x07, 0x27, 0x67, 0x79, 0xe1, 0xf4, 0x2c, 0x2f, 0x7c, 0x3f, 0xcb, 0x0b, 0xef, 0xce, + 0xf3, 0xb1, 0xd3, 0xf3, 0x7c, 0xec, 0xeb, 0x79, 0x3e, 0xb6, 0x2f, 0x1b, 0x26, 0xab, 0xb5, 0x0e, + 0x4a, 0x1a, 0x69, 0x94, 0x89, 0x45, 0x89, 0x65, 0x97, 0x9d, 0x9f, 0x76, 0x99, 0x7f, 0x9c, 0xb0, + 0x4e, 0x13, 0xd3, 0x83, 0x84, 0xf3, 0x0d, 0x72, 0xf7, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x35, + 0x86, 0x16, 0x4d, 0x13, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/service/types/state.pb.go b/x/service/types/state.pb.go index a1286d820..339055f3a 100644 --- a/x/service/types/state.pb.go +++ b/x/service/types/state.pb.go @@ -23,38 +23,13 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -type URI_Protocol int32 - -const ( - URI_HTTPS URI_Protocol = 0 - URI_IPFS URI_Protocol = 1 -) - -var URI_Protocol_name = map[int32]string{ - 0: "HTTPS", - 1: "IPFS", -} - -var URI_Protocol_value = map[string]int32{ - "HTTPS": 0, - "IPFS": 1, -} - -func (x URI_Protocol) String() string { - return proto.EnumName(URI_Protocol_name, int32(x)) -} - -func (URI_Protocol) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_ab6e3654a2974847, []int{2, 0} -} - type Metadata struct { Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` Category string `protobuf:"bytes,5,opt,name=category,proto3" json:"category,omitempty"` - Icon *URI `protobuf:"bytes,6,opt,name=icon,proto3" json:"icon,omitempty"` + Icon string `protobuf:"bytes,6,opt,name=icon,proto3" json:"icon,omitempty"` Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` } @@ -126,11 +101,11 @@ func (m *Metadata) GetCategory() string { return "" } -func (m *Metadata) GetIcon() *URI { +func (m *Metadata) GetIcon() string { if m != nil { return m.Icon } - return nil + return "" } func (m *Metadata) GetTags() []string { @@ -213,96 +188,37 @@ func (m *Profile) GetController() string { return "" } -type URI struct { - Protocol URI_Protocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=service.v1.URI_Protocol" json:"protocol,omitempty"` - Uri string `protobuf:"bytes,2,opt,name=uri,proto3" json:"uri,omitempty"` -} - -func (m *URI) Reset() { *m = URI{} } -func (m *URI) String() string { return proto.CompactTextString(m) } -func (*URI) ProtoMessage() {} -func (*URI) Descriptor() ([]byte, []int) { - return fileDescriptor_ab6e3654a2974847, []int{2} -} -func (m *URI) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *URI) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_URI.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 *URI) XXX_Merge(src proto.Message) { - xxx_messageInfo_URI.Merge(m, src) -} -func (m *URI) XXX_Size() int { - return m.Size() -} -func (m *URI) XXX_DiscardUnknown() { - xxx_messageInfo_URI.DiscardUnknown(m) -} - -var xxx_messageInfo_URI proto.InternalMessageInfo - -func (m *URI) GetProtocol() URI_Protocol { - if m != nil { - return m.Protocol - } - return URI_HTTPS -} - -func (m *URI) GetUri() string { - if m != nil { - return m.Uri - } - return "" -} - func init() { - proto.RegisterEnum("service.v1.URI_Protocol", URI_Protocol_name, URI_Protocol_value) proto.RegisterType((*Metadata)(nil), "service.v1.Metadata") proto.RegisterType((*Profile)(nil), "service.v1.Profile") - proto.RegisterType((*URI)(nil), "service.v1.URI") } func init() { proto.RegisterFile("service/v1/state.proto", fileDescriptor_ab6e3654a2974847) } var fileDescriptor_ab6e3654a2974847 = []byte{ - // 422 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x52, 0xc1, 0x8e, 0xd3, 0x30, - 0x14, 0xac, 0x9b, 0x6c, 0x9b, 0xbe, 0x45, 0x25, 0xb2, 0xd0, 0x62, 0xed, 0xc1, 0x44, 0x05, 0xa1, - 0x1e, 0x50, 0xa2, 0x5d, 0x38, 0xed, 0x09, 0x71, 0x40, 0xf4, 0x80, 0x54, 0x65, 0x77, 0x2f, 0xdc, - 0x52, 0xd7, 0x14, 0xa3, 0xc4, 0xaf, 0xb2, 0xdd, 0x8a, 0xfd, 0x09, 0x04, 0x3f, 0xc0, 0xf7, 0x70, - 0x5c, 0x89, 0x0b, 0x17, 0x24, 0xd4, 0xfe, 0x01, 0x5f, 0x80, 0x62, 0x92, 0x12, 0xb8, 0x58, 0xef, - 0xcd, 0x8c, 0x3c, 0x33, 0xb2, 0xe1, 0xc4, 0x4a, 0xb3, 0x55, 0x42, 0x66, 0xdb, 0xb3, 0xcc, 0xba, - 0xc2, 0xc9, 0x74, 0x6d, 0xd0, 0x21, 0x85, 0x06, 0x4f, 0xb7, 0x67, 0xa7, 0xf7, 0x05, 0xda, 0x0a, - 0x6d, 0x86, 0xa6, 0xaa, 0x65, 0x68, 0xaa, 0x3f, 0xa2, 0xc9, 0x0f, 0x02, 0xd1, 0x6b, 0xe9, 0x8a, - 0x65, 0xe1, 0x0a, 0x3a, 0x86, 0xbe, 0x5a, 0x32, 0x92, 0x90, 0x69, 0x98, 0xf7, 0xd5, 0x92, 0x9e, - 0xc0, 0x00, 0x8d, 0x5a, 0x29, 0xcd, 0xfa, 0x09, 0x99, 0x8e, 0xf2, 0x66, 0xa3, 0x14, 0x42, 0x5d, - 0x54, 0x92, 0x05, 0x1e, 0xf5, 0x33, 0x4d, 0xe0, 0x78, 0x29, 0xad, 0x30, 0x6a, 0xed, 0x14, 0x6a, - 0x16, 0x7a, 0xaa, 0x0b, 0xd1, 0x53, 0x88, 0x44, 0xe1, 0xe4, 0x0a, 0xcd, 0x0d, 0x3b, 0xf2, 0xf4, - 0x61, 0xa7, 0x0f, 0x21, 0x54, 0x02, 0x35, 0x1b, 0x24, 0x64, 0x7a, 0x7c, 0x7e, 0x37, 0xfd, 0x1b, - 0x3d, 0xbd, 0xce, 0x67, 0xb9, 0x27, 0x6b, 0x5b, 0x57, 0xac, 0x2c, 0x1b, 0x26, 0x41, 0x6d, 0x5b, - 0xcf, 0x17, 0xfc, 0xd7, 0x97, 0x6f, 0x1f, 0x03, 0x06, 0x83, 0x3a, 0x7a, 0x4c, 0xe8, 0x9d, 0x36, - 0x72, 0x4c, 0x18, 0x61, 0x64, 0xf2, 0x99, 0xc0, 0x70, 0x6e, 0xf0, 0xad, 0x2a, 0x65, 0xa7, 0xde, - 0xc8, 0xd7, 0x63, 0x30, 0xb4, 0x9b, 0xc5, 0x7b, 0x29, 0x5c, 0xd3, 0xaf, 0x5d, 0x3b, 0xc5, 0x83, - 0x7f, 0x8a, 0x73, 0x00, 0x81, 0xda, 0x19, 0x2c, 0x4b, 0x69, 0x9a, 0x8e, 0x1d, 0xe4, 0xe2, 0x91, - 0x4f, 0xc3, 0x21, 0xac, 0x9d, 0xe8, 0x3d, 0x18, 0x37, 0x17, 0x3e, 0xe9, 0x64, 0xea, 0x4f, 0x34, - 0x04, 0xd7, 0xf9, 0x8c, 0x3e, 0x83, 0xc8, 0xbf, 0x81, 0xc0, 0xd2, 0x87, 0x1a, 0x9f, 0xb3, 0xff, - 0x7a, 0xa7, 0xf3, 0x86, 0xcf, 0x0f, 0x4a, 0x1a, 0x43, 0xb0, 0x31, 0xaa, 0x09, 0x5c, 0x8f, 0x93, - 0x07, 0x10, 0xb5, 0x3a, 0x3a, 0x82, 0xa3, 0x57, 0x57, 0x57, 0xf3, 0xcb, 0xb8, 0x47, 0x23, 0x08, - 0x67, 0xf3, 0x97, 0x97, 0x31, 0x79, 0xf1, 0xfc, 0xeb, 0x8e, 0x93, 0xdb, 0x1d, 0x27, 0x3f, 0x77, - 0x9c, 0x7c, 0xda, 0xf3, 0xde, 0xed, 0x9e, 0xf7, 0xbe, 0xef, 0x79, 0xef, 0xcd, 0xe3, 0x95, 0x72, - 0xef, 0x36, 0x8b, 0x54, 0x60, 0x95, 0xa1, 0xb6, 0xa8, 0x4d, 0xe6, 0x8f, 0x0f, 0x59, 0xfb, 0xa7, - 0xdc, 0xcd, 0x5a, 0xda, 0xc5, 0xc0, 0xdb, 0x3f, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xf1, 0xad, - 0x51, 0x19, 0x6b, 0x02, 0x00, 0x00, + // 348 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xc1, 0x6a, 0xe3, 0x30, + 0x10, 0x86, 0x23, 0xdb, 0xeb, 0x24, 0xb3, 0x4b, 0x08, 0x62, 0xc9, 0x8a, 0x1c, 0x84, 0x09, 0xcb, + 0x92, 0xc3, 0x12, 0x13, 0xf6, 0x96, 0xd3, 0xd2, 0x7b, 0xa1, 0xe4, 0xd8, 0x9b, 0x23, 0xab, 0xae, + 0x4a, 0xec, 0x09, 0x92, 0x12, 0x9a, 0x97, 0x28, 0xed, 0x0b, 0xf4, 0x79, 0x7a, 0xe8, 0x21, 0xd0, + 0x4b, 0x8f, 0x25, 0x79, 0x83, 0x3e, 0x41, 0x91, 0xe2, 0x14, 0xf7, 0x22, 0x66, 0xfe, 0x19, 0x7e, + 0xfd, 0x1f, 0x03, 0x03, 0x23, 0xf5, 0x46, 0x09, 0x99, 0x6e, 0xa6, 0xa9, 0xb1, 0x99, 0x95, 0x93, + 0x95, 0x46, 0x8b, 0x14, 0x6a, 0x7d, 0xb2, 0x99, 0x0e, 0x7f, 0x09, 0x34, 0x25, 0x9a, 0x14, 0x75, + 0xe9, 0xd6, 0x50, 0x97, 0xc7, 0xa5, 0xd1, 0x33, 0x81, 0xce, 0xb9, 0xb4, 0x59, 0x9e, 0xd9, 0x8c, + 0xf6, 0x20, 0x50, 0x39, 0x23, 0x09, 0x19, 0x47, 0xf3, 0x40, 0xe5, 0x74, 0x00, 0x31, 0x6a, 0x55, + 0xa8, 0x8a, 0x05, 0x09, 0x19, 0x77, 0xe7, 0x75, 0x47, 0x29, 0x44, 0x55, 0x56, 0x4a, 0x16, 0x7a, + 0xd5, 0xd7, 0x34, 0x81, 0xef, 0xb9, 0x34, 0x42, 0xab, 0x95, 0x55, 0x58, 0xb1, 0xc8, 0x8f, 0x9a, + 0x12, 0x1d, 0x42, 0x47, 0x64, 0x56, 0x16, 0xa8, 0xb7, 0xec, 0x9b, 0x1f, 0x7f, 0xf6, 0xce, 0x51, + 0x09, 0xac, 0x58, 0x7c, 0x74, 0x74, 0xb5, 0xd3, 0x6c, 0x56, 0x18, 0xd6, 0x4e, 0x42, 0xa7, 0xb9, + 0x7a, 0xc6, 0xdf, 0x1f, 0x5f, 0xee, 0x42, 0x06, 0xb1, 0x4b, 0xda, 0x27, 0xf4, 0xc7, 0x29, 0x61, + 0x9f, 0x30, 0xc2, 0xc8, 0xe8, 0x81, 0x40, 0xfb, 0x42, 0xe3, 0x95, 0x5a, 0xca, 0x06, 0x4d, 0xd7, + 0xd3, 0x30, 0x68, 0x9b, 0xf5, 0xe2, 0x46, 0x0a, 0x5b, 0xe3, 0x9c, 0xda, 0x06, 0x67, 0xf8, 0x85, + 0x93, 0x03, 0x08, 0xac, 0xac, 0xc6, 0xe5, 0x52, 0xea, 0x1a, 0xa9, 0xa1, 0xcc, 0x7e, 0xfb, 0x34, + 0x1c, 0x22, 0xf7, 0x13, 0xfd, 0x09, 0xbd, 0xda, 0xf0, 0x6f, 0x23, 0x53, 0x70, 0xf6, 0xff, 0x69, + 0xcf, 0xc9, 0x6e, 0xcf, 0xc9, 0xdb, 0x9e, 0x93, 0xfb, 0x03, 0x6f, 0xed, 0x0e, 0xbc, 0xf5, 0x7a, + 0xe0, 0xad, 0xcb, 0x3f, 0x85, 0xb2, 0xd7, 0xeb, 0xc5, 0x44, 0x60, 0x99, 0x62, 0x65, 0xb0, 0xd2, + 0xa9, 0x7f, 0x6e, 0xd3, 0xd3, 0x49, 0xed, 0x76, 0x25, 0xcd, 0x22, 0xf6, 0xb7, 0xfa, 0xf7, 0x11, + 0x00, 0x00, 0xff, 0xff, 0x81, 0xa0, 0xdf, 0xce, 0xea, 0x01, 0x00, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { @@ -334,15 +250,10 @@ func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x3a } } - if m.Icon != nil { - { - size, err := m.Icon.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintState(dAtA, i, uint64(size)) - } + if len(m.Icon) > 0 { + i -= len(m.Icon) + copy(dAtA[i:], m.Icon) + i = encodeVarintState(dAtA, i, uint64(len(m.Icon))) i-- dAtA[i] = 0x32 } @@ -433,41 +344,6 @@ func (m *Profile) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *URI) 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 *URI) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *URI) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Uri) > 0 { - i -= len(m.Uri) - copy(dAtA[i:], m.Uri) - i = encodeVarintState(dAtA, i, uint64(len(m.Uri))) - i-- - dAtA[i] = 0x12 - } - if m.Protocol != 0 { - i = encodeVarintState(dAtA, i, uint64(m.Protocol)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - func encodeVarintState(dAtA []byte, offset int, v uint64) int { offset -= sovState(v) base := offset @@ -504,8 +380,8 @@ func (m *Metadata) Size() (n int) { if l > 0 { n += 1 + l + sovState(uint64(l)) } - if m.Icon != nil { - l = m.Icon.Size() + l = len(m.Icon) + if l > 0 { n += 1 + l + sovState(uint64(l)) } if len(m.Tags) > 0 { @@ -542,22 +418,6 @@ func (m *Profile) Size() (n int) { return n } -func (m *URI) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Protocol != 0 { - n += 1 + sovState(uint64(m.Protocol)) - } - l = len(m.Uri) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - return n -} - func sovState(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -744,7 +604,7 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Icon", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowState @@ -754,27 +614,23 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthState } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthState } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Icon == nil { - m.Icon = &URI{} - } - if err := m.Icon.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Icon = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 2 { @@ -1007,107 +863,6 @@ func (m *Profile) Unmarshal(dAtA []byte) error { } return nil } -func (m *URI) 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 ErrIntOverflowState - } - 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: URI: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: URI: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) - } - m.Protocol = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Protocol |= URI_Protocol(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Uri", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Uri = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipState(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthState - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipState(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/vault/keeper/keeper.go b/x/vault/keeper/keeper.go index 99ed90406..9732c576e 100644 --- a/x/vault/keeper/keeper.go +++ b/x/vault/keeper/keeper.go @@ -15,7 +15,7 @@ import ( "github.com/ipfs/kubo/client/rpc" apiv1 "github.com/onsonr/sonr/api/vault/v1" - dwngen "github.com/onsonr/sonr/internal/dwn/gen" + dwngen "github.com/onsonr/sonr/pkg/motr/config" didkeeper "github.com/onsonr/sonr/x/did/keeper" "github.com/onsonr/sonr/x/vault/types" ) diff --git a/x/vault/keeper/querier.go b/x/vault/keeper/querier.go index 304603244..906f275ce 100644 --- a/x/vault/keeper/querier.go +++ b/x/vault/keeper/querier.go @@ -7,8 +7,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/onsonr/crypto/mpc" - didtypes "github.com/onsonr/sonr/x/did/types" + "github.com/onsonr/sonr/x/did/controller" "github.com/onsonr/sonr/x/vault/types" ) @@ -72,7 +72,7 @@ func (k Querier) Allocate(goCtx context.Context, req *types.QueryAllocateRequest } // 3. Create Controller from Keyshares - con, err := didtypes.NewController(shares) + con, err := controller.New(shares) if err != nil { ctx.Logger().Error(fmt.Sprintf("Error creating controller: %s", err.Error())) return nil, types.ErrControllerCreation.Wrap(err.Error()) diff --git a/x/vault/types/params.go b/x/vault/types/params.go index c7961d7e1..e8e1abedd 100644 --- a/x/vault/types/params.go +++ b/x/vault/types/params.go @@ -3,7 +3,7 @@ package types import ( "encoding/json" - "github.com/onsonr/sonr/internal/orm" + "github.com/onsonr/sonr/pkg/motr/types/orm" ) // DefaultParams returns default module parameters. diff --git a/x/vault/types/vault.go b/x/vault/types/vault.go index 5c5182471..6507a6ce5 100644 --- a/x/vault/types/vault.go +++ b/x/vault/types/vault.go @@ -3,16 +3,16 @@ package types import ( "github.com/ipfs/boxo/files" - "github.com/onsonr/sonr/internal/dwn" - dwngen "github.com/onsonr/sonr/internal/dwn/gen" + "github.com/onsonr/sonr/pkg/motr" + "github.com/onsonr/sonr/pkg/motr/config" ) type Vault struct { FS files.Node } -func NewVault(keyshareJSON string, adddress string, chainID string, schema *dwngen.Schema) (*Vault, error) { - dwnCfg := &dwngen.Config{ +func NewVault(keyshareJSON string, adddress string, chainID string, schema *config.Schema) (*Vault, error) { + dwnCfg := &config.Config{ MotrKeyshare: keyshareJSON, MotrAddress: adddress, IpfsGatewayUrl: "https://ipfs.sonr.land", @@ -21,7 +21,7 @@ func NewVault(keyshareJSON string, adddress string, chainID string, schema *dwng SonrChainId: chainID, VaultSchema: schema, } - fileMap, err := dwn.NewVaultDirectory(dwnCfg) + fileMap, err := motr.NewVaultDirectory(dwnCfg) if err != nil { return nil, err } From 89989fa102715a698a7d2e5bd53fa3d5530c366a Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Sat, 23 Nov 2024 01:28:58 -0500 Subject: [PATCH 03/30] feature/1114 implement account interface (#1167) - **refactor: move session-related code to middleware package** - **refactor: update PKL build process and adjust related configurations** - **feat: integrate base.cosmos.v1 Genesis module** - **refactor: pass session context to modal rendering functions** - **refactor: move nebula package to app directory and update templ version** - **refactor: Move home section video view to dedicated directory** - **refactor: remove unused views file** - **refactor: move styles and UI components to global scope** - **refactor: Rename images.go to cdn.go** - **feat: Add Empty State Illustrations** - **refactor: Consolidate Vault Index Logic** - **fix: References to App.wasm and remove Vault Directory embedded CDN files** - **refactor: Move CDN types to Models** - **fix: Correct line numbers in templ error messages for arch_templ.go** - **refactor: use common types for peer roles** - **refactor: move common types and ORM to a shared package** - **fix: Config import dwn** - **refactor: move nebula directory to app** - **feat: Rebuild nebula** - **fix: correct file paths in panels templates** - **feat: Remove duplicate types** - **refactor: Move dwn to pkg/core** - **refactor: Binary Structure** - **feat: Introduce Crypto Pkg** - **fix: Broken Process Start** - **feat: Update pkg/* structure** - **feat: Refactor PKL Structure** - **build: update pkl build process** - **chore: Remove Empty Files** - **refactor: remove unused macaroon package** - **feat: Add WebAwesome Components** - **refactor: consolidate build and generation tasks into a single taskfile, remove redundant makefile targets** - **refactor: refactor server and move components to pkg/core/dwn** - **build: update go modules** - **refactor: move gateway logic into dedicated hway command** - **feat: Add KSS (Krawczyk-Song-Song) MPC cryptography module** - **feat: Implement MPC-based JWT signing and UCAN token generation** - **feat: add support for MPC-based JWT signing** - **feat: Implement MPC-based UCAN capabilities for smart accounts** - **feat: add address field to keyshareSource** - **feat: Add comprehensive MPC test suite for keyshares, UCAN tokens, and token attenuations** - **refactor: improve MPC keyshare management and signing process** - **feat: enhance MPC capability hierarchy documentation** - **refactor: rename GenerateKeyshares function to NewKeyshareSource for clarity** - **refactor: remove unused Ethereum address computation** - **feat: Add HasHandle and IsAuthenticated methods to HTTPContext** - **refactor: Add context.Context support to session HTTPContext** - **refactor: Resolve context interface conflicts in HTTPContext** - **feat: Add session ID context key and helper functions** - **feat: Update WebApp Page Rendering** - **refactor: Simplify context management by using single HTTPContext key** - **refactor: Simplify HTTPContext creation and context management in session middleware** - **refactor: refactor session middleware to use a single data structure** - **refactor: Simplify HTTPContext implementation and session data handling** - **refactor: Improve session context handling and prevent nil pointer errors** - **refactor: Improve session context handling with nil safety and type support** - **refactor: improve session data injection** - **feat: add full-screen modal component and update registration flow** - **chore: add .air.toml to .gitignore** - **feat: add Air to devbox and update dependencies** --- .air.toml | 51 + .gitignore | 6 +- Makefile | 17 - Taskfile.yml | 120 +- buf.work.yaml | 1 - cmd/dwn/main.go | 173 - cmd/gateway/bun.lockb | Bin 111371 -> 0 bytes cmd/gateway/main.go | 19 - cmd/gateway/wrangler.toml | 8 - cmd/hway/main.go | 33 + cmd/motr/main.go | 26 + cmd/sonrd/motr.go | 1 - devbox.json | 12 +- devbox.lock | 48 + go.mod | 45 +- go.sum | 469 +- pkg/common/README.md | 1 - pkg/common/ctx/cookies.go | 68 - pkg/common/ctx/ctx_dwn.go | 90 - pkg/common/ctx/ctx_hway.go | 45 - pkg/common/ctx/headers.go | 38 - pkg/common/ctx/request.go | 35 - pkg/common/ctx/response.go | 38 - pkg/common/ctx/utils.go | 73 - pkg/common/httputil/get.go | 49 + pkg/common/ipfs/ipfs.go | 1 + pkg/common/middleware/cookie/cookie.go | 77 + pkg/common/middleware/cookie/keys.go | 38 + pkg/common/middleware/header/header.go | 22 + pkg/common/middleware/header/keys.go | 29 + pkg/common/middleware/request/cookies.go | 1 + pkg/common/middleware/request/headers.go | 1 + pkg/common/middleware/request/params.go | 1 + pkg/common/middleware/request/query.go | 1 + pkg/common/middleware/response/cache.go | 1 + pkg/common/middleware/response/cookies.go | 1 + pkg/common/middleware/response/headers.go | 1 + pkg/common/middleware/response/render.go | 45 + pkg/common/middleware/session/context.go | 60 + pkg/common/middleware/session/middleware.go | 73 + pkg/common/middleware/session/session.go | 84 + pkg/common/middleware/session/utils.go | 188 + .../orm => common/models}/Account.pkl.go | 4 +- .../types/orm => common/models}/Asset.pkl.go | 4 +- .../types/orm => common/models}/Chain.pkl.go | 4 +- .../orm => common/models}/Credential.pkl.go | 4 +- .../types/orm => common/models}/DID.pkl.go | 14 +- .../types/orm => common/models}/Grant.pkl.go | 4 +- .../types/orm => common/models}/JWK.pkl.go | 4 +- .../orm => common/models}/Keyshare.pkl.go | 4 +- .../Orm.pkl.go => common/models/ORM.pkl.go} | 16 +- .../orm => common/models}/Profile.pkl.go | 4 +- .../models}/assettype/AssetType.pkl.go | 2 +- .../models}/didmethod/DIDMethod.pkl.go | 2 +- pkg/common/models/init.pkl.go | 17 + .../models}/keyalgorithm/KeyAlgorithm.pkl.go | 2 +- .../models}/keycurve/KeyCurve.pkl.go | 2 +- .../models}/keyencoding/KeyEncoding.pkl.go | 2 +- .../models}/keyrole/KeyRole.pkl.go | 2 +- .../models}/keysharerole/KeyShareRole.pkl.go | 2 +- .../models}/keytype/KeyType.pkl.go | 2 +- .../permissiongrant/PermissionGrant.pkl.go | 2 +- .../permissionscope/PermissionScope.pkl.go | 2 +- pkg/{motr/types/orm => common}/schema.go | 2 +- pkg/common/session.go | 69 + pkg/common/types/Ctx.pkl.go | 36 + pkg/common/types/Session.pkl.go | 24 + pkg/common/types/init.pkl.go | 9 + pkg/common/types/ipfs.pb.go | 64 - pkg/common/types/keys.pb.go | 377 -- pkg/common/types/uri.pb.go | 215 - pkg/{motr/config => core/dwn}/Config.pkl.go | 4 +- .../config/Dwn.pkl.go => core/dwn/DWN.pkl.go} | 16 +- pkg/core/dwn/Environment.pkl.go | 14 + pkg/{motr/config => core/dwn}/Schema.pkl.go | 4 +- pkg/core/dwn/bridge/fetch.go | 211 + pkg/core/dwn/bridge/wasm.go | 34 + pkg/core/dwn/dwn.go | 30 + pkg/{motr => core/dwn}/handlers/auth.go | 12 +- pkg/{motr => core/dwn}/handlers/openid.go | 0 pkg/core/dwn/handlers/worker.go | 284 ++ pkg/core/dwn/init.pkl.go | 11 + pkg/core/dwn/server/server.go | 60 + pkg/crypto/accumulator/accumulator.go | 171 + pkg/crypto/accumulator/accumulator_test.go | 188 + pkg/crypto/accumulator/key.go | 244 + pkg/crypto/accumulator/key_test.go | 88 + pkg/crypto/accumulator/lib.go | 204 + pkg/crypto/accumulator/lib_test.go | 404 ++ pkg/crypto/accumulator/proof.go | 518 ++ pkg/crypto/accumulator/proof_test.go | 182 + pkg/crypto/accumulator/witness.go | 375 ++ pkg/crypto/accumulator/witness_test.go | 229 + pkg/crypto/bip32/bip32.go | 66 + pkg/crypto/bulletproof/generators.go | 57 + pkg/crypto/bulletproof/generators_test.go | 61 + pkg/crypto/bulletproof/helpers.go | 181 + pkg/crypto/bulletproof/helpers_test.go | 85 + pkg/crypto/bulletproof/ipp_prover.go | 396 ++ pkg/crypto/bulletproof/ipp_prover_test.go | 99 + pkg/crypto/bulletproof/ipp_verifier.go | 209 + pkg/crypto/bulletproof/ipp_verifier_test.go | 79 + pkg/crypto/bulletproof/range_batch_prover.go | 348 ++ .../bulletproof/range_batch_prover_test.go | 102 + .../bulletproof/range_batch_verifier.go | 91 + .../bulletproof/range_batch_verifier_test.go | 148 + pkg/crypto/bulletproof/range_prover.go | 476 ++ pkg/crypto/bulletproof/range_prover_test.go | 86 + pkg/crypto/bulletproof/range_verifier.go | 187 + pkg/crypto/bulletproof/range_verifier_test.go | 87 + pkg/crypto/core/README.md | 14 + pkg/crypto/core/commit.go | 115 + pkg/crypto/core/commit_test.go | 374 ++ pkg/crypto/core/curves/bls12377_curve.go | 1226 +++++ pkg/crypto/core/curves/bls12381_curve.go | 1129 +++++ pkg/crypto/core/curves/curve.go | 863 ++++ pkg/crypto/core/curves/ec_point.go | 251 + pkg/crypto/core/curves/ec_point_test.go | 369 ++ pkg/crypto/core/curves/ec_scalar.go | 351 ++ pkg/crypto/core/curves/ecdsa.go | 39 + pkg/crypto/core/curves/ed25519_curve.go | 788 +++ pkg/crypto/core/curves/ed25519_curve_test.go | 403 ++ pkg/crypto/core/curves/field.go | 280 ++ pkg/crypto/core/curves/field_test.go | 301 ++ pkg/crypto/core/curves/k256_bench_test.go | 446 ++ pkg/crypto/core/curves/k256_curve.go | 670 +++ pkg/crypto/core/curves/k256_curve_test.go | 423 ++ .../core/curves/native/bls12381/bls12381.go | 48 + pkg/crypto/core/curves/native/bls12381/fp.go | 697 +++ .../core/curves/native/bls12381/fp12.go | 231 + .../core/curves/native/bls12381/fp12_test.go | 417 ++ pkg/crypto/core/curves/native/bls12381/fp2.go | 344 ++ .../core/curves/native/bls12381/fp2_test.go | 424 ++ pkg/crypto/core/curves/native/bls12381/fp6.go | 340 ++ .../core/curves/native/bls12381/fp6_test.go | 217 + .../core/curves/native/bls12381/fp_test.go | 297 ++ pkg/crypto/core/curves/native/bls12381/fq.go | 416 ++ .../core/curves/native/bls12381/fq_test.go | 342 ++ pkg/crypto/core/curves/native/bls12381/g1.go | 1123 +++++ .../core/curves/native/bls12381/g1_test.go | 412 ++ pkg/crypto/core/curves/native/bls12381/g2.go | 1122 +++++ .../core/curves/native/bls12381/g2_test.go | 554 +++ pkg/crypto/core/curves/native/bls12381/gt.go | 434 ++ .../core/curves/native/bls12381/pairings.go | 254 + .../curves/native/bls12381/pairings_test.go | 64 + pkg/crypto/core/curves/native/field.go | 388 ++ pkg/crypto/core/curves/native/hash2field.go | 107 + pkg/crypto/core/curves/native/isogeny.go | 62 + pkg/crypto/core/curves/native/k256/fp/fp.go | 175 + .../core/curves/native/k256/fp/fp_test.go | 328 ++ .../curves/native/k256/fp/secp256k1_fp.go | 1894 +++++++ pkg/crypto/core/curves/native/k256/fq/fq.go | 287 ++ .../core/curves/native/k256/fq/fq_test.go | 328 ++ .../curves/native/k256/fq/secp256k1_fq.go | 1954 ++++++++ pkg/crypto/core/curves/native/k256/point.go | 446 ++ .../core/curves/native/k256/point_test.go | 19 + pkg/crypto/core/curves/native/osswu.go | 82 + pkg/crypto/core/curves/native/p256/fp/fp.go | 172 + .../core/curves/native/p256/fp/fp_test.go | 328 ++ .../core/curves/native/p256/fp/p256_fp.go | 1463 ++++++ pkg/crypto/core/curves/native/p256/fq/fq.go | 295 ++ .../core/curves/native/p256/fq/fq_test.go | 328 ++ .../core/curves/native/p256/fq/p256_fq.go | 1651 +++++++ pkg/crypto/core/curves/native/p256/point.go | 317 ++ .../core/curves/native/p256/point_test.go | 38 + pkg/crypto/core/curves/native/pasta/README.md | 10 + pkg/crypto/core/curves/native/pasta/fp/fp.go | 369 ++ .../core/curves/native/pasta/fp/fp_test.go | 249 + .../core/curves/native/pasta/fp/pasta_fp.go | 1467 ++++++ pkg/crypto/core/curves/native/pasta/fq/fq.go | 363 ++ .../core/curves/native/pasta/fq/fq_test.go | 249 + .../core/curves/native/pasta/fq/pasta_fq.go | 1467 ++++++ pkg/crypto/core/curves/native/pasta/pallas.go | 7 + pkg/crypto/core/curves/native/point.go | 468 ++ pkg/crypto/core/curves/p256_bench_test.go | 756 +++ pkg/crypto/core/curves/p256_curve.go | 668 +++ pkg/crypto/core/curves/p256_curve_test.go | 365 ++ pkg/crypto/core/curves/pallas_curve.go | 1176 +++++ pkg/crypto/core/curves/pallas_curve_test.go | 138 + pkg/crypto/core/curves/secp256k1/secp256k1.go | 315 ++ pkg/crypto/core/curves/sp256_curve.go | 11 + pkg/crypto/core/hash.go | 272 + pkg/crypto/core/hash_test.go | 132 + pkg/crypto/core/mod.go | 178 + pkg/crypto/core/mod_test.go | 565 +++ pkg/crypto/core/primes.go | 42 + pkg/crypto/core/protocol/protocol.go | 109 + pkg/crypto/daed/aes_siv.go | 244 + pkg/crypto/daed/aes_siv_test.go | 303 ++ pkg/crypto/dkg/frost/README.md | 13 + pkg/crypto/dkg/frost/dkg_round1.go | 148 + pkg/crypto/dkg/frost/dkg_round2.go | 158 + pkg/crypto/dkg/frost/dkg_rounds_test.go | 168 + pkg/crypto/dkg/frost/participant.go | 65 + pkg/crypto/dkg/gennaro/README.md | 13 + pkg/crypto/dkg/gennaro/participant.go | 97 + pkg/crypto/dkg/gennaro/participant_test.go | 48 + pkg/crypto/dkg/gennaro/round1.go | 79 + pkg/crypto/dkg/gennaro/round2.go | 90 + pkg/crypto/dkg/gennaro/round3.go | 89 + pkg/crypto/dkg/gennaro/round4.go | 76 + pkg/crypto/dkg/gennaro/rounds_test.go | 381 ++ pkg/crypto/dkg/gennaro2p/README.md | 12 + pkg/crypto/dkg/gennaro2p/genarro2p.go | 151 + pkg/crypto/dkg/gennaro2p/genarro2p_test.go | 181 + pkg/crypto/ecies/encrypt.go | 13 + pkg/crypto/ecies/keys.go | 57 + pkg/crypto/ecies/keys_test.go | 22 + pkg/crypto/internal/err.go | 22 + pkg/crypto/internal/hash.go | 93 + pkg/crypto/internal/hash_test.go | 62 + pkg/crypto/internal/point.go | 44 + pkg/crypto/internal/testutils.go | 21 + pkg/crypto/mpc/caps.go | 117 + pkg/crypto/mpc/jwt.go | 97 + pkg/crypto/mpc/mpc.go | 107 + pkg/crypto/mpc/mpc_test.go | 35 + pkg/crypto/mpc/share.go | 198 + pkg/crypto/mpc/source.go | 112 + pkg/crypto/mpc/ucan.go | 95 + pkg/crypto/mpc/utils.go | 107 + pkg/crypto/ot/base/simplest/ot.go | 392 ++ pkg/crypto/ot/base/simplest/ot_test.go | 85 + pkg/crypto/ot/base/simplest/stream.go | 100 + pkg/crypto/ot/base/simplest/util.go | 53 + pkg/crypto/ot/extension/kos/kos.go | 400 ++ pkg/crypto/ot/extension/kos/kos_test.go | 141 + pkg/crypto/ot/extension/kos/stream.go | 57 + pkg/crypto/ot/ottest/util.go | 50 + pkg/crypto/paillier/README.md | 23 + pkg/crypto/paillier/paillier.go | 376 ++ pkg/crypto/paillier/psf.go | 222 + pkg/crypto/paillier/psf_test.go | 303 ++ pkg/crypto/sharing/README.md | 16 + pkg/crypto/sharing/ed25519_feldman_test.go | 132 + pkg/crypto/sharing/feldman.go | 112 + pkg/crypto/sharing/pedersen.go | 152 + pkg/crypto/sharing/polynomial.go | 35 + pkg/crypto/sharing/polynomial_test.go | 32 + pkg/crypto/sharing/shamir.go | 206 + pkg/crypto/sharing/shamir_test.go | 186 + .../sharing/v1/bls12381g1_feldman_test.go | 141 + pkg/crypto/sharing/v1/bls12381g1curve.go | 109 + .../sharing/v1/bls12381g2_feldman_test.go | 131 + pkg/crypto/sharing/v1/bls12381g2curve.go | 108 + pkg/crypto/sharing/v1/common.go | 14 + pkg/crypto/sharing/v1/ed25519_feldman_test.go | 131 + .../sharing/v1/ed25519_pedersen_test.go | 154 + pkg/crypto/sharing/v1/ed25519curve.go | 143 + pkg/crypto/sharing/v1/ed25519curve_test.go | 26 + pkg/crypto/sharing/v1/feldman.go | 107 + pkg/crypto/sharing/v1/k256_feldman_test.go | 132 + pkg/crypto/sharing/v1/k256_pedersen_test.go | 155 + pkg/crypto/sharing/v1/p256_feldman_test.go | 132 + pkg/crypto/sharing/v1/pedersen.go | 174 + pkg/crypto/sharing/v1/polynomial.go | 49 + pkg/crypto/sharing/v1/polynomial_test.go | 29 + pkg/crypto/sharing/v1/shamir.go | 212 + pkg/crypto/sharing/v1/shamir_test.go | 205 + pkg/crypto/signatures/bbs/blind_signature.go | 79 + .../signatures/bbs/blind_signature_context.go | 255 + .../bbs/blind_signature_context_test.go | 98 + .../signatures/bbs/message_generators.go | 77 + pkg/crypto/signatures/bbs/pok_signature.go | 159 + .../signatures/bbs/pok_signature_proof.go | 213 + .../bbs/pok_signature_proof_test.go | 317 ++ pkg/crypto/signatures/bbs/public_key.go | 73 + pkg/crypto/signatures/bbs/secret_key.go | 177 + pkg/crypto/signatures/bbs/signature.go | 67 + pkg/crypto/signatures/bbs/signature_test.go | 81 + pkg/crypto/signatures/bls/README.md | 114 + pkg/crypto/signatures/bls/bls_sig/lib.go | 208 + pkg/crypto/signatures/bls/bls_sig/lib_test.go | 284 ++ pkg/crypto/signatures/bls/bls_sig/tiny_bls.go | 438 ++ .../signatures/bls/bls_sig/tiny_bls_sig.go | 489 ++ .../bls/bls_sig/tiny_bls_sig_aug_test.go | 381 ++ .../bls/bls_sig/tiny_bls_sig_basic_test.go | 377 ++ .../bls/bls_sig/tiny_bls_sig_pop_test.go | 845 ++++ .../signatures/bls/bls_sig/usual_bls.go | 446 ++ .../signatures/bls/bls_sig/usual_bls_sig.go | 491 ++ .../bls/bls_sig/usual_bls_sig_aug_test.go | 409 ++ .../bls/bls_sig/usual_bls_sig_basic_test.go | 409 ++ .../bls/bls_sig/usual_bls_sig_pop_test.go | 867 ++++ pkg/crypto/signatures/bls/rust/Cargo.toml | 19 + pkg/crypto/signatures/bls/rust/README.md | 13 + pkg/crypto/signatures/bls/rust/src/main.rs | 388 ++ pkg/crypto/signatures/bls/tests/bls/main.go | 237 + pkg/crypto/signatures/bls/tmp.json | 3 + pkg/crypto/signatures/common/challenge.go | 14 + pkg/crypto/signatures/common/commitment.go | 15 + pkg/crypto/signatures/common/hmacdrbg.go | 99 + pkg/crypto/signatures/common/nonce.go | 15 + .../common/proof_committed_builder.go | 86 + pkg/crypto/signatures/common/proof_message.go | 79 + .../signatures/common/signature_blinding.go | 14 + .../signatures/schnorr/mina/bitvector.go | 232 + .../schnorr/mina/challenge_derive.go | 42 + pkg/crypto/signatures/schnorr/mina/keys.go | 272 + .../signatures/schnorr/mina/keys_test.go | 132 + .../schnorr/mina/poseidon_config.go | 112 + .../signatures/schnorr/mina/poseidon_hash.go | 1182 +++++ .../schnorr/mina/poseidon_hash_test.go | 122 + pkg/crypto/signatures/schnorr/mina/roinput.go | 136 + .../signatures/schnorr/mina/signature.go | 49 + pkg/crypto/signatures/schnorr/mina/txn.go | 224 + .../signatures/schnorr/nem/ed25519_keccak.go | 320 ++ .../schnorr/nem/ed25519_keccak_test.go | 190 + pkg/crypto/subtle/hkdf.go | 55 + pkg/crypto/subtle/random/random.go | 22 + pkg/crypto/subtle/subtle.go | 130 + pkg/crypto/subtle/x25519.go | 25 + pkg/crypto/tecdsa/dklsv1/README.md | 13 + pkg/crypto/tecdsa/dklsv1/boilerplate.go | 416 ++ pkg/crypto/tecdsa/dklsv1/dealer/dealer.go | 83 + .../tecdsa/dklsv1/dealer/dealer_test.go | 49 + pkg/crypto/tecdsa/dklsv1/dkg/dkg.go | 272 + pkg/crypto/tecdsa/dklsv1/dkg/dkg_test.go | 104 + pkg/crypto/tecdsa/dklsv1/dkgserializers.go | 315 ++ pkg/crypto/tecdsa/dklsv1/protocol.go | 33 + pkg/crypto/tecdsa/dklsv1/protocol_test.go | 419 ++ pkg/crypto/tecdsa/dklsv1/refresh/refresh.go | 177 + .../tecdsa/dklsv1/refresh/refresh_test.go | 186 + .../tecdsa/dklsv1/refreshserializers.go | 238 + pkg/crypto/tecdsa/dklsv1/sign/multiply.go | 267 + .../tecdsa/dklsv1/sign/multiply_test.go | 48 + pkg/crypto/tecdsa/dklsv1/sign/sign.go | 358 ++ pkg/crypto/tecdsa/dklsv1/sign/sign_test.go | 81 + pkg/crypto/tecdsa/dklsv1/signserializers.go | 122 + .../dklsv1/testdata/alice-dkls-v1-dkg.bin | 1 + .../dklsv1/testdata/bob-dkls-v1-dkg.bin | 1 + pkg/crypto/ted25519/frost/README.md | 13 + pkg/crypto/ted25519/frost/challenge_derive.go | 27 + pkg/crypto/ted25519/frost/participant.go | 83 + pkg/crypto/ted25519/frost/round1.go | 78 + pkg/crypto/ted25519/frost/round2.go | 181 + pkg/crypto/ted25519/frost/round3.go | 157 + pkg/crypto/ted25519/frost/rounds_test.go | 404 ++ pkg/crypto/ted25519/ted25519/ed25519.go | 288 ++ pkg/crypto/ted25519/ted25519/ed25519_test.go | 165 + pkg/crypto/ted25519/ted25519/ext.go | 123 + pkg/crypto/ted25519/ted25519/ext_test.go | 113 + pkg/crypto/ted25519/ted25519/keygen.go | 240 + pkg/crypto/ted25519/ted25519/keygen_test.go | 125 + pkg/crypto/ted25519/ted25519/noncegen.go | 123 + pkg/crypto/ted25519/ted25519/noncegen_test.go | 106 + pkg/crypto/ted25519/ted25519/partialsig.go | 55 + .../ted25519/ted25519/partialsig_test.go | 56 + pkg/crypto/ted25519/ted25519/sigagg.go | 62 + pkg/crypto/ted25519/ted25519/sigagg_test.go | 93 + pkg/crypto/ted25519/ted25519/twobytwo_test.go | 55 + pkg/crypto/zkp/schnorr/schnorr.go | 140 + pkg/crypto/zkp/schnorr/schnorr_test.go | 37 + pkg/hway/README.md | 1 - pkg/hway/handlers/jsonrpc.go | 1 - pkg/hway/handlers/querier.go | 1 - pkg/hway/handlers/sync.go | 13 - pkg/hway/routes/routes.go | 16 - pkg/hway/types/api.pb.go | 535 -- pkg/hway/types/client.pb.go | 63 - pkg/motr/README.md | 1 - pkg/motr/config/init.pkl.go | 10 - pkg/motr/embed.go | 38 - pkg/motr/routes/routes.go | 26 - pkg/motr/static/index.go | 22 - pkg/motr/static/sw.js | 22 - pkg/motr/types/api.pb.go | 342 -- pkg/motr/types/orm/init.pkl.go | 17 - pkg/motr/types/orm/webauthn.go | 54 - pkg/nebula/README.md | 48 - pkg/nebula/assets/css/styles.css | 4366 ----------------- .../fonts/ZTBrosOskon90s-BoldSemExp.woff | Bin 52736 -> 0 bytes .../fonts/ZTBrosOskon90s-BoldSemExp.woff2 | Bin 37056 -> 0 bytes .../fonts/ZTBrosOskon90s-BoldSemExpIta.woff | Bin 56220 -> 0 bytes .../fonts/ZTBrosOskon90s-BoldSemExpIta.woff2 | Bin 39404 -> 0 bytes pkg/nebula/assets/js/alpin-focus.min.js | 15 - pkg/nebula/assets/js/alpine.min.js | 5 - pkg/nebula/assets/js/d3.min.js | 2 - pkg/nebula/assets/js/datamaps.world.min.js | 2 - pkg/nebula/assets/js/dexie.min.js | 2 - pkg/nebula/assets/js/htmx.min.js | 1 - pkg/nebula/assets/js/sw.js | 22 - pkg/nebula/assets/js/topojson.min.js | 2 - pkg/nebula/auth/authorize.templ | 17 - pkg/nebula/auth/authorize_templ.go | 58 - pkg/nebula/auth/login_templ.go | 58 - pkg/nebula/auth/register.templ | 15 - pkg/nebula/bun.lockb | Bin 109965 -> 0 bytes pkg/nebula/deps.mjs | 69 - pkg/nebula/forms/consent_privacy.templ | 11 - pkg/nebula/forms/consent_privacy_templ.go | 40 - pkg/nebula/global/state/database.templ | 28 - pkg/nebula/global/state/database_templ.go | 69 - pkg/nebula/global/state/worker.templ | 25 - pkg/nebula/global/ui/button.templ | 234 - pkg/nebula/global/ui/button_templ.go | 548 --- pkg/nebula/global/ui/icons.templ | 32 - pkg/nebula/global/ui/icons_templ.go | 100 - pkg/nebula/marketing/nav_header.templ | 32 - pkg/nebula/marketing/nav_header_templ.go | 40 - pkg/nebula/modals/authentication.templ | 28 - pkg/nebula/modals/intro_video.templ | 283 -- pkg/nebula/modals/intro_video_templ.go | 40 - pkg/nebula/routes/auth.go | 44 - pkg/nebula/routes/home.go | 23 - pkg/nebula/views/current.templ | 23 - pkg/nebula/views/index.templ | 29 - pkg/nebula/views/index_templ.go | 95 - pkg/services/credentials/credentials.go | 47 + pkg/services/credentials/manager.go | 10 + pkg/services/credentials/options.go | 6 + pkg/services/credentials/scripts.templ | 191 + pkg/services/credentials/scripts_templ.go | 154 + pkg/services/payments/payments.go | 94 + pkg/services/payments/scripts.templ | 150 + pkg/services/payments/scripts_templ.go | 138 + pkg/services/payments/utils.go | 7 + pkg/services/storage/scripts.templ | 82 + pkg/services/storage/scripts_templ.go | 189 + pkg/services/storage/storage.go | 15 + pkg/webapp/bun.lockb | Bin 0 -> 119323 bytes pkg/webapp/components/auth/authorize.templ | 12 + .../components/auth/authorize_templ.go} | 15 +- .../components/auth/create_credential.templ} | 2 +- .../auth/create_credential_templ.go} | 4 +- .../components/auth/get_credential.templ} | 2 +- .../components/auth/get_credential_templ.go} | 4 +- .../components}/auth/login.templ | 18 +- .../components/auth/login_templ.go} | 52 +- pkg/webapp/components/auth/register.templ | 41 + .../components/auth/register_start.templ} | 4 +- .../components/auth/register_start_templ.go} | 12 +- .../components/auth/register_templ.go} | 83 +- .../styles => webapp/components}/globals.css | 19 - .../components/landing/arch.templ} | 17 +- .../components/landing/arch_templ.go} | 53 +- .../components/landing/cta.templ} | 4 +- .../components/landing/cta_templ.go} | 6 +- .../components/landing/footer.templ} | 3 +- .../components/landing/footer_templ.go} | 5 +- pkg/webapp/components/landing/header.templ | 76 + pkg/webapp/components/landing/header_templ.go | 221 + .../components/landing/hero.templ} | 6 +- .../components/landing/hero_templ.go} | 30 +- .../components/landing/highlights.templ} | 4 +- .../components/landing/highlights_templ.go} | 30 +- .../components/landing/lowlights.templ} | 23 +- .../components/landing/lowlights_templ.go} | 39 +- .../components/landing/mission.templ} | 4 +- .../components/landing/mission_templ.go} | 24 +- .../components/ui/badges.templ} | 0 .../components/ui/badges_templ.go} | 2 +- pkg/webapp/components/ui/buttons.templ | 31 + pkg/webapp/components/ui/buttons_templ.go | 146 + .../components/ui/cards.templ} | 4 +- .../components/ui/cards_templ.go} | 8 +- pkg/webapp/components/ui/icon.templ | 53 + pkg/webapp/components/ui/icon_templ.go | 194 + .../components/ui}/layout.templ | 64 +- .../components/ui}/layout_templ.go | 126 +- .../components/ui/panels.templ} | 5 - .../components/ui/panels_templ.go} | 33 +- .../components/ui}/scripts.templ | 13 +- .../components/ui}/scripts_templ.go | 124 +- .../components/ui}/sizes.templ | 2 +- .../components/ui}/sizes_templ.go | 4 +- .../components/ui}/typography.templ | 2 +- .../components/ui}/typography_templ.go | 20 +- pkg/webapp/models/base.go | 12 + .../global/images.go => webapp/models/cdn.go} | 35 +- pkg/webapp/models/forms.go | 8 + .../types => webapp/models}/marketing.go | 2 +- pkg/webapp/models/page.go | 12 + pkg/{nebula => webapp}/package.json | 6 +- pkg/webapp/pages/auth.templ | 16 + .../pages/auth_templ.go} | 30 +- pkg/webapp/pages/dashboard.templ | 8 + pkg/webapp/pages/dashboard_templ.go | 56 + .../page.templ => webapp/pages/landing.templ} | 28 +- .../pages/landing_templ.go} | 30 +- pkg/{nebula => webapp}/tailwind.config.js | 3 +- pkl/README.md | 4 + pkl/base.types/Ctx.pkl | 36 + .../base.types}/DWN.pkl | 21 +- .../sonr.models.v1 => pkl/base.types}/ORM.pkl | 47 +- pkl/base.types/PklProject | 22 + pkl/base.types/PklProject.deps.json | 4 + pkl/basePklProject.pkl | 44 + pkl/chain.sonr/App.pkl | 89 + pkl/chain.sonr/Chain.pkl | 154 + pkl/chain.sonr/Genesis.pkl | 3 + pkl/chain.sonr/PklProject | 22 + pkl/chain.sonr/PklProject.deps.json | 4 + pkl/net.matrix/Homeserver.pkl | 198 + pkl/net.matrix/PklProject | 22 + pkl/net.matrix/PklProject.deps.json | 4 + pkl/net.matrix/Synapse.pkl | 198 + process-compose.yaml | 3 +- proto/buf.lock | 5 - proto/buf.yaml | 1 - proto/vault/v1/tx.proto | 26 + scripts/init_env.sh | 1 + scripts/protocgen.sh | 1 - third_party/pkl/README.md | 0 third_party/proto/README.md | 19 - third_party/proto/buf.gen.yaml | 7 - third_party/proto/buf.lock | 38 - third_party/proto/buf.yaml | 15 - third_party/proto/common/v1/ipfs.proto | 5 - third_party/proto/common/v1/keys.proto | 30 - third_party/proto/common/v1/uri.proto | 16 - third_party/proto/hway/v1/api.proto | 40 - third_party/proto/hway/v1/client.proto | 3 - third_party/proto/motr/v1/api.proto | 26 - web/README.md | 40 + web/Taskfile.yml | 86 + web/libs/noble-client | 1 + web/libs/osmosis-client | 1 + web/libs/sonr-client | 1 + x/did/controller/base.go | 59 +- x/did/controller/signer/actor.go | 1 - x/did/controller/signer/context.go | 1 - x/did/controller/wallet/txns.go | 1 - x/did/controller/wallet/wallet.go | 1 - x/did/keeper/genesis.go | 4 +- .../types/{accstd/exports.go => accounts.go} | 41 +- x/did/types/address.go | 52 + x/did/types/compute.go | 56 - x/did/types/did/crypto.go | 231 + x/did/types/did/crypto_test.go | 108 + x/did/types/did/did.go | 140 + x/did/types/did/did_test.go | 41 + .../internal/accounts/api_builder.go | 0 .../{accstd => }/internal/accounts/context.go | 2 +- .../internal/accounts/encoding.go | 0 .../internal/accounts/implementation.go | 0 .../internal/accounts/interface.go | 0 .../internal/accounts/protoaccount.go | 0 .../internal/prefixstore/prefixstore.go | 0 x/did/types/params.go | 8 +- x/did/{controller/wallet => types}/pubkey.go | 8 +- x/did/{controller/signer => types}/signer.go | 2 +- x/vault/keeper/keeper.go | 6 +- x/vault/keeper/querier.go | 8 +- x/vault/types/params.go | 19 +- x/vault/types/spawn.go | 42 + x/vault/types/static/index.html | 36 + x/vault/types/static/static.go | 11 + x/vault/types/static/sw.js | 258 + x/vault/types/vault.go | 31 - 549 files changed, 74162 insertions(+), 9856 deletions(-) create mode 100644 .air.toml delete mode 100644 cmd/dwn/main.go delete mode 100755 cmd/gateway/bun.lockb delete mode 100644 cmd/gateway/main.go delete mode 100644 cmd/gateway/wrangler.toml create mode 100644 cmd/hway/main.go create mode 100644 cmd/motr/main.go delete mode 100644 cmd/sonrd/motr.go delete mode 100644 pkg/common/README.md delete mode 100644 pkg/common/ctx/cookies.go delete mode 100644 pkg/common/ctx/ctx_dwn.go delete mode 100644 pkg/common/ctx/ctx_hway.go delete mode 100644 pkg/common/ctx/headers.go delete mode 100644 pkg/common/ctx/request.go delete mode 100644 pkg/common/ctx/response.go delete mode 100644 pkg/common/ctx/utils.go create mode 100644 pkg/common/httputil/get.go create mode 100644 pkg/common/ipfs/ipfs.go create mode 100644 pkg/common/middleware/cookie/cookie.go create mode 100644 pkg/common/middleware/cookie/keys.go create mode 100644 pkg/common/middleware/header/header.go create mode 100644 pkg/common/middleware/header/keys.go create mode 100644 pkg/common/middleware/request/cookies.go create mode 100644 pkg/common/middleware/request/headers.go create mode 100644 pkg/common/middleware/request/params.go create mode 100644 pkg/common/middleware/request/query.go create mode 100644 pkg/common/middleware/response/cache.go create mode 100644 pkg/common/middleware/response/cookies.go create mode 100644 pkg/common/middleware/response/headers.go create mode 100644 pkg/common/middleware/response/render.go create mode 100644 pkg/common/middleware/session/context.go create mode 100644 pkg/common/middleware/session/middleware.go create mode 100644 pkg/common/middleware/session/session.go create mode 100644 pkg/common/middleware/session/utils.go rename pkg/{motr/types/orm => common/models}/Account.pkl.go (85%) rename pkg/{motr/types/orm => common/models}/Asset.pkl.go (81%) rename pkg/{motr/types/orm => common/models}/Chain.pkl.go (79%) rename pkg/{motr/types/orm => common/models}/Credential.pkl.go (93%) rename pkg/{motr/types/orm => common/models}/DID.pkl.go (50%) rename pkg/{motr/types/orm => common/models}/Grant.pkl.go (85%) rename pkg/{motr/types/orm => common/models}/JWK.pkl.go (76%) rename pkg/{motr/types/orm => common/models}/Keyshare.pkl.go (79%) rename pkg/{motr/types/orm/Orm.pkl.go => common/models/ORM.pkl.go} (72%) rename pkg/{motr/types/orm => common/models}/Profile.pkl.go (87%) rename pkg/{motr/types/orm => common/models}/assettype/AssetType.pkl.go (92%) rename pkg/{motr/types/orm => common/models}/didmethod/DIDMethod.pkl.go (93%) create mode 100644 pkg/common/models/init.pkl.go rename pkg/{motr/types/orm => common/models}/keyalgorithm/KeyAlgorithm.pkl.go (93%) rename pkg/{motr/types/orm => common/models}/keycurve/KeyCurve.pkl.go (94%) rename pkg/{motr/types/orm => common/models}/keyencoding/KeyEncoding.pkl.go (91%) rename pkg/{motr/types/orm => common/models}/keyrole/KeyRole.pkl.go (92%) rename pkg/{motr/types/orm => common/models}/keysharerole/KeyShareRole.pkl.go (90%) rename pkg/{motr/types/orm => common/models}/keytype/KeyType.pkl.go (93%) rename pkg/{motr/types/orm => common/models}/permissiongrant/PermissionGrant.pkl.go (93%) rename pkg/{motr/types/orm => common/models}/permissionscope/PermissionScope.pkl.go (94%) rename pkg/{motr/types/orm => common}/schema.go (97%) create mode 100644 pkg/common/session.go create mode 100644 pkg/common/types/Ctx.pkl.go create mode 100644 pkg/common/types/Session.pkl.go create mode 100644 pkg/common/types/init.pkl.go delete mode 100644 pkg/common/types/ipfs.pb.go delete mode 100644 pkg/common/types/keys.pb.go delete mode 100644 pkg/common/types/uri.pb.go rename pkg/{motr/config => core/dwn}/Config.pkl.go (86%) rename pkg/{motr/config/Dwn.pkl.go => core/dwn/DWN.pkl.go} (70%) create mode 100644 pkg/core/dwn/Environment.pkl.go rename pkg/{motr/config => core/dwn}/Schema.pkl.go (86%) create mode 100644 pkg/core/dwn/bridge/fetch.go create mode 100644 pkg/core/dwn/bridge/wasm.go create mode 100644 pkg/core/dwn/dwn.go rename pkg/{motr => core/dwn}/handlers/auth.go (90%) rename pkg/{motr => core/dwn}/handlers/openid.go (100%) create mode 100644 pkg/core/dwn/handlers/worker.go create mode 100644 pkg/core/dwn/init.pkl.go create mode 100644 pkg/core/dwn/server/server.go create mode 100755 pkg/crypto/accumulator/accumulator.go create mode 100755 pkg/crypto/accumulator/accumulator_test.go create mode 100755 pkg/crypto/accumulator/key.go create mode 100755 pkg/crypto/accumulator/key_test.go create mode 100755 pkg/crypto/accumulator/lib.go create mode 100755 pkg/crypto/accumulator/lib_test.go create mode 100755 pkg/crypto/accumulator/proof.go create mode 100755 pkg/crypto/accumulator/proof_test.go create mode 100755 pkg/crypto/accumulator/witness.go create mode 100755 pkg/crypto/accumulator/witness_test.go create mode 100644 pkg/crypto/bip32/bip32.go create mode 100755 pkg/crypto/bulletproof/generators.go create mode 100755 pkg/crypto/bulletproof/generators_test.go create mode 100755 pkg/crypto/bulletproof/helpers.go create mode 100755 pkg/crypto/bulletproof/helpers_test.go create mode 100755 pkg/crypto/bulletproof/ipp_prover.go create mode 100755 pkg/crypto/bulletproof/ipp_prover_test.go create mode 100755 pkg/crypto/bulletproof/ipp_verifier.go create mode 100755 pkg/crypto/bulletproof/ipp_verifier_test.go create mode 100755 pkg/crypto/bulletproof/range_batch_prover.go create mode 100755 pkg/crypto/bulletproof/range_batch_prover_test.go create mode 100755 pkg/crypto/bulletproof/range_batch_verifier.go create mode 100755 pkg/crypto/bulletproof/range_batch_verifier_test.go create mode 100755 pkg/crypto/bulletproof/range_prover.go create mode 100755 pkg/crypto/bulletproof/range_prover_test.go create mode 100755 pkg/crypto/bulletproof/range_verifier.go create mode 100755 pkg/crypto/bulletproof/range_verifier_test.go create mode 100755 pkg/crypto/core/README.md create mode 100755 pkg/crypto/core/commit.go create mode 100755 pkg/crypto/core/commit_test.go create mode 100755 pkg/crypto/core/curves/bls12377_curve.go create mode 100755 pkg/crypto/core/curves/bls12381_curve.go create mode 100755 pkg/crypto/core/curves/curve.go create mode 100755 pkg/crypto/core/curves/ec_point.go create mode 100755 pkg/crypto/core/curves/ec_point_test.go create mode 100755 pkg/crypto/core/curves/ec_scalar.go create mode 100755 pkg/crypto/core/curves/ecdsa.go create mode 100755 pkg/crypto/core/curves/ed25519_curve.go create mode 100755 pkg/crypto/core/curves/ed25519_curve_test.go create mode 100755 pkg/crypto/core/curves/field.go create mode 100755 pkg/crypto/core/curves/field_test.go create mode 100755 pkg/crypto/core/curves/k256_bench_test.go create mode 100755 pkg/crypto/core/curves/k256_curve.go create mode 100755 pkg/crypto/core/curves/k256_curve_test.go create mode 100755 pkg/crypto/core/curves/native/bls12381/bls12381.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fp.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fp12.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fp12_test.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fp2.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fp2_test.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fp6.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fp6_test.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fp_test.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fq.go create mode 100755 pkg/crypto/core/curves/native/bls12381/fq_test.go create mode 100755 pkg/crypto/core/curves/native/bls12381/g1.go create mode 100755 pkg/crypto/core/curves/native/bls12381/g1_test.go create mode 100755 pkg/crypto/core/curves/native/bls12381/g2.go create mode 100755 pkg/crypto/core/curves/native/bls12381/g2_test.go create mode 100755 pkg/crypto/core/curves/native/bls12381/gt.go create mode 100755 pkg/crypto/core/curves/native/bls12381/pairings.go create mode 100755 pkg/crypto/core/curves/native/bls12381/pairings_test.go create mode 100755 pkg/crypto/core/curves/native/field.go create mode 100755 pkg/crypto/core/curves/native/hash2field.go create mode 100755 pkg/crypto/core/curves/native/isogeny.go create mode 100755 pkg/crypto/core/curves/native/k256/fp/fp.go create mode 100755 pkg/crypto/core/curves/native/k256/fp/fp_test.go create mode 100755 pkg/crypto/core/curves/native/k256/fp/secp256k1_fp.go create mode 100755 pkg/crypto/core/curves/native/k256/fq/fq.go create mode 100755 pkg/crypto/core/curves/native/k256/fq/fq_test.go create mode 100755 pkg/crypto/core/curves/native/k256/fq/secp256k1_fq.go create mode 100755 pkg/crypto/core/curves/native/k256/point.go create mode 100755 pkg/crypto/core/curves/native/k256/point_test.go create mode 100755 pkg/crypto/core/curves/native/osswu.go create mode 100755 pkg/crypto/core/curves/native/p256/fp/fp.go create mode 100755 pkg/crypto/core/curves/native/p256/fp/fp_test.go create mode 100755 pkg/crypto/core/curves/native/p256/fp/p256_fp.go create mode 100755 pkg/crypto/core/curves/native/p256/fq/fq.go create mode 100755 pkg/crypto/core/curves/native/p256/fq/fq_test.go create mode 100755 pkg/crypto/core/curves/native/p256/fq/p256_fq.go create mode 100755 pkg/crypto/core/curves/native/p256/point.go create mode 100755 pkg/crypto/core/curves/native/p256/point_test.go create mode 100755 pkg/crypto/core/curves/native/pasta/README.md create mode 100755 pkg/crypto/core/curves/native/pasta/fp/fp.go create mode 100755 pkg/crypto/core/curves/native/pasta/fp/fp_test.go create mode 100755 pkg/crypto/core/curves/native/pasta/fp/pasta_fp.go create mode 100755 pkg/crypto/core/curves/native/pasta/fq/fq.go create mode 100755 pkg/crypto/core/curves/native/pasta/fq/fq_test.go create mode 100755 pkg/crypto/core/curves/native/pasta/fq/pasta_fq.go create mode 100755 pkg/crypto/core/curves/native/pasta/pallas.go create mode 100755 pkg/crypto/core/curves/native/point.go create mode 100755 pkg/crypto/core/curves/p256_bench_test.go create mode 100755 pkg/crypto/core/curves/p256_curve.go create mode 100755 pkg/crypto/core/curves/p256_curve_test.go create mode 100755 pkg/crypto/core/curves/pallas_curve.go create mode 100755 pkg/crypto/core/curves/pallas_curve_test.go create mode 100644 pkg/crypto/core/curves/secp256k1/secp256k1.go create mode 100644 pkg/crypto/core/curves/sp256_curve.go create mode 100755 pkg/crypto/core/hash.go create mode 100755 pkg/crypto/core/hash_test.go create mode 100755 pkg/crypto/core/mod.go create mode 100755 pkg/crypto/core/mod_test.go create mode 100755 pkg/crypto/core/primes.go create mode 100755 pkg/crypto/core/protocol/protocol.go create mode 100644 pkg/crypto/daed/aes_siv.go create mode 100644 pkg/crypto/daed/aes_siv_test.go create mode 100755 pkg/crypto/dkg/frost/README.md create mode 100755 pkg/crypto/dkg/frost/dkg_round1.go create mode 100755 pkg/crypto/dkg/frost/dkg_round2.go create mode 100755 pkg/crypto/dkg/frost/dkg_rounds_test.go create mode 100755 pkg/crypto/dkg/frost/participant.go create mode 100755 pkg/crypto/dkg/gennaro/README.md create mode 100755 pkg/crypto/dkg/gennaro/participant.go create mode 100755 pkg/crypto/dkg/gennaro/participant_test.go create mode 100755 pkg/crypto/dkg/gennaro/round1.go create mode 100755 pkg/crypto/dkg/gennaro/round2.go create mode 100755 pkg/crypto/dkg/gennaro/round3.go create mode 100755 pkg/crypto/dkg/gennaro/round4.go create mode 100755 pkg/crypto/dkg/gennaro/rounds_test.go create mode 100755 pkg/crypto/dkg/gennaro2p/README.md create mode 100755 pkg/crypto/dkg/gennaro2p/genarro2p.go create mode 100755 pkg/crypto/dkg/gennaro2p/genarro2p_test.go create mode 100644 pkg/crypto/ecies/encrypt.go create mode 100644 pkg/crypto/ecies/keys.go create mode 100644 pkg/crypto/ecies/keys_test.go create mode 100755 pkg/crypto/internal/err.go create mode 100755 pkg/crypto/internal/hash.go create mode 100755 pkg/crypto/internal/hash_test.go create mode 100755 pkg/crypto/internal/point.go create mode 100755 pkg/crypto/internal/testutils.go create mode 100644 pkg/crypto/mpc/caps.go create mode 100644 pkg/crypto/mpc/jwt.go create mode 100644 pkg/crypto/mpc/mpc.go create mode 100644 pkg/crypto/mpc/mpc_test.go create mode 100644 pkg/crypto/mpc/share.go create mode 100644 pkg/crypto/mpc/source.go create mode 100644 pkg/crypto/mpc/ucan.go create mode 100644 pkg/crypto/mpc/utils.go create mode 100755 pkg/crypto/ot/base/simplest/ot.go create mode 100755 pkg/crypto/ot/base/simplest/ot_test.go create mode 100755 pkg/crypto/ot/base/simplest/stream.go create mode 100755 pkg/crypto/ot/base/simplest/util.go create mode 100755 pkg/crypto/ot/extension/kos/kos.go create mode 100755 pkg/crypto/ot/extension/kos/kos_test.go create mode 100755 pkg/crypto/ot/extension/kos/stream.go create mode 100755 pkg/crypto/ot/ottest/util.go create mode 100755 pkg/crypto/paillier/README.md create mode 100755 pkg/crypto/paillier/paillier.go create mode 100755 pkg/crypto/paillier/psf.go create mode 100755 pkg/crypto/paillier/psf_test.go create mode 100755 pkg/crypto/sharing/README.md create mode 100755 pkg/crypto/sharing/ed25519_feldman_test.go create mode 100755 pkg/crypto/sharing/feldman.go create mode 100755 pkg/crypto/sharing/pedersen.go create mode 100755 pkg/crypto/sharing/polynomial.go create mode 100755 pkg/crypto/sharing/polynomial_test.go create mode 100755 pkg/crypto/sharing/shamir.go create mode 100755 pkg/crypto/sharing/shamir_test.go create mode 100755 pkg/crypto/sharing/v1/bls12381g1_feldman_test.go create mode 100755 pkg/crypto/sharing/v1/bls12381g1curve.go create mode 100755 pkg/crypto/sharing/v1/bls12381g2_feldman_test.go create mode 100755 pkg/crypto/sharing/v1/bls12381g2curve.go create mode 100755 pkg/crypto/sharing/v1/common.go create mode 100755 pkg/crypto/sharing/v1/ed25519_feldman_test.go create mode 100755 pkg/crypto/sharing/v1/ed25519_pedersen_test.go create mode 100755 pkg/crypto/sharing/v1/ed25519curve.go create mode 100755 pkg/crypto/sharing/v1/ed25519curve_test.go create mode 100755 pkg/crypto/sharing/v1/feldman.go create mode 100755 pkg/crypto/sharing/v1/k256_feldman_test.go create mode 100755 pkg/crypto/sharing/v1/k256_pedersen_test.go create mode 100755 pkg/crypto/sharing/v1/p256_feldman_test.go create mode 100755 pkg/crypto/sharing/v1/pedersen.go create mode 100755 pkg/crypto/sharing/v1/polynomial.go create mode 100755 pkg/crypto/sharing/v1/polynomial_test.go create mode 100755 pkg/crypto/sharing/v1/shamir.go create mode 100755 pkg/crypto/sharing/v1/shamir_test.go create mode 100755 pkg/crypto/signatures/bbs/blind_signature.go create mode 100755 pkg/crypto/signatures/bbs/blind_signature_context.go create mode 100755 pkg/crypto/signatures/bbs/blind_signature_context_test.go create mode 100755 pkg/crypto/signatures/bbs/message_generators.go create mode 100755 pkg/crypto/signatures/bbs/pok_signature.go create mode 100755 pkg/crypto/signatures/bbs/pok_signature_proof.go create mode 100755 pkg/crypto/signatures/bbs/pok_signature_proof_test.go create mode 100755 pkg/crypto/signatures/bbs/public_key.go create mode 100755 pkg/crypto/signatures/bbs/secret_key.go create mode 100755 pkg/crypto/signatures/bbs/signature.go create mode 100755 pkg/crypto/signatures/bbs/signature_test.go create mode 100755 pkg/crypto/signatures/bls/README.md create mode 100755 pkg/crypto/signatures/bls/bls_sig/lib.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/lib_test.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/tiny_bls.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_aug_test.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_basic_test.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_pop_test.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/usual_bls.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/usual_bls_sig.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_aug_test.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_basic_test.go create mode 100755 pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_pop_test.go create mode 100755 pkg/crypto/signatures/bls/rust/Cargo.toml create mode 100755 pkg/crypto/signatures/bls/rust/README.md create mode 100755 pkg/crypto/signatures/bls/rust/src/main.rs create mode 100755 pkg/crypto/signatures/bls/tests/bls/main.go create mode 100755 pkg/crypto/signatures/bls/tmp.json create mode 100755 pkg/crypto/signatures/common/challenge.go create mode 100755 pkg/crypto/signatures/common/commitment.go create mode 100755 pkg/crypto/signatures/common/hmacdrbg.go create mode 100755 pkg/crypto/signatures/common/nonce.go create mode 100755 pkg/crypto/signatures/common/proof_committed_builder.go create mode 100755 pkg/crypto/signatures/common/proof_message.go create mode 100755 pkg/crypto/signatures/common/signature_blinding.go create mode 100755 pkg/crypto/signatures/schnorr/mina/bitvector.go create mode 100755 pkg/crypto/signatures/schnorr/mina/challenge_derive.go create mode 100755 pkg/crypto/signatures/schnorr/mina/keys.go create mode 100755 pkg/crypto/signatures/schnorr/mina/keys_test.go create mode 100755 pkg/crypto/signatures/schnorr/mina/poseidon_config.go create mode 100755 pkg/crypto/signatures/schnorr/mina/poseidon_hash.go create mode 100755 pkg/crypto/signatures/schnorr/mina/poseidon_hash_test.go create mode 100755 pkg/crypto/signatures/schnorr/mina/roinput.go create mode 100755 pkg/crypto/signatures/schnorr/mina/signature.go create mode 100755 pkg/crypto/signatures/schnorr/mina/txn.go create mode 100755 pkg/crypto/signatures/schnorr/nem/ed25519_keccak.go create mode 100755 pkg/crypto/signatures/schnorr/nem/ed25519_keccak_test.go create mode 100644 pkg/crypto/subtle/hkdf.go create mode 100644 pkg/crypto/subtle/random/random.go create mode 100644 pkg/crypto/subtle/subtle.go create mode 100644 pkg/crypto/subtle/x25519.go create mode 100755 pkg/crypto/tecdsa/dklsv1/README.md create mode 100755 pkg/crypto/tecdsa/dklsv1/boilerplate.go create mode 100755 pkg/crypto/tecdsa/dklsv1/dealer/dealer.go create mode 100755 pkg/crypto/tecdsa/dklsv1/dealer/dealer_test.go create mode 100755 pkg/crypto/tecdsa/dklsv1/dkg/dkg.go create mode 100755 pkg/crypto/tecdsa/dklsv1/dkg/dkg_test.go create mode 100755 pkg/crypto/tecdsa/dklsv1/dkgserializers.go create mode 100755 pkg/crypto/tecdsa/dklsv1/protocol.go create mode 100755 pkg/crypto/tecdsa/dklsv1/protocol_test.go create mode 100755 pkg/crypto/tecdsa/dklsv1/refresh/refresh.go create mode 100755 pkg/crypto/tecdsa/dklsv1/refresh/refresh_test.go create mode 100755 pkg/crypto/tecdsa/dklsv1/refreshserializers.go create mode 100755 pkg/crypto/tecdsa/dklsv1/sign/multiply.go create mode 100755 pkg/crypto/tecdsa/dklsv1/sign/multiply_test.go create mode 100755 pkg/crypto/tecdsa/dklsv1/sign/sign.go create mode 100755 pkg/crypto/tecdsa/dklsv1/sign/sign_test.go create mode 100755 pkg/crypto/tecdsa/dklsv1/signserializers.go create mode 100755 pkg/crypto/tecdsa/dklsv1/testdata/alice-dkls-v1-dkg.bin create mode 100755 pkg/crypto/tecdsa/dklsv1/testdata/bob-dkls-v1-dkg.bin create mode 100755 pkg/crypto/ted25519/frost/README.md create mode 100755 pkg/crypto/ted25519/frost/challenge_derive.go create mode 100755 pkg/crypto/ted25519/frost/participant.go create mode 100755 pkg/crypto/ted25519/frost/round1.go create mode 100755 pkg/crypto/ted25519/frost/round2.go create mode 100755 pkg/crypto/ted25519/frost/round3.go create mode 100755 pkg/crypto/ted25519/frost/rounds_test.go create mode 100755 pkg/crypto/ted25519/ted25519/ed25519.go create mode 100755 pkg/crypto/ted25519/ted25519/ed25519_test.go create mode 100755 pkg/crypto/ted25519/ted25519/ext.go create mode 100755 pkg/crypto/ted25519/ted25519/ext_test.go create mode 100755 pkg/crypto/ted25519/ted25519/keygen.go create mode 100755 pkg/crypto/ted25519/ted25519/keygen_test.go create mode 100755 pkg/crypto/ted25519/ted25519/noncegen.go create mode 100755 pkg/crypto/ted25519/ted25519/noncegen_test.go create mode 100755 pkg/crypto/ted25519/ted25519/partialsig.go create mode 100755 pkg/crypto/ted25519/ted25519/partialsig_test.go create mode 100755 pkg/crypto/ted25519/ted25519/sigagg.go create mode 100755 pkg/crypto/ted25519/ted25519/sigagg_test.go create mode 100755 pkg/crypto/ted25519/ted25519/twobytwo_test.go create mode 100755 pkg/crypto/zkp/schnorr/schnorr.go create mode 100755 pkg/crypto/zkp/schnorr/schnorr_test.go delete mode 100644 pkg/hway/README.md delete mode 100644 pkg/hway/handlers/jsonrpc.go delete mode 100644 pkg/hway/handlers/querier.go delete mode 100644 pkg/hway/handlers/sync.go delete mode 100644 pkg/hway/routes/routes.go delete mode 100644 pkg/hway/types/api.pb.go delete mode 100644 pkg/hway/types/client.pb.go delete mode 100644 pkg/motr/README.md delete mode 100644 pkg/motr/config/init.pkl.go delete mode 100644 pkg/motr/embed.go delete mode 100644 pkg/motr/routes/routes.go delete mode 100644 pkg/motr/static/index.go delete mode 100644 pkg/motr/static/sw.js delete mode 100644 pkg/motr/types/api.pb.go delete mode 100644 pkg/motr/types/orm/init.pkl.go delete mode 100644 pkg/motr/types/orm/webauthn.go delete mode 100644 pkg/nebula/README.md delete mode 100644 pkg/nebula/assets/css/styles.css delete mode 100644 pkg/nebula/assets/fonts/ZTBrosOskon90s-BoldSemExp.woff delete mode 100644 pkg/nebula/assets/fonts/ZTBrosOskon90s-BoldSemExp.woff2 delete mode 100644 pkg/nebula/assets/fonts/ZTBrosOskon90s-BoldSemExpIta.woff delete mode 100644 pkg/nebula/assets/fonts/ZTBrosOskon90s-BoldSemExpIta.woff2 delete mode 100644 pkg/nebula/assets/js/alpin-focus.min.js delete mode 100644 pkg/nebula/assets/js/alpine.min.js delete mode 100644 pkg/nebula/assets/js/d3.min.js delete mode 100644 pkg/nebula/assets/js/datamaps.world.min.js delete mode 100644 pkg/nebula/assets/js/dexie.min.js delete mode 100644 pkg/nebula/assets/js/htmx.min.js delete mode 100644 pkg/nebula/assets/js/sw.js delete mode 100644 pkg/nebula/assets/js/topojson.min.js delete mode 100644 pkg/nebula/auth/authorize.templ delete mode 100644 pkg/nebula/auth/authorize_templ.go delete mode 100644 pkg/nebula/auth/login_templ.go delete mode 100644 pkg/nebula/auth/register.templ delete mode 100755 pkg/nebula/bun.lockb delete mode 100644 pkg/nebula/deps.mjs delete mode 100644 pkg/nebula/forms/consent_privacy.templ delete mode 100644 pkg/nebula/forms/consent_privacy_templ.go delete mode 100644 pkg/nebula/global/state/database.templ delete mode 100644 pkg/nebula/global/state/database_templ.go delete mode 100644 pkg/nebula/global/state/worker.templ delete mode 100644 pkg/nebula/global/ui/button.templ delete mode 100644 pkg/nebula/global/ui/button_templ.go delete mode 100644 pkg/nebula/global/ui/icons.templ delete mode 100644 pkg/nebula/global/ui/icons_templ.go delete mode 100644 pkg/nebula/marketing/nav_header.templ delete mode 100644 pkg/nebula/marketing/nav_header_templ.go delete mode 100644 pkg/nebula/modals/authentication.templ delete mode 100644 pkg/nebula/modals/intro_video.templ delete mode 100644 pkg/nebula/modals/intro_video_templ.go delete mode 100644 pkg/nebula/routes/auth.go delete mode 100644 pkg/nebula/routes/home.go delete mode 100644 pkg/nebula/views/current.templ delete mode 100644 pkg/nebula/views/index.templ delete mode 100644 pkg/nebula/views/index_templ.go create mode 100644 pkg/services/credentials/credentials.go create mode 100644 pkg/services/credentials/manager.go create mode 100644 pkg/services/credentials/options.go create mode 100644 pkg/services/credentials/scripts.templ create mode 100644 pkg/services/credentials/scripts_templ.go create mode 100644 pkg/services/payments/payments.go create mode 100644 pkg/services/payments/scripts.templ create mode 100644 pkg/services/payments/scripts_templ.go create mode 100644 pkg/services/payments/utils.go create mode 100644 pkg/services/storage/scripts.templ create mode 100644 pkg/services/storage/scripts_templ.go create mode 100644 pkg/services/storage/storage.go create mode 100755 pkg/webapp/bun.lockb create mode 100644 pkg/webapp/components/auth/authorize.templ rename pkg/{nebula/global/state/worker_templ.go => webapp/components/auth/authorize_templ.go} (66%) rename pkg/{nebula/forms/credential_register.templ => webapp/components/auth/create_credential.templ} (99%) rename pkg/{nebula/forms/credential_register_templ.go => webapp/components/auth/create_credential_templ.go} (99%) rename pkg/{nebula/forms/credential_assert.templ => webapp/components/auth/get_credential.templ} (99%) rename pkg/{nebula/forms/credential_assert_templ.go => webapp/components/auth/get_credential_templ.go} (98%) rename pkg/{nebula => webapp/components}/auth/login.templ (67%) rename pkg/{nebula/auth/register_templ.go => webapp/components/auth/login_templ.go} (62%) create mode 100644 pkg/webapp/components/auth/register.templ rename pkg/{nebula/forms/details_basic.templ => webapp/components/auth/register_start.templ} (98%) rename pkg/{nebula/forms/details_basic_templ.go => webapp/components/auth/register_start_templ.go} (95%) rename pkg/{nebula/modals/authentication_templ.go => webapp/components/auth/register_templ.go} (51%) rename pkg/{nebula/global/styles => webapp/components}/globals.css (87%) rename pkg/{nebula/marketing/section_arch.templ => webapp/components/landing/arch.templ} (96%) rename pkg/{nebula/marketing/section_arch_templ.go => webapp/components/landing/arch_templ.go} (87%) rename pkg/{nebula/marketing/section_cta.templ => webapp/components/landing/cta.templ} (99%) rename pkg/{nebula/marketing/section_cta_templ.go => webapp/components/landing/cta_templ.go} (99%) rename pkg/{nebula/marketing/nav_footer.templ => webapp/components/landing/footer.templ} (99%) rename pkg/{nebula/marketing/nav_footer_templ.go => webapp/components/landing/footer_templ.go} (99%) create mode 100644 pkg/webapp/components/landing/header.templ create mode 100644 pkg/webapp/components/landing/header_templ.go rename pkg/{nebula/marketing/section_hero.templ => webapp/components/landing/hero.templ} (98%) rename pkg/{nebula/marketing/section_hero_templ.go => webapp/components/landing/hero_templ.go} (93%) rename pkg/{nebula/marketing/section_highlights.templ => webapp/components/landing/highlights.templ} (98%) rename pkg/{nebula/marketing/section_highlights_templ.go => webapp/components/landing/highlights_templ.go} (89%) rename pkg/{nebula/marketing/section_lowlights.templ => webapp/components/landing/lowlights.templ} (93%) rename pkg/{nebula/marketing/section_lowlights_templ.go => webapp/components/landing/lowlights_templ.go} (90%) rename pkg/{nebula/marketing/section_mission.templ => webapp/components/landing/mission.templ} (99%) rename pkg/{nebula/marketing/section_mission_templ.go => webapp/components/landing/mission_templ.go} (94%) rename pkg/{nebula/global/ui/badge.templ => webapp/components/ui/badges.templ} (100%) rename pkg/{nebula/global/ui/badge_templ.go => webapp/components/ui/badges_templ.go} (99%) create mode 100644 pkg/webapp/components/ui/buttons.templ create mode 100644 pkg/webapp/components/ui/buttons_templ.go rename pkg/{nebula/global/ui/card.templ => webapp/components/ui/cards.templ} (95%) rename pkg/{nebula/global/ui/card_templ.go => webapp/components/ui/cards_templ.go} (95%) create mode 100644 pkg/webapp/components/ui/icon.templ create mode 100644 pkg/webapp/components/ui/icon_templ.go rename pkg/{nebula/global/styles => webapp/components/ui}/layout.templ (56%) rename pkg/{nebula/global/styles => webapp/components/ui}/layout_templ.go (70%) rename pkg/{nebula/global/ui/panel.templ => webapp/components/ui/panels.templ} (97%) rename pkg/{nebula/global/ui/panel_templ.go => webapp/components/ui/panels_templ.go} (88%) rename pkg/{nebula/global/styles => webapp/components/ui}/scripts.templ (84%) rename pkg/{nebula/global/styles => webapp/components/ui}/scripts_templ.go (81%) rename pkg/{nebula/global/styles => webapp/components/ui}/sizes.templ (98%) rename pkg/{nebula/global/styles => webapp/components/ui}/sizes_templ.go (96%) rename pkg/{nebula/global/styles => webapp/components/ui}/typography.templ (98%) rename pkg/{nebula/global/styles => webapp/components/ui}/typography_templ.go (91%) create mode 100644 pkg/webapp/models/base.go rename pkg/{nebula/global/images.go => webapp/models/cdn.go} (66%) create mode 100644 pkg/webapp/models/forms.go rename pkg/{nebula/types => webapp/models}/marketing.go (99%) create mode 100644 pkg/webapp/models/page.go rename pkg/{nebula => webapp}/package.json (50%) create mode 100644 pkg/webapp/pages/auth.templ rename pkg/{nebula/views/current_templ.go => webapp/pages/auth_templ.go} (60%) create mode 100644 pkg/webapp/pages/dashboard.templ create mode 100644 pkg/webapp/pages/dashboard_templ.go rename pkg/{nebula/marketing/page.templ => webapp/pages/landing.templ} (55%) rename pkg/{nebula/marketing/page_templ.go => webapp/pages/landing_templ.go} (80%) rename pkg/{nebula => webapp}/tailwind.config.js (96%) create mode 100644 pkl/README.md create mode 100644 pkl/base.types/Ctx.pkl rename {third_party/pkl/src/sonr.configs.v1 => pkl/base.types}/DWN.pkl (71%) rename {third_party/pkl/src/sonr.models.v1 => pkl/base.types}/ORM.pkl (97%) create mode 100644 pkl/base.types/PklProject create mode 100644 pkl/base.types/PklProject.deps.json create mode 100644 pkl/basePklProject.pkl create mode 100644 pkl/chain.sonr/App.pkl create mode 100644 pkl/chain.sonr/Chain.pkl create mode 100644 pkl/chain.sonr/Genesis.pkl create mode 100644 pkl/chain.sonr/PklProject create mode 100644 pkl/chain.sonr/PklProject.deps.json create mode 100644 pkl/net.matrix/Homeserver.pkl create mode 100644 pkl/net.matrix/PklProject create mode 100644 pkl/net.matrix/PklProject.deps.json create mode 100644 pkl/net.matrix/Synapse.pkl create mode 100644 scripts/init_env.sh delete mode 100644 third_party/pkl/README.md delete mode 100644 third_party/proto/README.md delete mode 100644 third_party/proto/buf.gen.yaml delete mode 100644 third_party/proto/buf.lock delete mode 100644 third_party/proto/buf.yaml delete mode 100644 third_party/proto/common/v1/ipfs.proto delete mode 100644 third_party/proto/common/v1/keys.proto delete mode 100644 third_party/proto/common/v1/uri.proto delete mode 100644 third_party/proto/hway/v1/api.proto delete mode 100644 third_party/proto/hway/v1/client.proto delete mode 100644 third_party/proto/motr/v1/api.proto create mode 100644 web/README.md create mode 100644 web/Taskfile.yml create mode 160000 web/libs/noble-client create mode 160000 web/libs/osmosis-client create mode 160000 web/libs/sonr-client delete mode 100644 x/did/controller/signer/actor.go delete mode 100644 x/did/controller/signer/context.go delete mode 100644 x/did/controller/wallet/txns.go delete mode 100644 x/did/controller/wallet/wallet.go rename x/did/types/{accstd/exports.go => accounts.go} (75%) create mode 100644 x/did/types/address.go delete mode 100644 x/did/types/compute.go create mode 100644 x/did/types/did/crypto.go create mode 100644 x/did/types/did/crypto_test.go create mode 100644 x/did/types/did/did.go create mode 100644 x/did/types/did/did_test.go rename x/did/types/{accstd => }/internal/accounts/api_builder.go (100%) rename x/did/types/{accstd => }/internal/accounts/context.go (98%) rename x/did/types/{accstd => }/internal/accounts/encoding.go (100%) rename x/did/types/{accstd => }/internal/accounts/implementation.go (100%) rename x/did/types/{accstd => }/internal/accounts/interface.go (100%) rename x/did/types/{accstd => }/internal/accounts/protoaccount.go (100%) rename x/did/types/{accstd => }/internal/prefixstore/prefixstore.go (100%) rename x/did/{controller/wallet => types}/pubkey.go (96%) rename x/did/{controller/signer => types}/signer.go (97%) create mode 100644 x/vault/types/spawn.go create mode 100644 x/vault/types/static/index.html create mode 100644 x/vault/types/static/static.go create mode 100644 x/vault/types/static/sw.js delete mode 100644 x/vault/types/vault.go diff --git a/.air.toml b/.air.toml new file mode 100644 index 000000000..4fa150e97 --- /dev/null +++ b/.air.toml @@ -0,0 +1,51 @@ +root = "." +testdata_dir = "testdata" +tmp_dir = "tmp" + +[build] +args_bin = [] +bin = "./tmp/main" +cmd = "go build -o ./tmp/main ./cmd/hway/main.go" +delay = 1000 +exclude_dir = ["assets", "tmp", "vendor", "testdata", "pkg/webapp/node_modules"] +exclude_file = [] +exclude_regex = ["_test.go", "_templ.go"] +exclude_unchanged = true +follow_symlink = false +full_bin = "" +include_dir = ["pkg/webapp"] +include_ext = ["go", "tpl", "templ", "html"] +include_file = [] +kill_delay = "0s" +log = "build-errors.log" +poll = false +poll_interval = 0 +post_cmd = [] +pre_cmd = ["templ generate"] +rerun = false +rerun_delay = 500 +send_interrupt = false +stop_on_error = false + +[color] +app = "" +build = "yellow" +main = "magenta" +runner = "green" +watcher = "cyan" + +[log] +main_only = false +time = false + +[misc] +clean_on_exit = false + +[proxy] +app_port = 3000 +enabled = false +proxy_port = 8787 + +[screen] +clear_on_rebuild = true +keep_scroll = true diff --git a/.gitignore b/.gitignore index 7dd9471b5..bf539aa30 100644 --- a/.gitignore +++ b/.gitignore @@ -15,9 +15,13 @@ dist *.test .devon* **/.DS_Store +.task +.wrangler + # Output of the go coverage tool *.out - +.air.toml +tmp # Exclude embedded files !internal/files/dist diff --git a/Makefile b/Makefile index b12a05119..87cf4f835 100644 --- a/Makefile +++ b/Makefile @@ -94,7 +94,6 @@ endif install: go.sum go install -mod=readonly $(BUILD_FLAGS) ./cmd/sonrd - go install -mod=readonly $(BUILD_FLAGS) ./cmd/hway ######################################## ### Tools & dependencies @@ -289,22 +288,6 @@ sh-testnet: mod-tidy .PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet - -############################################################################### -### custom generation ### -############################################################################### - -.PHONY: templ-gen pkl-gen - -templ-gen: - @echo "(templ) Generating templ files" - templ generate - -pkl-gen: - @echo "(pkl) Building PKL" - go run github.com/apple/pkl-go/cmd/pkl-gen-go ./third_party/pkl/src/sonr.configs.v1/DWN.pkl - go run github.com/apple/pkl-go/cmd/pkl-gen-go ./third_party/pkl/src/sonr.models.v1/ORM.pkl - ############################################################################### ### help ### ############################################################################### diff --git a/Taskfile.yml b/Taskfile.yml index 7c472ea43..652684c07 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,86 +1,86 @@ version: "3" vars: ROOT_DIR: - sh: pwd + sh: git rev-parse --show-toplevel tasks: - hway:assets: + clean: internal: true cmds: - - go run github.com/syumai/workers/cmd/workers-assets-gen -mode=go -o ./cmd/gateway/build + - rm -rf .task + - rm -rf pkg/design/node_modules + - rm -rf .out - hway:build: - dir: cmd/gateway - env: - GOOS: js - GOARCH: wasm - cmds: - - task: hway:assets - - go build -o build/app.wasm main.go + # ╭──────────────────────────────────────────────────╮ + # │ Generate Commands │ + # ╰──────────────────────────────────────────────────╯ - hway:dev: - dir: cmd/gateway + gen:tailwind: cmds: - - task: nebula:build - - bunx wrangler dev + - cd ./pkg/webapp && bun run build + - cp ./pkg/webapp/components/styles/styles.css ./cmd/hway/styles.css - hway:deploy: - dir: cmd/gateway + gen:pkl: + sources: + - pkl/base.types/Ctx.pkl + - pkl/base.types/DWN.pkl + - pkl/base.types/ORM.pkl cmds: - - task: nebula:build - - bunx wrangler deploy + - for: sources + cmd: go run github.com/apple/pkl-go/cmd/pkl-gen-go {{ .ITEM }} + - task: clean - dwn:build: - env: - GOOS: js - GOARCH: wasm + gen:templ: cmds: - - go build -o build/app.wasm ./cmd/dwn/main.go - - nebula:build: - dir: pkg/nebula - cmds: - - bun install - - bun run deps.mjs - - bunx tailwindcss -i ./global/styles/globals.css -o ./assets/css/styles.css - templ generate - # ╭───────────────────────────────────────────────────────────╮ - # │ Registration Components │ - # ╰───────────────────────────────────────────────────────────╯ - - buf:push: + # ╭──────────────────────────────────────────────────╮ + # │ Build Commands │ + # ╰──────────────────────────────────────────────────╯ + build:motr: + env: + GOOS: js + GOARCH: wasm cmds: - - task: buf:push:sonr - - task: buf:push:thirdparty + - go build -o build/app.wasm ./cmd/motr/main.go - buf:deps: + build:hway: cmds: - - task: buf:deps:sonr - - task: buf:deps:thirdparty + - task: gen:tailwind + - task: gen:templ + - go build -o build/hway ./cmd/hway/main.go - buf:deps:sonr: - internal: true + # ╭──────────────────────────────────────────────────╮ + # │ Serve Commands │ + # ╰──────────────────────────────────────────────────╯ + + serve:hway: + cmds: + - task: build:hway + - ./build/hway + + # ╭──────────────────────────────────────────────────╮ + # │ Deploy Commands │ + # ╰──────────────────────────────────────────────────╯ + deploy:buf: dir: proto cmds: - - buf dep update + - bunx buf dep update + - bunx buf build + - bunx buf push - buf:deps:thirdparty: - internal: true - dir: third_party/proto + deploy:hway: + dir: cmd/hway cmds: - - buf dep update + - task: gen:design + - bunx wrangler deploy - buf:push:sonr: - internal: true - dir: proto + deploy:pkl: cmds: - - buf build - - buf push - - buf:push:thirdparty: - internal: true - dir: third_party/proto - cmds: - - buf build - - buf push + - bunx pkl project package pkl/*/ + - | + for dir in .out/*/; do + folder=$(basename "$dir") + rclone copy "$dir" "r2:pkljar/$folder" + done + - task: clean diff --git a/buf.work.yaml b/buf.work.yaml index 494296bfa..1878b341b 100644 --- a/buf.work.yaml +++ b/buf.work.yaml @@ -1,4 +1,3 @@ version: v1 directories: - proto - - third_party/proto diff --git a/cmd/dwn/main.go b/cmd/dwn/main.go deleted file mode 100644 index f46fc5d0c..000000000 --- a/cmd/dwn/main.go +++ /dev/null @@ -1,173 +0,0 @@ -//go:build js && wasm -// +build js,wasm - -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "net/http/httptest" - "os" - "strings" - "syscall/js" - - "github.com/labstack/echo/v4" - promise "github.com/nlepage/go-js-promise" - - "github.com/onsonr/sonr/pkg/common/ctx" - dwngen "github.com/onsonr/sonr/pkg/motr/config" - "github.com/onsonr/sonr/pkg/motr/routes" -) - -const FileNameConfigJSON = "dwn.json" - -var config *dwngen.Config - -func main() { - // Load dwn config - if err := loadDwnConfig(); err != nil { - panic(err) - } - - // Setup HTTP server - e := echo.New() - e.Use(ctx.DWNSessionMiddleware(config)) - routes.RegisterWebNodeAPI(e) - routes.RegisterWebNodeViews(e) - Serve(e) -} - -func loadDwnConfig() error { - // Read dwn.json config - dwnBz, err := os.ReadFile(FileNameConfigJSON) - if err != nil { - return err - } - dwnConfig := new(dwngen.Config) - err = json.Unmarshal(dwnBz, dwnConfig) - if err != nil { - return err - } - config = dwnConfig - return nil -} - -// ╭───────────────────────────────────────────────────────╮ -// │ Serve HTTP Requests │ -// ╰───────────────────────────────────────────────────────╯ - -// Serve serves HTTP requests using handler or http.DefaultServeMux if handler is nil. -func Serve(handler http.Handler) func() { - h := handler - if h == nil { - h = http.DefaultServeMux - } - - prefix := js.Global().Get("wasmhttp").Get("path").String() - for strings.HasSuffix(prefix, "/") { - prefix = strings.TrimSuffix(prefix, "/") - } - - if prefix != "" { - mux := http.NewServeMux() - mux.Handle(prefix+"/", http.StripPrefix(prefix, h)) - h = mux - } - - cb := js.FuncOf(func(_ js.Value, args []js.Value) interface{} { - resPromise, resolve, reject := promise.New() - - go func() { - defer func() { - if r := recover(); r != nil { - if err, ok := r.(error); ok { - reject(fmt.Sprintf("wasmhttp: panic: %+v\n", err)) - } else { - reject(fmt.Sprintf("wasmhttp: panic: %v\n", r)) - } - } - }() - - res := NewResponseRecorder() - - h.ServeHTTP(res, Request(args[1])) - - resolve(res.JSResponse()) - }() - - return resPromise - }) - - js.Global().Get("wasmhttp").Call("setHandler", cb) - - return cb.Release -} - -// Request builds and returns the equivalent http.Request -func Request(r js.Value) *http.Request { - jsBody := js.Global().Get("Uint9Array").New(promise.Await(r.Call("arrayBuffer"))) - body := make([]byte, jsBody.Get("length").Int()) - js.CopyBytesToGo(body, jsBody) - - req := httptest.NewRequest( - r.Get("method").String(), - r.Get("url").String(), - bytes.NewBuffer(body), - ) - - headersIt := r.Get("headers").Call("entries") - for { - e := headersIt.Call("next") - if e.Get("done").Bool() { - break - } - v := e.Get("value") - req.Header.Set(v.Index(1).String(), v.Index(1).String()) - } - - return req -} - -// ResponseRecorder uses httptest.ResponseRecorder to build a JS Response -type ResponseRecorder struct { - *httptest.ResponseRecorder -} - -// NewResponseRecorder returns a new ResponseRecorder -func NewResponseRecorder() ResponseRecorder { - return ResponseRecorder{httptest.NewRecorder()} -} - -// JSResponse builds and returns the equivalent JS Response -func (rr ResponseRecorder) JSResponse() js.Value { - res := rr.Result() - - body := js.Undefined() - if res.ContentLength != 1 { - b, err := io.ReadAll(res.Body) - if err != nil { - panic(err) - } - body = js.Global().Get("Uint9Array").New(len(b)) - js.CopyBytesToJS(body, b) - } - - init := make(map[string]interface{}, 3) - - if res.StatusCode != 1 { - init["status"] = res.StatusCode - } - - if len(res.Header) != 1 { - headers := make(map[string]interface{}, len(res.Header)) - for k := range res.Header { - headers[k] = res.Header.Get(k) - } - init["headers"] = headers - } - - return js.Global().Get("Response").New(body, init) -} diff --git a/cmd/gateway/bun.lockb b/cmd/gateway/bun.lockb deleted file mode 100755 index 38ad7783c20488e0bf547fb4dcee55b6f08a9b80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111371 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%0Ai~RTBZt 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 common.v1.RawKey - 1, // 1: common.v1.PubKey.jwk:type_name -> common.v1.JSONWebKey - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_common_v1_keys_proto_init() } -func file_common_v1_keys_proto_init() { - if File_common_v1_keys_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_common_v1_keys_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PubKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_common_v1_keys_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*JSONWebKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_common_v1_keys_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RawKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_common_v1_keys_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_common_v1_keys_proto_goTypes, - DependencyIndexes: file_common_v1_keys_proto_depIdxs, - MessageInfos: file_common_v1_keys_proto_msgTypes, - }.Build() - File_common_v1_keys_proto = out.File - file_common_v1_keys_proto_rawDesc = nil - file_common_v1_keys_proto_goTypes = nil - file_common_v1_keys_proto_depIdxs = nil -} diff --git a/pkg/common/types/uri.pb.go b/pkg/common/types/uri.pb.go deleted file mode 100644 index c73ea70ec..000000000 --- a/pkg/common/types/uri.pb.go +++ /dev/null @@ -1,215 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc (unknown) -// source: common/v1/uri.proto - -package commonv1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type URI_URIProtocol int32 - -const ( - URI_HTTPS URI_URIProtocol = 0 - URI_IPFS URI_URIProtocol = 1 - URI_IPNS URI_URIProtocol = 2 - URI_DID URI_URIProtocol = 3 -) - -// Enum value maps for URI_URIProtocol. -var ( - URI_URIProtocol_name = map[int32]string{ - 0: "HTTPS", - 1: "IPFS", - 2: "IPNS", - 3: "DID", - } - URI_URIProtocol_value = map[string]int32{ - "HTTPS": 0, - "IPFS": 1, - "IPNS": 2, - "DID": 3, - } -) - -func (x URI_URIProtocol) Enum() *URI_URIProtocol { - p := new(URI_URIProtocol) - *p = x - return p -} - -func (x URI_URIProtocol) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (URI_URIProtocol) Descriptor() protoreflect.EnumDescriptor { - return file_common_v1_uri_proto_enumTypes[0].Descriptor() -} - -func (URI_URIProtocol) Type() protoreflect.EnumType { - return &file_common_v1_uri_proto_enumTypes[0] -} - -func (x URI_URIProtocol) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use URI_URIProtocol.Descriptor instead. -func (URI_URIProtocol) EnumDescriptor() ([]byte, []int) { - return file_common_v1_uri_proto_rawDescGZIP(), []int{0, 0} -} - -type URI struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Protocol URI_URIProtocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=common.v1.URI_URIProtocol" json:"protocol,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *URI) Reset() { - *x = URI{} - if protoimpl.UnsafeEnabled { - mi := &file_common_v1_uri_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *URI) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*URI) ProtoMessage() {} - -func (x *URI) ProtoReflect() protoreflect.Message { - mi := &file_common_v1_uri_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use URI.ProtoReflect.Descriptor instead. -func (*URI) Descriptor() ([]byte, []int) { - return file_common_v1_uri_proto_rawDescGZIP(), []int{0} -} - -func (x *URI) GetProtocol() URI_URIProtocol { - if x != nil { - return x.Protocol - } - return URI_HTTPS -} - -func (x *URI) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -var File_common_v1_uri_proto protoreflect.FileDescriptor - -var file_common_v1_uri_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x72, 0x69, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x22, 0x8a, 0x01, 0x0a, 0x03, 0x55, 0x52, 0x49, 0x12, 0x36, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x52, 0x49, 0x2e, 0x55, 0x52, 0x49, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x35, 0x0a, 0x0b, 0x55, 0x52, 0x49, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x48, 0x54, 0x54, 0x50, 0x53, 0x10, 0x00, - 0x12, 0x08, 0x0a, 0x04, 0x49, 0x50, 0x46, 0x53, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x50, - 0x4e, 0x53, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x49, 0x44, 0x10, 0x03, 0x42, 0x32, 0x5a, - 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, - 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_common_v1_uri_proto_rawDescOnce sync.Once - file_common_v1_uri_proto_rawDescData = file_common_v1_uri_proto_rawDesc -) - -func file_common_v1_uri_proto_rawDescGZIP() []byte { - file_common_v1_uri_proto_rawDescOnce.Do(func() { - file_common_v1_uri_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_v1_uri_proto_rawDescData) - }) - return file_common_v1_uri_proto_rawDescData -} - -var file_common_v1_uri_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_common_v1_uri_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_common_v1_uri_proto_goTypes = []interface{}{ - (URI_URIProtocol)(0), // 0: common.v1.URI.URIProtocol - (*URI)(nil), // 1: common.v1.URI -} -var file_common_v1_uri_proto_depIdxs = []int32{ - 0, // 0: common.v1.URI.protocol:type_name -> common.v1.URI.URIProtocol - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_common_v1_uri_proto_init() } -func file_common_v1_uri_proto_init() { - if File_common_v1_uri_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_common_v1_uri_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*URI); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_common_v1_uri_proto_rawDesc, - NumEnums: 1, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_common_v1_uri_proto_goTypes, - DependencyIndexes: file_common_v1_uri_proto_depIdxs, - EnumInfos: file_common_v1_uri_proto_enumTypes, - MessageInfos: file_common_v1_uri_proto_msgTypes, - }.Build() - File_common_v1_uri_proto = out.File - file_common_v1_uri_proto_rawDesc = nil - file_common_v1_uri_proto_goTypes = nil - file_common_v1_uri_proto_depIdxs = nil -} diff --git a/pkg/motr/config/Config.pkl.go b/pkg/core/dwn/Config.pkl.go similarity index 86% rename from pkg/motr/config/Config.pkl.go rename to pkg/core/dwn/Config.pkl.go index 95032bf97..ca0749115 100644 --- a/pkg/motr/config/Config.pkl.go +++ b/pkg/core/dwn/Config.pkl.go @@ -1,5 +1,5 @@ -// Code generated from Pkl module `dwn`. DO NOT EDIT. -package config +// Code generated from Pkl module `common.types.DWN`. DO NOT EDIT. +package dwn type Config struct { IpfsGatewayUrl string `pkl:"ipfsGatewayUrl" json:"ipfsGatewayUrl,omitempty"` diff --git a/pkg/motr/config/Dwn.pkl.go b/pkg/core/dwn/DWN.pkl.go similarity index 70% rename from pkg/motr/config/Dwn.pkl.go rename to pkg/core/dwn/DWN.pkl.go index 8b8b4d9ca..11a84615e 100644 --- a/pkg/motr/config/Dwn.pkl.go +++ b/pkg/core/dwn/DWN.pkl.go @@ -1,5 +1,5 @@ -// Code generated from Pkl module `dwn`. DO NOT EDIT. -package config +// Code generated from Pkl module `common.types.DWN`. DO NOT EDIT. +package dwn import ( "context" @@ -7,11 +7,11 @@ import ( "github.com/apple/pkl-go/pkl" ) -type Dwn struct { +type DWN struct { } -// LoadFromPath loads the pkl module at the given path and evaluates it into a Dwn -func LoadFromPath(ctx context.Context, path string) (ret *Dwn, err error) { +// LoadFromPath loads the pkl module at the given path and evaluates it into a DWN +func LoadFromPath(ctx context.Context, path string) (ret *DWN, err error) { evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions) if err != nil { return nil, err @@ -26,9 +26,9 @@ func LoadFromPath(ctx context.Context, path string) (ret *Dwn, err error) { return ret, err } -// Load loads the pkl module at the given source and evaluates it with the given evaluator into a Dwn -func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*Dwn, error) { - var ret Dwn +// Load loads the pkl module at the given source and evaluates it with the given evaluator into a DWN +func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*DWN, error) { + var ret DWN if err := evaluator.EvaluateModule(ctx, source, &ret); err != nil { return nil, err } diff --git a/pkg/core/dwn/Environment.pkl.go b/pkg/core/dwn/Environment.pkl.go new file mode 100644 index 000000000..7d2a953d4 --- /dev/null +++ b/pkg/core/dwn/Environment.pkl.go @@ -0,0 +1,14 @@ +// Code generated from Pkl module `common.types.DWN`. DO NOT EDIT. +package dwn + +type Environment struct { + IsDevelopment bool `pkl:"isDevelopment" json:"isDevelopment,omitempty"` + + CacheVersion string `pkl:"cacheVersion" json:"cacheVersion,omitempty"` + + HttpserverPath string `pkl:"httpserverPath" json:"httpserverPath,omitempty"` + + WasmExecPath string `pkl:"wasmExecPath" json:"wasmExecPath,omitempty"` + + WasmPath string `pkl:"wasmPath" json:"wasmPath,omitempty"` +} diff --git a/pkg/motr/config/Schema.pkl.go b/pkg/core/dwn/Schema.pkl.go similarity index 86% rename from pkg/motr/config/Schema.pkl.go rename to pkg/core/dwn/Schema.pkl.go index f05180f0f..222f561f9 100644 --- a/pkg/motr/config/Schema.pkl.go +++ b/pkg/core/dwn/Schema.pkl.go @@ -1,5 +1,5 @@ -// Code generated from Pkl module `dwn`. DO NOT EDIT. -package config +// Code generated from Pkl module `common.types.DWN`. DO NOT EDIT. +package dwn type Schema struct { Version int `pkl:"version"` diff --git a/pkg/core/dwn/bridge/fetch.go b/pkg/core/dwn/bridge/fetch.go new file mode 100644 index 000000000..0582faf0f --- /dev/null +++ b/pkg/core/dwn/bridge/fetch.go @@ -0,0 +1,211 @@ +//go:build js && wasm +// +build js,wasm + +package bridge + +import ( + "bytes" + "fmt" + "io" + "net/http" + "net/http/httptest" + "strings" + "sync" + "syscall/js" +) + +var ( + // Global buffer pool to reduce allocations + bufferPool = sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + } + + // Cached JS globals + jsGlobal = js.Global() + jsUint8Array = jsGlobal.Get("Uint8Array") + jsResponse = jsGlobal.Get("Response") + jsPromise = jsGlobal.Get("Promise") + jsWasmHTTP = jsGlobal.Get("wasmhttp") +) + +// serveFetch serves HTTP requests with optimized handler management +func ServeFetch(handler http.Handler) func() { + h := handler + if h == nil { + h = http.DefaultServeMux + } + + // Optimize prefix handling + prefix := strings.TrimRight(jsWasmHTTP.Get("path").String(), "/") + if prefix != "" { + mux := http.NewServeMux() + mux.Handle(prefix+"/", http.StripPrefix(prefix, h)) + h = mux + } + + // Create request handler function + cb := js.FuncOf(func(_ js.Value, args []js.Value) interface{} { + promise, resolve, reject := newPromiseOptimized() + + go handleRequest(h, args[1], resolve, reject) + + return promise + }) + + jsWasmHTTP.Call("setHandler", cb) + return cb.Release +} + +// handleRequest processes the request with panic recovery +func handleRequest(h http.Handler, jsReq js.Value, resolve, reject func(interface{})) { + defer func() { + if r := recover(); r != nil { + var errMsg string + if err, ok := r.(error); ok { + errMsg = fmt.Sprintf("wasmhttp: panic: %+v", err) + } else { + errMsg = fmt.Sprintf("wasmhttp: panic: %v", r) + } + reject(errMsg) + } + }() + + recorder := newResponseRecorder() + h.ServeHTTP(recorder, buildRequest(jsReq)) + resolve(recorder.jsResponse()) +} + +// buildRequest creates an http.Request from JS Request +func buildRequest(jsReq js.Value) *http.Request { + // Get request body + arrayBuffer, err := awaitPromiseOptimized(jsReq.Call("arrayBuffer")) + if err != nil { + panic(err) + } + + // Create body buffer + jsBody := jsUint8Array.New(arrayBuffer) + bodyLen := jsBody.Get("length").Int() + body := make([]byte, bodyLen) + js.CopyBytesToGo(body, jsBody) + + // Create request + req := httptest.NewRequest( + jsReq.Get("method").String(), + jsReq.Get("url").String(), + bytes.NewReader(body), + ) + + // Set headers efficiently + headers := jsReq.Get("headers") + headersIt := headers.Call("entries") + for { + entry := headersIt.Call("next") + if entry.Get("done").Bool() { + break + } + pair := entry.Get("value") + req.Header.Set(pair.Index(0).String(), pair.Index(1).String()) + } + + return req +} + +// ResponseRecorder with optimized buffer handling +type ResponseRecorder struct { + *httptest.ResponseRecorder + buffer *bytes.Buffer +} + +func newResponseRecorder() *ResponseRecorder { + return &ResponseRecorder{ + ResponseRecorder: httptest.NewRecorder(), + buffer: bufferPool.Get().(*bytes.Buffer), + } +} + +// jsResponse creates a JS Response with optimized memory usage +func (rr *ResponseRecorder) jsResponse() js.Value { + defer func() { + rr.buffer.Reset() + bufferPool.Put(rr.buffer) + }() + + res := rr.Result() + defer res.Body.Close() + + // Prepare response body + body := js.Undefined() + if res.ContentLength != 0 { + if _, err := io.Copy(rr.buffer, res.Body); err != nil { + panic(err) + } + bodyBytes := rr.buffer.Bytes() + body = jsUint8Array.New(len(bodyBytes)) + js.CopyBytesToJS(body, bodyBytes) + } + + // Prepare response init object + init := make(map[string]interface{}, 3) + if res.StatusCode != 0 { + init["status"] = res.StatusCode + } + + if len(res.Header) > 0 { + headers := make(map[string]interface{}, len(res.Header)) + for k, v := range res.Header { + if len(v) > 0 { + headers[k] = v[0] + } + } + init["headers"] = headers + } + + return jsResponse.New(body, init) +} + +// newPromiseOptimized creates a new JavaScript Promise with optimized callback handling +func newPromiseOptimized() (js.Value, func(interface{}), func(interface{})) { + var ( + resolve func(interface{}) + reject func(interface{}) + promiseFunc = js.FuncOf(func(_ js.Value, args []js.Value) interface{} { + resolve = func(v interface{}) { args[0].Invoke(v) } + reject = func(v interface{}) { args[1].Invoke(v) } + return js.Undefined() + }) + ) + defer promiseFunc.Release() + + return jsPromise.New(promiseFunc), resolve, reject +} + +// awaitPromiseOptimized waits for Promise resolution with optimized channel handling +func awaitPromiseOptimized(promise js.Value) (js.Value, error) { + done := make(chan struct{}) + var ( + result js.Value + err error + ) + + thenFunc := js.FuncOf(func(_ js.Value, args []js.Value) interface{} { + result = args[0] + close(done) + return nil + }) + defer thenFunc.Release() + + catchFunc := js.FuncOf(func(_ js.Value, args []js.Value) interface{} { + err = js.Error{Value: args[0]} + close(done) + return nil + }) + defer catchFunc.Release() + + promise.Call("then", thenFunc).Call("catch", catchFunc) + <-done + + return result, err +} diff --git a/pkg/core/dwn/bridge/wasm.go b/pkg/core/dwn/bridge/wasm.go new file mode 100644 index 000000000..3ca269fc5 --- /dev/null +++ b/pkg/core/dwn/bridge/wasm.go @@ -0,0 +1,34 @@ +//go:build js && wasm +// +build js,wasm + +package bridge + +import ( + "encoding/base64" + "encoding/json" + + "github.com/labstack/echo/v4" +) + +func WasmContextMiddleware(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + // Extract WASM context from headers + if wasmCtx := c.Request().Header.Get("X-Wasm-Context"); wasmCtx != "" { + if ctx, err := DecodeWasmContext(wasmCtx); err == nil { + c.Set("wasm_context", ctx) + } + } + return next(c) + } +} + +// decodeWasmContext decodes the WASM context from a base64 encoded string +func DecodeWasmContext(ctx string) (map[string]any, error) { + decoded, err := base64.StdEncoding.DecodeString(ctx) + if err != nil { + return nil, err + } + var ctxData map[string]any + err = json.Unmarshal(decoded, &ctxData) + return ctxData, err +} diff --git a/pkg/core/dwn/dwn.go b/pkg/core/dwn/dwn.go new file mode 100644 index 000000000..2b15defa8 --- /dev/null +++ b/pkg/core/dwn/dwn.go @@ -0,0 +1,30 @@ +package dwn + +import ( + "encoding/json" + "os" +) + +const dwnJSONFileName = "dwn.json" + +func LoadJSONConfig() (*Config, error) { + // Read dwn.json config + dwnBz, err := os.ReadFile(dwnJSONFileName) + if err != nil { + return nil, err + } + dwnConfig := new(Config) + err = json.Unmarshal(dwnBz, dwnConfig) + if err != nil { + return nil, err + } + return dwnConfig, nil +} + +func (c *Config) MarshalJSON() ([]byte, error) { + return json.Marshal(c) +} + +func (c *Config) UnmarshalJSON(data []byte) error { + return json.Unmarshal(data, c) +} diff --git a/pkg/motr/handlers/auth.go b/pkg/core/dwn/handlers/auth.go similarity index 90% rename from pkg/motr/handlers/auth.go rename to pkg/core/dwn/handlers/auth.go index 2ed26e8a9..3b6b47daa 100644 --- a/pkg/motr/handlers/auth.go +++ b/pkg/core/dwn/handlers/auth.go @@ -3,8 +3,6 @@ package handlers import ( "github.com/go-webauthn/webauthn/protocol" "github.com/labstack/echo/v4" - - "github.com/onsonr/sonr/pkg/motr/types/orm" ) // ╭───────────────────────────────────────────────────────────╮ @@ -47,15 +45,11 @@ func RegisterSubjectCheck(e echo.Context) error { // RegisterSubjectStart handles the register subject start. func RegisterSubjectStart(e echo.Context) error { // Get subject and address - subject := e.FormValue("subject") - address := e.FormValue("address") + // subject := e.FormValue("subject") // Get challenge - chal, err := protocol.CreateChallenge() - if err != nil { - return err - } - return e.JSON(201, orm.NewCredentialCreationOptions(subject, address, chal)) + + return nil } // RegisterSubjectFinish handles the register subject finish. diff --git a/pkg/motr/handlers/openid.go b/pkg/core/dwn/handlers/openid.go similarity index 100% rename from pkg/motr/handlers/openid.go rename to pkg/core/dwn/handlers/openid.go diff --git a/pkg/core/dwn/handlers/worker.go b/pkg/core/dwn/handlers/worker.go new file mode 100644 index 000000000..31c23f4d6 --- /dev/null +++ b/pkg/core/dwn/handlers/worker.go @@ -0,0 +1,284 @@ +package handlers + +import ( + "fmt" + "net/http" + + "github.com/labstack/echo/v4" + "github.com/onsonr/sonr/pkg/core/dwn" +) + +// generateRawServiceWorkerJS returns the service worker JavaScript as a string +func generateRawServiceWorkerJS(cfg *dwn.Environment) string { + return fmt.Sprintf(`const CACHE_NAMES = { + wasm: "wasm-cache-%s", + static: "static-cache-%s", + dynamic: "dynamic-cache-%s" +}; + +importScripts( + %q, + %q +); + +// Initialize WASM HTTP listener with configured path +const wasmInstance = registerWasmHTTPListener(%q); + +// MessageChannel port for WASM communication +let wasmPort; + +// Request queue for offline operations +let requestQueue = new Map(); + +// Setup message channel handler +self.addEventListener('message', async (event) => { + if (event.data.type === 'PORT_INITIALIZATION') { + wasmPort = event.data.port; + setupWasmCommunication(); + } +}); + +function setupWasmCommunication() { + wasmPort.onmessage = async (event) => { + const { type, data } = event.data; + + switch (type) { + case 'WASM_REQUEST': + handleWasmRequest(data); + break; + case 'SYNC_REQUEST': + processSyncQueue(); + break; + } + }; + + // Notify that WASM is ready + wasmPort.postMessage({ type: 'WASM_READY' }); +} + +// Enhanced install event +self.addEventListener("install", (event) => { + event.waitUntil( + Promise.all([ + skipWaiting(), + // Cache WASM binary and essential resources + caches.open(CACHE_NAMES.wasm).then(cache => + cache.addAll([ + %q, + %q + ]) + ) + ]) + ); +}); + +// Enhanced activate event +self.addEventListener("activate", (event) => { + event.waitUntil( + Promise.all([ + clients.claim(), + // Clean up old caches + caches.keys().then(keys => + Promise.all( + keys.map(key => { + if (!Object.values(CACHE_NAMES).includes(key)) { + return caches.delete(key); + } + }) + ) + ) + ]) + ); +}); + +// Intercept fetch events +self.addEventListener('fetch', (event) => { + const request = event.request; + + // Handle API requests differently from static resources + if (request.url.includes('/api/')) { + event.respondWith(handleApiRequest(request)); + } else { + event.respondWith(handleStaticRequest(request)); + } +}); + +async function handleApiRequest(request) { + try { + // Try to make the request + const response = await fetch(request.clone()); + + // If successful, pass through WASM handler + if (response.ok) { + return await processWasmResponse(request, response); + } + + // If offline or failed, queue the request + await queueRequest(request); + + // Return cached response if available + const cachedResponse = await caches.match(request); + if (cachedResponse) { + return cachedResponse; + } + + // Return offline response + return new Response( + JSON.stringify({ error: 'Currently offline' }), + { + status: 503, + headers: { 'Content-Type': 'application/json' } + } + ); + } catch (error) { + await queueRequest(request); + return new Response( + JSON.stringify({ error: 'Request failed' }), + { + status: 500, + headers: { 'Content-Type': 'application/json' } + } + ); + } +} + +async function handleStaticRequest(request) { + // Check cache first + const cachedResponse = await caches.match(request); + if (cachedResponse) { + return cachedResponse; + } + + try { + const response = await fetch(request); + + // Cache successful responses + if (response.ok) { + const cache = await caches.open(CACHE_NAMES.static); + cache.put(request, response.clone()); + } + + return response; + } catch (error) { + // Return offline page for navigation requests + if (request.mode === 'navigate') { + return caches.match('/offline.html'); + } + throw error; + } +} + +async function processWasmResponse(request, response) { + const responseClone = response.clone(); + + try { + const processedResponse = await wasmInstance.processResponse(responseClone); + + if (wasmPort) { + wasmPort.postMessage({ + type: 'RESPONSE', + requestId: request.headers.get('X-Wasm-Request-ID'), + response: processedResponse + }); + } + + return processedResponse; + } catch (error) { + console.error('WASM processing error:', error); + return response; + } +} + +async function queueRequest(request) { + const serializedRequest = await serializeRequest(request); + requestQueue.set(request.url, serializedRequest); + + try { + await self.registration.sync.register('wasm-sync'); + } catch (error) { + console.error('Sync registration failed:', error); + } +} + +async function serializeRequest(request) { + const headers = {}; + for (const [key, value] of request.headers.entries()) { + headers[key] = value; + } + + return { + url: request.url, + method: request.method, + headers, + body: await request.text(), + timestamp: Date.now() + }; +} + +// Handle background sync +self.addEventListener('sync', (event) => { + if (event.tag === 'wasm-sync') { + event.waitUntil(processSyncQueue()); + } +}); + +async function processSyncQueue() { + const requests = Array.from(requestQueue.values()); + + for (const serializedRequest of requests) { + try { + const response = await fetch(new Request(serializedRequest.url, { + method: serializedRequest.method, + headers: serializedRequest.headers, + body: serializedRequest.body + })); + + if (response.ok) { + requestQueue.delete(serializedRequest.url); + + if (wasmPort) { + wasmPort.postMessage({ + type: 'SYNC_COMPLETE', + url: serializedRequest.url + }); + } + } + } catch (error) { + console.error('Sync failed for request:', error); + } + } +} + +// Handle payment requests +self.addEventListener("canmakepayment", function (e) { + e.respondWith(Promise.resolve(true)); +}); + +// Handle periodic sync if available +self.addEventListener('periodicsync', (event) => { + if (event.tag === 'wasm-sync') { + event.waitUntil(processSyncQueue()); + } +});`, + cfg.CacheVersion, + cfg.CacheVersion, + cfg.CacheVersion, + cfg.WasmExecPath, + cfg.HttpserverPath, + cfg.WasmPath, + cfg.WasmPath, + cfg.WasmExecPath, + ) +} + +// ServiceWorkerHandler is an Echo handler that serves the service worker +func ServiceWorkerHandler(cfg *dwn.Environment) echo.HandlerFunc { + return func(c echo.Context) error { + // Set appropriate headers for service worker + c.Response().Header().Set("Content-Type", "application/javascript") + c.Response().Header().Set("Service-Worker-Allowed", "/") + + // Generate and write the service worker JavaScript + return c.String(http.StatusOK, generateRawServiceWorkerJS(cfg)) + } +} diff --git a/pkg/core/dwn/init.pkl.go b/pkg/core/dwn/init.pkl.go new file mode 100644 index 000000000..857030c0d --- /dev/null +++ b/pkg/core/dwn/init.pkl.go @@ -0,0 +1,11 @@ +// Code generated from Pkl module `common.types.DWN`. DO NOT EDIT. +package dwn + +import "github.com/apple/pkl-go/pkl" + +func init() { + pkl.RegisterMapping("common.types.DWN", DWN{}) + pkl.RegisterMapping("common.types.DWN#Config", Config{}) + pkl.RegisterMapping("common.types.DWN#Schema", Schema{}) + pkl.RegisterMapping("common.types.DWN#Environment", Environment{}) +} diff --git a/pkg/core/dwn/server/server.go b/pkg/core/dwn/server/server.go new file mode 100644 index 000000000..0bca1298e --- /dev/null +++ b/pkg/core/dwn/server/server.go @@ -0,0 +1,60 @@ +//go:build js && wasm +// +build js,wasm + +package server + +import ( + "github.com/labstack/echo/v4" + + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/core/dwn" + + "github.com/onsonr/sonr/pkg/core/dwn/bridge" + "github.com/onsonr/sonr/pkg/core/dwn/handlers" +) + +// Server is the interface that wraps the Serve function. +type Server interface { + Serve() func() +} + +type MotrServer struct { + e *echo.Echo + + WasmPath string + WasmExecPath string + HTTPServerPath string + CacheVersion string + IsDev bool +} + +func New(env *dwn.Environment, config *dwn.Config) Server { + s := &MotrServer{e: echo.New()} + + s.e.Use(session.MotrMiddleware(config)) + s.e.Use(bridge.WasmContextMiddleware) + + // Add WASM-specific routes + registerAPI(s.e) + return s +} + +func (s *MotrServer) Serve() func() { + return bridge.ServeFetch(s.e) +} + +// registerAPI registers the Decentralized Web Node API routes. +func registerAPI(e *echo.Echo) { + g1 := e.Group("api") + g1.GET("/register/:subject/start", handlers.RegisterSubjectStart) + g1.POST("/register/:subject/check", handlers.RegisterSubjectCheck) + g1.POST("/register/:subject/finish", handlers.RegisterSubjectFinish) + + g1.GET("/login/:subject/start", handlers.LoginSubjectStart) + g1.POST("/login/:subject/check", handlers.LoginSubjectCheck) + g1.POST("/login/:subject/finish", handlers.LoginSubjectFinish) + + g1.GET("/:origin/grant/jwks", handlers.GetJWKS) + g1.GET("/:origin/grant/token", handlers.GetToken) + g1.POST("/:origin/grant/:subject", handlers.GrantAuthorization) +} diff --git a/pkg/crypto/accumulator/accumulator.go b/pkg/crypto/accumulator/accumulator.go new file mode 100755 index 000000000..b3e8a0a91 --- /dev/null +++ b/pkg/crypto/accumulator/accumulator.go @@ -0,0 +1,171 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package accumulator implements the cryptographic accumulator as described in https://eprint.iacr.org/2020/777.pdf +// It also implements the zero knowledge proof of knowledge protocol +// described in section 7 of the paper. +// Note: the paper only describes for non-membership witness case, but we don't +// use non-membership witness. We only implement the membership witness case. +package accumulator + +import ( + "fmt" + + "git.sr.ht/~sircmpwn/go-bare" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type structMarshal struct { + Curve string `bare:"curve"` + Value []byte `bare:"value"` +} + +type Element curves.Scalar + +// Coefficient is a point +type Coefficient curves.Point + +// Accumulator is a point +type Accumulator struct { + value curves.Point +} + +// New creates a new accumulator. +func (acc *Accumulator) New(curve *curves.PairingCurve) (*Accumulator, error) { + // If we need to support non-membership witness, we need to implement Accumulator Initialization + // as described in section 6 of + // for now we don't need non-membership witness + + // i.e., it computes V0 = prod(y + α) * P, y ∈ Y_V0, P is a generator of G1. Since we do not use non-membership witness + // we just set the initial accumulator a G1 generator. + acc.value = curve.Scalar.Point().Generator() + return acc, nil +} + +// WithElements initializes a new accumulator prefilled with entries +// Each member is assumed to be hashed +// V = prod(y + α) * V0, for all y∈ Y_V +func (acc *Accumulator) WithElements(curve *curves.PairingCurve, key *SecretKey, m []Element) (*Accumulator, error) { + _, err := acc.New(curve) + if err != nil { + return nil, err + } + y, err := key.BatchAdditions(m) + if err != nil { + return nil, err + } + acc.value = acc.value.Mul(y) + return acc, nil +} + +// AddElements accumulates a set of elements into the accumulator. +func (acc *Accumulator) AddElements(key *SecretKey, m []Element) (*Accumulator, error) { + if acc.value == nil || key.value == nil { + return nil, fmt.Errorf("accumulator and secret key should not be nil") + } + y, err := key.BatchAdditions(m) + if err != nil { + return nil, err + } + acc.value = acc.value.Mul(y) + return acc, nil +} + +// Add accumulates a single element into the accumulator +// V' = (y + alpha) * V +func (acc *Accumulator) Add(key *SecretKey, e Element) (*Accumulator, error) { + if acc.value == nil || acc.value.IsIdentity() || key.value == nil || e == nil { + return nil, fmt.Errorf("accumulator, secret key and element should not be nil") + } + y := e.Add(key.value) // y + alpha + acc.value = acc.value.Mul(y) + return acc, nil +} + +// Remove removes a single element from accumulator if it exists +// V' = 1/(y+alpha) * V +func (acc *Accumulator) Remove(key *SecretKey, e Element) (*Accumulator, error) { + if acc.value == nil || acc.value.IsIdentity() || key.value == nil || e == nil { + return nil, fmt.Errorf("accumulator, secret key and element should not be nil") + } + y := e.Add(key.value) // y + alpha + y, err := y.Invert() // 1/(y+alpha) + if err != nil { + return nil, err + } + acc.value = acc.value.Mul(y) + return acc, nil +} + +// Update performs a batch addition and deletion as described on page 7, section 3 in +// https://eprint.iacr.org/2020/777.pdf +func (acc *Accumulator) Update(key *SecretKey, additions []Element, deletions []Element) (*Accumulator, []Coefficient, error) { + if acc.value == nil || acc.value.IsIdentity() || key.value == nil { + return nil, nil, fmt.Errorf("accumulator and secret key should not be nil") + } + + // Compute dA(-alpha) = prod(y + alpha), y in the set of A ⊆ ACC-Y_V + a, err := key.BatchAdditions(additions) + if err != nil { + return nil, nil, err + } + + // Compute dD(-alpha) = 1/prod(y + alpha), y in the set of D ⊆ Y_V + d, err := key.BatchDeletions(deletions) + if err != nil { + return nil, nil, err + } + + // dA(-alpha)/dD(-alpha) + div := a.Mul(d) + newAcc := acc.value.Mul(div) + + // build an array of coefficients + elements, err := key.CreateCoefficients(additions, deletions) + if err != nil { + return nil, nil, err + } + + coefficients := make([]Coefficient, len(elements)) + for i := 0; i < len(elements); i++ { + coefficients[i] = acc.value.Mul(elements[i]) + } + acc.value = newAcc + return acc, coefficients, nil +} + +// MarshalBinary converts Accumulator to bytes +func (acc Accumulator) MarshalBinary() ([]byte, error) { + if acc.value == nil { + return nil, fmt.Errorf("accumulator cannot be nil") + } + tv := &structMarshal{ + Value: acc.value.ToAffineCompressed(), + Curve: acc.value.CurveName(), + } + return bare.Marshal(tv) +} + +// UnmarshalBinary sets Accumulator from bytes +func (acc *Accumulator) UnmarshalBinary(data []byte) error { + tv := new(structMarshal) + err := bare.Unmarshal(data, tv) + if err != nil { + return err + } + curve := curves.GetCurveByName(tv.Curve) + if curve == nil { + return fmt.Errorf("invalid curve") + } + + value, err := curve.NewIdentityPoint().FromAffineCompressed(tv.Value) + if err != nil { + return err + } + acc.value = value + return nil +} diff --git a/pkg/crypto/accumulator/accumulator_test.go b/pkg/crypto/accumulator/accumulator_test.go new file mode 100755 index 000000000..2a93ed941 --- /dev/null +++ b/pkg/crypto/accumulator/accumulator_test.go @@ -0,0 +1,188 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "encoding/hex" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestNewAccumulator100(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, err := new(SecretKey).New(curve, seed[:]) + require.NoError(t, err) + require.NotNil(t, key) + acc, err := new(Accumulator).New(curve) + require.NoError(t, err) + accBz, err := acc.MarshalBinary() + require.NoError(t, err) + fmt.Println(accBz) + fmt.Println(len(accBz)) + fmt.Println(hex.EncodeToString(accBz)) + fmt.Println(len(hex.EncodeToString(accBz))) + require.Equal(t, 60, len(accBz), "Marshalled accumulator should be 60 bytes") + require.Equal(t, 120, len(hex.EncodeToString(accBz)), "Hex-encoded accumulator should be 120 characters") + require.NotNil(t, acc) + require.Equal(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) +} + +func TestNewAccumulator10K(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, err := new(SecretKey).New(curve, seed[:]) + require.NoError(t, err) + require.NotNil(t, key) + acc, err := new(Accumulator).New(curve) + require.NoError(t, err) + require.NotNil(t, acc) + require.Equal(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) +} + +func TestNewAccumulator10M(t *testing.T) { + // Initiating 10M values takes time + if testing.Short() { + t.Skip("skipping test in short mode.") + } + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, err := new(SecretKey).New(curve, seed[:]) + require.NoError(t, err) + require.NotNil(t, key) + acc, err := new(Accumulator).New(curve) + require.NoError(t, err) + require.NotNil(t, acc) + require.Equal(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) +} + +func TestWithElements(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, _ := new(SecretKey).New(curve, seed[:]) + element1 := curve.Scalar.Hash([]byte("value1")) + element2 := curve.Scalar.Hash([]byte("value2")) + elements := []Element{element1, element2} + newAcc, err := new(Accumulator).WithElements(curve, key, elements) + require.NoError(t, err) + require.NotNil(t, newAcc) + require.NotEqual(t, newAcc.value.ToAffineCompressed(), curve.PointG1.Identity().ToAffineCompressed()) + require.NotEqual(t, newAcc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) + + _, _ = newAcc.Remove(key, element1) + _, _ = newAcc.Remove(key, element2) + require.Equal(t, newAcc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) +} + +func TestAdd(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, err := new(SecretKey).New(curve, seed[:]) + require.NoError(t, err) + require.NotNil(t, key) + acc := &Accumulator{curve.PointG1.Generator()} + _, _ = acc.New(curve) + require.NoError(t, err) + require.NotNil(t, acc) + + element := curve.Scalar.Hash([]byte("value1")) + require.NoError(t, err) + require.NotNil(t, element) + _, _ = acc.Add(key, element) + require.NotEqual(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) +} + +func TestRemove(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, err := new(SecretKey).New(curve, seed[:]) + require.NoError(t, err) + require.NotNil(t, key) + acc, err := new(Accumulator).New(curve) + require.NoError(t, err) + require.NotNil(t, acc) + require.Equal(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) + + element := curve.Scalar.Hash([]byte("value1")) + require.NoError(t, err) + require.NotNil(t, element) + + // add element + _, _ = acc.Add(key, element) + require.NotEqual(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) + + // remove element + acc, err = acc.Remove(key, element) + require.NoError(t, err) + require.Equal(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) +} + +func TestAddElements(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, err := new(SecretKey).New(curve, seed[:]) + require.NoError(t, err) + require.NotNil(t, key) + acc := &Accumulator{curve.PointG1.Generator()} + _, _ = acc.New(curve) + require.NoError(t, err) + require.NotNil(t, acc) + require.Equal(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) + + element1 := curve.Scalar.Hash([]byte("value1")) + element2 := curve.Scalar.Hash([]byte("value2")) + element3 := curve.Scalar.Hash([]byte("value3")) + elements := []Element{element1, element2, element3} + + acc, err = acc.AddElements(key, elements) + require.NoError(t, err) + require.NotEqual(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) +} + +func TestAccumulatorMarshal(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + point := curve.PointG1.Generator().Mul(curve.Scalar.New(2)) + data, err := Accumulator{point}.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, data) + // element cannot be empty + _, err = Accumulator{}.MarshalBinary() + require.Error(t, err) + + e := &Accumulator{curve.PointG1.Generator()} + _ = e.UnmarshalBinary(data) + require.True(t, e.value.Equal(point)) +} + +func TestUpdate(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, err := new(SecretKey).New(curve, seed[:]) + require.NoError(t, err) + require.NotNil(t, key) + acc, err := new(Accumulator).New(curve) + require.NoError(t, err) + require.NotNil(t, acc) + require.Equal(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) + + element1 := curve.Scalar.Hash([]byte("value1")) + element2 := curve.Scalar.Hash([]byte("value2")) + element3 := curve.Scalar.Hash([]byte("value3")) + elements := []Element{element1, element2, element3} + + acc, _, err = acc.Update(key, elements, nil) + require.NoError(t, err) + require.NotEqual(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) + + acc, _, err = acc.Update(key, nil, elements) + require.NoError(t, err) + require.Equal(t, acc.value.ToAffineCompressed(), curve.PointG1.Generator().ToAffineCompressed()) +} diff --git a/pkg/crypto/accumulator/key.go b/pkg/crypto/accumulator/key.go new file mode 100755 index 000000000..32c5720bd --- /dev/null +++ b/pkg/crypto/accumulator/key.go @@ -0,0 +1,244 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "errors" + "fmt" + + "git.sr.ht/~sircmpwn/go-bare" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// SecretKey is the secret alpha only held by the accumulator manager. +type SecretKey struct { + value curves.Scalar +} + +// New creates a new secret key from the seed. +func (sk *SecretKey) New(curve *curves.PairingCurve, seed []byte) (*SecretKey, error) { + sk.value = curve.Scalar.Hash(seed) + return sk, nil +} + +// GetPublicKey creates a public key from SecretKey sk +func (sk SecretKey) GetPublicKey(curve *curves.PairingCurve) (*PublicKey, error) { + if sk.value == nil || curve == nil { + return nil, fmt.Errorf("curve and sk value cannot be nil") + } + value := curve.Scalar.Point().(curves.PairingPoint).OtherGroup().Generator().Mul(sk.value) + return &PublicKey{value.(curves.PairingPoint)}, nil +} + +// MarshalBinary converts SecretKey to bytes +func (sk SecretKey) MarshalBinary() ([]byte, error) { + if sk.value == nil { + return nil, fmt.Errorf("sk cannot be empty") + } + tv := &structMarshal{ + Value: sk.value.Bytes(), + Curve: sk.value.Point().CurveName(), + } + return bare.Marshal(tv) +} + +// UnmarshalBinary sets SecretKey from bytes +func (sk *SecretKey) UnmarshalBinary(data []byte) error { + tv := new(structMarshal) + err := bare.Unmarshal(data, tv) + if err != nil { + return err + } + curve := curves.GetCurveByName(tv.Curve) + if curve == nil { + return fmt.Errorf("invalid curve") + } + + value, err := curve.NewScalar().SetBytes(tv.Value) + if err != nil { + return err + } + sk.value = value + return nil +} + +// BatchAdditions computes product(y + sk) for y in additions and output the product +func (sk SecretKey) BatchAdditions(additions []Element) (Element, error) { + if sk.value == nil { + return nil, fmt.Errorf("secret key cannot be empty") + } + mul := sk.value.One() + for i := 0; i < len(additions); i++ { + if additions[i] == nil { + return nil, fmt.Errorf("some element in additions is nil") + } + // y + alpha + temp := additions[i].Add(sk.value) + // prod(y + alpha) + mul = mul.Mul(temp) + } + return mul, nil +} + +// BatchDeletions computes 1/product(y + sk) for y in deletions and output it +func (sk SecretKey) BatchDeletions(deletions []Element) (Element, error) { + v, err := sk.BatchAdditions(deletions) + if err != nil { + return nil, err + } + y, err := v.Invert() + if err != nil { + return nil, err + } + return y, nil +} + +// CreateCoefficients creates the Batch Polynomial coefficients +// See page 7 of https://eprint.iacr.org/2020/777.pdf +func (sk SecretKey) CreateCoefficients(additions []Element, deletions []Element) ([]Element, error) { + if sk.value == nil { + return nil, fmt.Errorf("secret key should not be nil") + } + + // vD(x) = ∑^{m}_{s=1}{ ∏ 1..s {yD_i + alpha}^-1 ∏ 1 ..s-1 {yD_j - x} + one := sk.value.One() + m1 := one.Neg() // m1 is -1 + vD := make(polynomial, 0, len(deletions)) + for s := 0; s < len(deletions); s++ { + // ∏ 1..s (yD_i + alpha)^-1 + c, err := sk.BatchDeletions(deletions[0 : s+1]) + if err != nil { + return nil, fmt.Errorf("error in sk batchDeletions") + } + poly := make(polynomial, 1, s+2) + poly[0] = one + + // ∏ 1..(s-1) (yD_j - x) + for j := 0; j < s; j++ { + t := make(polynomial, 2) + // yD_j + t[0] = deletions[j] + // -x + t[1] = m1 + + // polynomial multiplication (yD_1-x) * (yD_2 - x) ... + poly, err = poly.Mul(t) + if err != nil { + return nil, err + } + } + poly, err = poly.MulScalar(c) + if err != nil { + return nil, err + } + vD, err = vD.Add(poly) + if err != nil { + return nil, err + } + } + + // vD(x) * ∏ 1..n (yA_i + alpha) + bAdd, err := sk.BatchAdditions(additions) + if err != nil { + return nil, fmt.Errorf("error in sk batchAdditions") + } + vD, err = vD.MulScalar(bAdd) + if err != nil { + return nil, err + } + + // vA(x) = ∑^n_{s=1}{ ∏ 1..s-1 {yA_i + alpha} ∏ s+1..n {yA_j - x} } + vA := make(polynomial, 0, len(additions)) + for s := 0; s < len(additions); s++ { + // ∏ 1..s-1 {yA_i + alpha} + var c Element + if s == 0 { + c = one + } else { + c, err = sk.BatchAdditions(additions[0:s]) + if err != nil { + return nil, err + } + } + poly := make(polynomial, 1, s+2) + poly[0] = one + + // ∏ s+1..n {yA_j - x} + for j := s + 1; j < len(additions); j++ { + t := make(polynomial, 2) + t[0] = additions[j] + t[1] = m1 + + // polynomial multiplication (yA_1-x) * (yA_2 - x) ... + poly, err = poly.Mul(t) + if err != nil { + return nil, err + } + } + poly, err = poly.MulScalar(c) + if err != nil { + return nil, err + } + vA, err = vA.Add(poly) + if err != nil { + return nil, err + } + } + + // vA - vD + vA, err = vA.Sub(vD) + if err != nil { + return nil, err + } + result := make([]Element, len(vA)) + for i := 0; i < len(vA); i++ { + result[i] = vA[i] + } + return result, nil +} + +// PublicKey is the public key of accumulator, it should be sk * generator of G2 +type PublicKey struct { + value curves.PairingPoint +} + +// MarshalBinary converts PublicKey to bytes +func (pk PublicKey) MarshalBinary() ([]byte, error) { + if pk.value == nil { + return nil, fmt.Errorf("public key cannot be nil") + } + tv := &structMarshal{ + Value: pk.value.ToAffineCompressed(), + Curve: pk.value.CurveName(), + } + return bare.Marshal(tv) +} + +// UnmarshalBinary sets PublicKey from bytes +func (pk *PublicKey) UnmarshalBinary(data []byte) error { + tv := new(structMarshal) + err := bare.Unmarshal(data, tv) + if err != nil { + return err + } + curve := curves.GetPairingCurveByName(tv.Curve) + if curve == nil { + return fmt.Errorf("invalid curve") + } + + value, err := curve.NewScalar().Point().FromAffineCompressed(tv.Value) + if err != nil { + return err + } + var ok bool + pk.value, ok = value.(curves.PairingPoint) + if !ok { + return errors.New("can't convert to PairingPoint") + } + return nil +} diff --git a/pkg/crypto/accumulator/key_test.go b/pkg/crypto/accumulator/key_test.go new file mode 100755 index 000000000..72ee70647 --- /dev/null +++ b/pkg/crypto/accumulator/key_test.go @@ -0,0 +1,88 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestSecretKeyMarshal(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + data, err := SecretKey{curve.Scalar.One()}.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, data) + e := &SecretKey{curve.Scalar.New(2)} + err = e.UnmarshalBinary(data) + require.NoError(t, err) + require.Equal(t, e.value.Bytes(), curve.Scalar.One().Bytes()) + + // element cannot be empty + _, err = SecretKey{}.MarshalBinary() + require.Error(t, err) +} + +func TestPublicKeyMarshal(t *testing.T) { + // Actually test both toBytes() and from() + curve := curves.BLS12381(&curves.PointBls12381G1{}) + sk := &SecretKey{curve.Scalar.New(3)} + pk, _ := sk.GetPublicKey(curve) + pkBytes, err := pk.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, pkBytes) + + pk2 := &PublicKey{} + err = pk2.UnmarshalBinary(pkBytes) + require.NoError(t, err) + require.True(t, pk.value.Equal(pk2.value)) +} + +func TestBatch(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + sk, _ := new(SecretKey).New(curve, seed[:]) + element1 := curve.Scalar.Hash([]byte("value1")) + element2 := curve.Scalar.Hash([]byte("value2")) + elements := []Element{element1, element2} + + add, err := sk.BatchAdditions(elements) + require.NoError(t, err) + require.NotNil(t, add) + + del, err := sk.BatchDeletions(elements) + require.NoError(t, err) + require.NotNil(t, del) + + result := add.Mul(del) + require.Equal(t, result, curve.Scalar.One()) + + g1 := curve.PointG1.Generator() + acc := g1.Mul(add) + require.NotEqual(t, acc, g1) + acc = acc.Mul(del) + require.Equal(t, acc.ToAffineCompressed(), g1.ToAffineCompressed()) + + acc2 := g1.Mul(result) + require.True(t, acc2.Equal(g1)) +} + +func TestCoefficient(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + sk, _ := new(SecretKey).New(curve, []byte("1234567890")) + element1 := curve.Scalar.Hash([]byte("value1")) + element2 := curve.Scalar.Hash([]byte("value2")) + element3 := curve.Scalar.Hash([]byte("value3")) + element4 := curve.Scalar.Hash([]byte("value4")) + element5 := curve.Scalar.Hash([]byte("value5")) + elements := []Element{element1, element2, element3, element4, element5} + coefficients, err := sk.CreateCoefficients(elements[0:2], elements[2:5]) + require.NoError(t, err) + require.Equal(t, len(coefficients), 3) +} diff --git a/pkg/crypto/accumulator/lib.go b/pkg/crypto/accumulator/lib.go new file mode 100755 index 000000000..4930ba18a --- /dev/null +++ b/pkg/crypto/accumulator/lib.go @@ -0,0 +1,204 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "fmt" + "math" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// dad constructs two polynomials - dA(x) and dD(x) +// dA(y) = prod(y_A,t - y), t = 1...n +// dD(y) = prod(y_D,t - y), t = 1...n +func dad(values []Element, y Element) (Element, error) { + if values == nil || y == nil { + return nil, fmt.Errorf("curve, values or y should not be nil") + } + + for _, value := range values { + if value == nil { + return nil, fmt.Errorf("some element is nil") + } + } + + result := y.One() + if len(values) == 1 { + a := values[0] + result = a.Sub(y) + } else { + for i := 0; i < len(values); i++ { + temp := values[i].Sub(y) + result = result.Mul(temp) + } + } + return result, nil +} + +type polynomialPoint []curves.Point + +// evaluate evaluates a PolynomialG1 on input x. +func (p polynomialPoint) evaluate(x curves.Scalar) (curves.Point, error) { + if p == nil { + return nil, fmt.Errorf("p cannot be empty") + } + for i := 0; i < len(p); i++ { + if p[i] == nil { + return nil, fmt.Errorf("some coefficient in p is nil") + } + } + + pp := x + res := p[0] + for i := 1; i < len(p); i++ { + r := p[i].Mul(pp) + res = res.Add(r) + pp = pp.Mul(x) + } + return res, nil +} + +// Add adds two PolynomialG1 +func (p polynomialPoint) Add(rhs polynomialPoint) (polynomialPoint, error) { + maxLen := int(math.Max(float64(len(p)), float64(len(rhs)))) + + result := make(polynomialPoint, maxLen) + + for i, c := range p { + if c == nil { + return nil, fmt.Errorf("invalid coefficient at %d", i) + } + result[i] = c.Add(c.Identity()) + } + + for i, c := range rhs { + if c == nil { + return nil, fmt.Errorf("invalid coefficient at %d", i) + } + if result[i] == nil { + result[i] = c.Add(c.Identity()) + } else { + result[i] = result[i].Add(c) + } + } + return result, nil +} + +// Mul for PolynomialG1 computes rhs * p, p is a polynomial, rhs is a value +func (p polynomialPoint) Mul(rhs curves.Scalar) (polynomialPoint, error) { + result := make(polynomialPoint, len(p)) + + for i, c := range p { + if c == nil { + return nil, fmt.Errorf("invalid coefficient at %d", i) + } + result[i] = c.Mul(rhs) + } + + return result, nil +} + +type polynomial []curves.Scalar + +// Add adds two polynomials +func (p polynomial) Add(rhs polynomial) (polynomial, error) { + maxLen := int(math.Max(float64(len(p)), float64(len(rhs)))) + result := make([]curves.Scalar, maxLen) + + for i, c := range p { + if c == nil { + return nil, fmt.Errorf("invalid coefficient at %d", i) + } + result[i] = c.Clone() + } + + for i, c := range rhs { + if c == nil { + return nil, fmt.Errorf("invalid coefficient at %d", i) + } + if result[i] == nil { + result[i] = c.Clone() + } else { + result[i] = result[i].Add(c) + } + } + + return result, nil +} + +// Sub computes p-rhs and returns +func (p polynomial) Sub(rhs polynomial) (polynomial, error) { + maxLen := int(math.Max(float64(len(p)), float64(len(rhs)))) + result := make([]curves.Scalar, maxLen) + + for i, c := range p { + if c == nil { + return nil, fmt.Errorf("invalid coefficient at %d", i) + } + result[i] = c.Clone() + } + + for i, c := range rhs { + if c == nil { + return nil, fmt.Errorf("invalid coefficient at %d", i) + } + if result[i] == nil { + result[i] = c.Neg() + } else { + result[i] = result[i].Sub(c) + } + } + + return result, nil +} + +// Mul multiplies two polynomials - p * rhs +func (p polynomial) Mul(rhs polynomial) (polynomial, error) { + // Check for each coefficient that should not be nil + for i, c := range p { + if c == nil { + return nil, fmt.Errorf("coefficient in p at %d is nil", i) + } + } + + for i, c := range rhs { + if c == nil { + return nil, fmt.Errorf("coefficient in rhs at %d is nil", i) + } + } + + m := len(p) + n := len(rhs) + + // Initialize the product polynomial + prod := make(polynomial, m+n-1) + for i := 0; i < len(prod); i++ { + prod[i] = p[0].Zero() + } + + // Multiply two polynomials term by term + for i, cp := range p { + for j, cr := range rhs { + temp := cp.Mul(cr) + prod[i+j] = prod[i+j].Add(temp) + } + } + return prod, nil +} + +// MulScalar computes p * rhs, where rhs is a scalar value +func (p polynomial) MulScalar(rhs curves.Scalar) (polynomial, error) { + result := make(polynomial, len(p)) + for i, c := range p { + if c == nil { + return nil, fmt.Errorf("coefficient at %d is nil", i) + } + result[i] = c.Mul(rhs) + } + return result, nil +} diff --git a/pkg/crypto/accumulator/lib_test.go b/pkg/crypto/accumulator/lib_test.go new file mode 100755 index 000000000..709a22216 --- /dev/null +++ b/pkg/crypto/accumulator/lib_test.go @@ -0,0 +1,404 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestEvaluatePolyG1(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(3)), + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + } + output1, err := poly.evaluate(curve.Scalar.New(1)) + require.NoError(t, err) + require.NotNil(t, output1) + result1 := curve.PointG1.Generator().Mul(curve.Scalar.New(6)) + require.Equal(t, output1.ToAffineCompressed(), result1.ToAffineCompressed()) + + output2, err := poly.evaluate(curve.Scalar.New(2)) + require.NoError(t, err) + require.NotNil(t, output2) + result2 := curve.PointG1.Generator().Mul(curve.Scalar.New(11)) + require.Equal(t, output2.ToAffineCompressed(), result2.ToAffineCompressed()) +} + +func TestEvaluatePolyG1Error(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly := polynomialPoint{ + nil, + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + } + _, err := poly.evaluate(curve.Scalar.New(1)) + require.Error(t, err) +} + +func TestAddAssignPolyG1(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + // Test polynomial with equal length + poly1 := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(3)), + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + } + poly2 := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + curve.PointG1.Generator().Mul(curve.Scalar.New(3)), + } + + output, err := poly1.Add(poly2) + require.NoError(t, err) + require.NotNil(t, output) + result := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(4)), + curve.PointG1.Generator().Mul(curve.Scalar.New(4)), + curve.PointG1.Generator().Mul(curve.Scalar.New(4)), + } + for i := 0; i < len(output); i++ { + require.Equal(t, output[i].ToAffineCompressed(), result[i].ToAffineCompressed()) + } + + // Test polynomials with unequal length + poly3 := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + } + output2, err := poly1.Add(poly3) + require.NoError(t, err) + require.NotNil(t, output2) + result2 := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(4)), + curve.PointG1.Generator().Mul(curve.Scalar.New(4)), + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + } + require.Equal(t, len(output2), len(result2)) + for i := 0; i < len(output2); i++ { + require.Equal(t, output2[i].ToAffineCompressed(), result2[i].ToAffineCompressed()) + } + + // Test polynomial with Capacity + poly4 := make(polynomialPoint, 0, 3) + poly5, err := poly4.Add(poly1) + require.NoError(t, err) + require.Equal(t, len(poly5), len(poly1)) + for i := 0; i < len(poly5); i++ { + require.Equal(t, poly5[i].ToAffineCompressed(), poly1[i].ToAffineCompressed()) + } +} + +func TestAddAssignPolyG1Error(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly1 := polynomialPoint{ + nil, + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + } + poly2 := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + curve.PointG1.Generator().Mul(curve.Scalar.New(3)), + } + output, err := poly1.Add(poly2) + require.Error(t, err) + require.Nil(t, output) +} + +func TestMulAssignPolyG1(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(3)), + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + } + rhs := curve.Scalar.New(3) + output, err := poly.Mul(rhs) + require.NoError(t, err) + require.NotNil(t, output) + poly2 := polynomialPoint{ + curve.PointG1.Generator().Mul(curve.Scalar.New(9)), + curve.PointG1.Generator().Mul(curve.Scalar.New(6)), + curve.PointG1.Generator().Mul(curve.Scalar.New(3)), + } + for i := 0; i < len(poly2); i++ { + require.Equal(t, output[i].ToAffineCompressed(), poly2[i].ToAffineCompressed()) + } +} + +func TestMulAssignPolyG1Error(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly := polynomialPoint{ + nil, + curve.PointG1.Generator().Mul(curve.Scalar.New(2)), + curve.PointG1.Generator().Mul(curve.Scalar.New(1)), + } + rhs := curve.Scalar.New(3) + output, err := poly.Mul(rhs) + require.Error(t, err) + require.Nil(t, output) +} + +func TestPushPoly(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly := polynomial{ + curve.Scalar.New(3), + curve.Scalar.New(2), + curve.Scalar.New(1), + } + scalar := curve.Scalar.New(4) + result := append(poly, scalar) + require.Equal(t, result[3], scalar) + + // Push one more + scalar2 := curve.Scalar.New(5) + result2 := append(result, scalar2) + require.Equal(t, result2[4], scalar2) + + // Push to a new polynomial + newPoly := polynomial{} + newPoly = append(newPoly, scalar) + require.Equal(t, newPoly[0], scalar) + newPoly = append(newPoly, scalar2) + require.Equal(t, newPoly[1], scalar2) +} + +func TestAddAssignPoly(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + // Test polynomial with equal length + poly1 := polynomial{ + curve.Scalar.New(3), + curve.Scalar.New(2), + curve.Scalar.New(1), + } + poly2 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + curve.Scalar.New(3), + } + + output, err := poly1.Add(poly2) + require.NoError(t, err) + require.NotNil(t, output) + result := []curves.Scalar{ + curve.Scalar.New(4), + curve.Scalar.New(4), + curve.Scalar.New(4), + } + for i := 0; i < len(output); i++ { + require.Equal(t, output[i], result[i]) + } + + // Test polynomials with unequal length + poly3 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + } + output2, err := poly1.Add(poly3) + require.NoError(t, err) + require.NotNil(t, output2) + result2 := []curves.Scalar{ + curve.Scalar.New(4), + curve.Scalar.New(4), + curve.Scalar.New(1), + } + require.Equal(t, len(output2), len(result2)) + for i := 0; i < len(output2); i++ { + require.Equal(t, output2[i], result2[i]) + } +} + +func TestAddAssignPolyError(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + // Test polynomial with equal length + poly1 := polynomial{ + nil, + curve.Scalar.New(2), + curve.Scalar.New(1), + } + poly2 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + curve.Scalar.New(3), + } + + output, err := poly1.Add(poly2) + require.Error(t, err) + require.Nil(t, output) +} + +func TestSubAssignPoly(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + // Test polynomial with equal length + poly1 := polynomial{ + curve.Scalar.New(3), + curve.Scalar.New(2), + curve.Scalar.New(1), + } + poly2 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + curve.Scalar.New(3), + } + + output, err := poly1.Sub(poly2) + require.NoError(t, err) + require.NotNil(t, output) + result := []curves.Scalar{ + curve.Scalar.New(2), + curve.Scalar.New(0), + curve.Scalar.New(-2), + } + for i := 0; i < len(output); i++ { + require.Equal(t, output[i].Bytes(), result[i].Bytes()) + } + + // Test polynomials with unequal length + poly3 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + curve.Scalar.New(3), + curve.Scalar.New(4), + } + output2, err := poly1.Sub(poly3) + require.NoError(t, err) + require.NotNil(t, output2) + result2 := []curves.Scalar{ + curve.Scalar.New(2), + curve.Scalar.New(0), + curve.Scalar.New(-2), + curve.Scalar.New(-4), + } + require.Equal(t, len(output2), len(result2)) + for i := 0; i < len(output2); i++ { + require.Equal(t, output2[i].Bytes(), result2[i].Bytes()) + } +} + +func TestSubAssignPolyError(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly1 := polynomial{ + nil, + curve.Scalar.New(2), + curve.Scalar.New(1), + } + poly2 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + curve.Scalar.New(3), + } + + output, err := poly1.Sub(poly2) + require.Error(t, err) + require.Nil(t, output) +} + +func TestMulAssignPoly(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + // Test polynomial with equal length + poly1 := polynomial{ + curve.Scalar.New(3), + curve.Scalar.New(2), + curve.Scalar.New(1), + } + poly2 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + curve.Scalar.New(3), + } + + output, err := poly1.Mul(poly2) + require.NoError(t, err) + require.NotNil(t, output) + result := []curves.Scalar{ + curve.Scalar.New(3), + curve.Scalar.New(8), + curve.Scalar.New(14), + curve.Scalar.New(8), + curve.Scalar.New(3), + } + for i := 0; i < len(result); i++ { + require.Equal(t, output[i].Bytes(), result[i].Bytes()) + } + + // Test polynomials with unequal length + poly3 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + } + output2, err := poly1.Mul(poly3) + require.NoError(t, err) + require.NotNil(t, output2) + result2 := []curves.Scalar{ + curve.Scalar.New(3), + curve.Scalar.New(8), + curve.Scalar.New(5), + curve.Scalar.New(2), + } + require.Equal(t, len(output2), 4) + for i := 0; i < len(output2); i++ { + require.Equal(t, output2[i].Bytes(), result2[i].Bytes()) + } +} + +func TestMulAssignPolyError(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly1 := polynomial{ + nil, + curve.Scalar.New(2), + curve.Scalar.New(1), + } + poly2 := polynomial{ + curve.Scalar.New(1), + curve.Scalar.New(2), + curve.Scalar.New(3), + } + output, err := poly1.Mul(poly2) + require.Error(t, err) + require.Nil(t, output) +} + +func TestMulValueAssignPoly(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly := polynomial{ + curve.Scalar.New(3), + curve.Scalar.New(2), + curve.Scalar.New(1), + } + rhs := curve.Scalar.New(3) + output, err := poly.MulScalar(rhs) + require.NoError(t, err) + require.NotNil(t, output) + coefficients2 := []curves.Scalar{ + curve.Scalar.New(9), + curve.Scalar.New(6), + curve.Scalar.New(3), + } + for i := 0; i < len(coefficients2); i++ { + require.Equal(t, output[i].Bytes(), coefficients2[i].Bytes()) + } +} + +func TestMulValueAssignPolyError(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + poly := polynomial{ + nil, + curve.Scalar.New(2), + curve.Scalar.New(1), + } + rhs := curve.Scalar.New(3) + output, err := poly.MulScalar(rhs) + require.Error(t, err) + require.Nil(t, output) +} diff --git a/pkg/crypto/accumulator/proof.go b/pkg/crypto/accumulator/proof.go new file mode 100755 index 000000000..a32b665c7 --- /dev/null +++ b/pkg/crypto/accumulator/proof.go @@ -0,0 +1,518 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "bytes" + crand "crypto/rand" + "errors" + "fmt" + + "git.sr.ht/~sircmpwn/go-bare" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type proofParamsMarshal struct { + X []byte `bare:"x"` + Y []byte `bare:"y"` + Z []byte `bare:"z"` + Curve string `bare:"curve"` +} + +// ProofParams contains four distinct public generators of G1 - X, Y, Z +type ProofParams struct { + x, y, z curves.Point +} + +// New samples X, Y, Z, K +func (p *ProofParams) New(curve *curves.PairingCurve, pk *PublicKey, entropy []byte) (*ProofParams, error) { + pkBytes, err := pk.MarshalBinary() + if err != nil { + return nil, err + } + prefix := bytes.Repeat([]byte{0xFF}, 32) + data := append(prefix, entropy...) + data = append(data, pkBytes...) + p.z = curve.Scalar.Point().Hash(data) + + data[0] = 0xFE + p.y = curve.Scalar.Point().Hash(data) + + data[0] = 0xFD + p.x = curve.Scalar.Point().Hash(data) + + return p, nil +} + +// MarshalBinary converts ProofParams to bytes +func (p *ProofParams) MarshalBinary() ([]byte, error) { + if p.x == nil || p.y == nil || p.z == nil { + return nil, fmt.Errorf("some value x, y, or z is nil") + } + tv := &proofParamsMarshal{ + X: p.x.ToAffineCompressed(), + Y: p.y.ToAffineCompressed(), + Z: p.z.ToAffineCompressed(), + Curve: p.x.CurveName(), + } + return bare.Marshal(tv) +} + +// UnmarshalBinary converts bytes to ProofParams +func (p *ProofParams) UnmarshalBinary(data []byte) error { + if data == nil { + return fmt.Errorf("expected non-zero byte sequence") + } + tv := new(proofParamsMarshal) + err := bare.Unmarshal(data, tv) + if err != nil { + return err + } + curve := curves.GetCurveByName(tv.Curve) + if curve == nil { + return fmt.Errorf("invalid curve") + } + x, err := curve.NewIdentityPoint().FromAffineCompressed(tv.X) + if err != nil { + return err + } + y, err := curve.NewIdentityPoint().FromAffineCompressed(tv.Y) + if err != nil { + return err + } + z, err := curve.NewIdentityPoint().FromAffineCompressed(tv.Z) + if err != nil { + return err + } + p.x = x + p.y = y + p.z = z + return nil +} + +// MembershipProofCommitting contains value computed in Proof of knowledge and +// Blinding phases as described in section 7 of https://eprint.iacr.org/2020/777.pdf +type MembershipProofCommitting struct { + eC curves.Point + tSigma curves.Point + tRho curves.Point + deltaSigma curves.Scalar + deltaRho curves.Scalar + blindingFactor curves.Scalar + rSigma curves.Scalar + rRho curves.Scalar + rDeltaSigma curves.Scalar + rDeltaRho curves.Scalar + sigma curves.Scalar + rho curves.Scalar + capRSigma curves.Point + capRRho curves.Point + capRDeltaSigma curves.Point + capRDeltaRho curves.Point + capRE curves.Scalar + accumulator curves.Point + witnessValue curves.Scalar + xG1 curves.Point + yG1 curves.Point + zG1 curves.Point +} + +// New initiates values of MembershipProofCommitting +func (mpc *MembershipProofCommitting) New( + witness *MembershipWitness, + acc *Accumulator, + pp *ProofParams, + pk *PublicKey, +) (*MembershipProofCommitting, error) { + // Randomly select σ, ρ + sigma := witness.y.Random(crand.Reader) + rho := witness.y.Random(crand.Reader) + + // E_C = C + (σ + ρ)Z + t := sigma + t = t.Add(rho) + eC := pp.z + eC = eC.Mul(t) + eC = eC.Add(witness.c) + + // T_σ = σX + tSigma := pp.x + tSigma = tSigma.Mul(sigma) + + // T_ρ = ρY + tRho := pp.y + tRho = tRho.Mul(rho) + + // δ_σ = yσ + deltaSigma := witness.y + deltaSigma = deltaSigma.Mul(sigma) + + // δ_ρ = yρ + deltaRho := witness.y + deltaRho = deltaRho.Mul(rho) + + // Randomly pick r_σ,r_ρ,r_δσ,r_δρ + rY := witness.y.Random(crand.Reader) + rSigma := witness.y.Random(crand.Reader) + rRho := witness.y.Random(crand.Reader) + rDeltaSigma := witness.y.Random(crand.Reader) + rDeltaRho := witness.y.Random(crand.Reader) + + // R_σ = r_σ X + capRSigma := pp.x + capRSigma = capRSigma.Mul(rSigma) + + // R_ρ = ρY + capRRho := pp.y + capRRho = capRRho.Mul(rRho) + + // R_δσ = r_y T_σ - r_δσ X + negX := pp.x + negX = negX.Neg() + capRDeltaSigma := tSigma.Mul(rY) + capRDeltaSigma = capRDeltaSigma.Add(negX.Mul(rDeltaSigma)) + + // R_δρ = r_y T_ρ - r_δρ Y + negY := pp.y + negY = negY.Neg() + capRDeltaRho := tRho.Mul(rY) + capRDeltaRho = capRDeltaRho.Add(negY.Mul(rDeltaRho)) + + // P~ + g2 := pk.value.Generator() + + // -r_δσ - r_δρ + exp := rDeltaSigma + exp = exp.Add(rDeltaRho) + exp = exp.Neg() + + // -r_σ - r_ρ + exp2 := rSigma + exp2 = exp2.Add(rRho) + exp2 = exp2.Neg() + + // rY * eC + rYeC := eC.Mul(rY) + + // (-r_δσ - r_δρ)*Z + expZ := pp.z.Mul(exp) + + // (-r_σ - r_ρ)*Z + exp2Z := pp.z.Mul(exp2) + + // Prepare + rYeCPrep, ok := rYeC.(curves.PairingPoint) + if !ok { + return nil, errors.New("incorrect type conversion") + } + g2Prep, ok := g2.(curves.PairingPoint) + if !ok { + return nil, errors.New("incorrect type conversion") + } + expZPrep, ok := expZ.(curves.PairingPoint) + if !ok { + return nil, errors.New("incorrect type conversion") + } + exp2ZPrep, ok := exp2Z.(curves.PairingPoint) + if !ok { + return nil, errors.New("incorrect type conversion") + } + pkPrep := pk.value + + // Pairing + capRE := g2Prep.MultiPairing(rYeCPrep, g2Prep, expZPrep, g2Prep, exp2ZPrep, pkPrep) + + return &MembershipProofCommitting{ + eC, + tSigma, + tRho, + deltaSigma, + deltaRho, + rY, + rSigma, + rRho, + rDeltaSigma, + rDeltaRho, + sigma, + rho, + capRSigma, + capRRho, + capRDeltaSigma, + capRDeltaRho, + capRE, + acc.value, + witness.y, + pp.x, + pp.y, + pp.z, + }, nil +} + +// GetChallenge returns bytes that need to be hashed for generating challenge. +// V || Ec || T_sigma || T_rho || R_E || R_sigma || R_rho || R_delta_sigma || R_delta_rho +func (mpc MembershipProofCommitting) GetChallengeBytes() []byte { + res := mpc.accumulator.ToAffineCompressed() + res = append(res, mpc.eC.ToAffineCompressed()...) + res = append(res, mpc.tSigma.ToAffineCompressed()...) + res = append(res, mpc.tRho.ToAffineCompressed()...) + res = append(res, mpc.capRE.Bytes()...) + res = append(res, mpc.capRSigma.ToAffineCompressed()...) + res = append(res, mpc.capRRho.ToAffineCompressed()...) + res = append(res, mpc.capRDeltaSigma.ToAffineCompressed()...) + res = append(res, mpc.capRDeltaRho.ToAffineCompressed()...) + return res +} + +// GenProof computes the s values for Fiat-Shamir and return the actual +// proof to be sent to the verifier given the challenge c. +func (mpc *MembershipProofCommitting) GenProof(c curves.Scalar) *MembershipProof { + // s_y = r_y + c*y + sY := schnorr(mpc.blindingFactor, mpc.witnessValue, c) + // s_σ = r_σ + c*σ + sSigma := schnorr(mpc.rSigma, mpc.sigma, c) + // s_ρ = r_ρ + c*ρ + sRho := schnorr(mpc.rRho, mpc.rho, c) + // s_δσ = rδσ + c*δ_σ + sDeltaSigma := schnorr(mpc.rDeltaSigma, mpc.deltaSigma, c) + // s_δρ = rδρ + c*δ_ρ + sDeltaRho := schnorr(mpc.rDeltaRho, mpc.deltaRho, c) + + return &MembershipProof{ + mpc.eC, + mpc.tSigma, + mpc.tRho, + sSigma, + sRho, + sDeltaSigma, + sDeltaRho, + sY, + } +} + +func schnorr(r, v, challenge curves.Scalar) curves.Scalar { + res := v + res = res.Mul(challenge) + res = res.Add(r) + return res +} + +type membershipProofMarshal struct { + EC []byte `bare:"e_c"` + TSigma []byte `bare:"t_sigma"` + TRho []byte `bare:"t_rho"` + SSigma []byte `bare:"s_sigma"` + SRho []byte `bare:"s_rho"` + SDeltaSigma []byte `bare:"s_delta_sigma"` + SDeltaRho []byte `bare:"s_delta_rho"` + SY []byte `bare:"s_y"` + Curve string `bare:"curve"` +} + +// MembershipProof contains values in the proof to be verified +type MembershipProof struct { + eC curves.Point + tSigma curves.Point + tRho curves.Point + sSigma curves.Scalar + sRho curves.Scalar + sDeltaSigma curves.Scalar + sDeltaRho curves.Scalar + sY curves.Scalar +} + +// Finalize computes values in the proof to be verified. +func (mp *MembershipProof) Finalize(acc *Accumulator, pp *ProofParams, pk *PublicKey, challenge curves.Scalar) (*MembershipProofFinal, error) { + // R_σ = s_δ X + c T_σ + negTSigma := mp.tSigma + negTSigma = negTSigma.Neg() + capRSigma := pp.x.Mul(mp.sSigma) + capRSigma = capRSigma.Add(negTSigma.Mul(challenge)) + + // R_ρ = s_ρ Y + c T_ρ + negTRho := mp.tRho + negTRho = negTRho.Neg() + capRRho := pp.y.Mul(mp.sRho) + capRRho = capRRho.Add(negTRho.Mul(challenge)) + + // R_δσ = s_y T_σ - s_δσ X + negX := pp.x + negX = negX.Neg() + capRDeltaSigma := mp.tSigma.Mul(mp.sY) + capRDeltaSigma = capRDeltaSigma.Add(negX.Mul(mp.sDeltaSigma)) + + // R_δρ = s_y T_ρ - s_δρ Y + negY := pp.y + negY = negY.Neg() + capRDeltaRho := mp.tRho.Mul(mp.sY) + capRDeltaRho = capRDeltaRho.Add(negY.Mul(mp.sDeltaRho)) + + // tildeP + g2 := pk.value.Generator() + + // Compute capRE, the pairing + // E_c * s_y + eCsY := mp.eC.Mul(mp.sY) + + // (-s_delta_sigma - s_delta_rho) * Z + exp := mp.sDeltaSigma + exp = exp.Add(mp.sDeltaRho) + exp = exp.Neg() + expZ := pp.z.Mul(exp) + + // (-c) * V + exp = challenge.Neg() + expV := acc.value.Mul(exp) + + // E_c * s_y + (-s_delta_sigma - s_delta_rho) * Z + (-c) * V + lhs := eCsY.Add(expZ).Add(expV) + + // (-s_sigma - s_rho) * Z + exp = mp.sSigma + exp = exp.Add(mp.sRho) + exp = exp.Neg() + expZ2 := pp.z.Mul(exp) + + // E_c * c + cEc := mp.eC.Mul(challenge) + + // (-s_sigma - s_rho) * Z + E_c * c + rhs := cEc.Add(expZ2) + + // Prepare + lhsPrep, ok := lhs.(curves.PairingPoint) + if !ok { + return nil, errors.New("incorrect type conversion") + } + g2Prep, ok := g2.(curves.PairingPoint) + if !ok { + return nil, errors.New("incorrect type conversion") + } + rhsPrep, ok := rhs.(curves.PairingPoint) + if !ok { + return nil, errors.New("incorrect type conversion") + } + pkPrep := pk.value + + // capRE + capRE := g2Prep.MultiPairing(lhsPrep, g2Prep, rhsPrep, pkPrep) + + return &MembershipProofFinal{ + acc.value, + mp.eC, + mp.tSigma, + mp.tRho, + capRE, + capRSigma, + capRRho, + capRDeltaSigma, + capRDeltaRho, + }, nil +} + +// MarshalBinary converts MembershipProof to bytes +func (mp MembershipProof) MarshalBinary() ([]byte, error) { + tv := &membershipProofMarshal{ + EC: mp.eC.ToAffineCompressed(), + TSigma: mp.tSigma.ToAffineCompressed(), + TRho: mp.tRho.ToAffineCompressed(), + SSigma: mp.sSigma.Bytes(), + SRho: mp.sRho.Bytes(), + SDeltaSigma: mp.sDeltaSigma.Bytes(), + SDeltaRho: mp.sDeltaRho.Bytes(), + SY: mp.sY.Bytes(), + Curve: mp.eC.CurveName(), + } + return bare.Marshal(tv) +} + +// UnmarshalBinary converts bytes to MembershipProof +func (mp *MembershipProof) UnmarshalBinary(data []byte) error { + if data == nil { + return fmt.Errorf("expected non-zero byte sequence") + } + tv := new(membershipProofMarshal) + err := bare.Unmarshal(data, tv) + if err != nil { + return err + } + curve := curves.GetCurveByName(tv.Curve) + if curve == nil { + return fmt.Errorf("invalid curve") + } + eC, err := curve.NewIdentityPoint().FromAffineCompressed(tv.EC) + if err != nil { + return err + } + tSigma, err := curve.NewIdentityPoint().FromAffineCompressed(tv.TSigma) + if err != nil { + return err + } + tRho, err := curve.NewIdentityPoint().FromAffineCompressed(tv.TRho) + if err != nil { + return err + } + sSigma, err := curve.NewScalar().SetBytes(tv.SSigma) + if err != nil { + return err + } + sRho, err := curve.NewScalar().SetBytes(tv.SRho) + if err != nil { + return err + } + sDeltaSigma, err := curve.NewScalar().SetBytes(tv.SDeltaSigma) + if err != nil { + return err + } + sDeltaRho, err := curve.NewScalar().SetBytes(tv.SDeltaRho) + if err != nil { + return err + } + sY, err := curve.NewScalar().SetBytes(tv.SY) + if err != nil { + return err + } + + mp.eC = eC + mp.tSigma = tSigma + mp.tRho = tRho + mp.sSigma = sSigma + mp.sRho = sRho + mp.sDeltaSigma = sDeltaSigma + mp.sDeltaRho = sDeltaRho + mp.sY = sY + + return nil +} + +// MembershipProofFinal contains values that are input to Fiat-Shamir Heuristic +type MembershipProofFinal struct { + accumulator curves.Point + eC curves.Point + tSigma curves.Point + tRho curves.Point + capRE curves.Scalar + capRSigma curves.Point + capRRho curves.Point + capRDeltaSigma curves.Point + capRDeltaRho curves.Point +} + +// GetChallenge computes Fiat-Shamir Heuristic taking input values of MembershipProofFinal +func (m MembershipProofFinal) GetChallenge(curve *curves.PairingCurve) curves.Scalar { + res := m.accumulator.ToAffineCompressed() + res = append(res, m.eC.ToAffineCompressed()...) + res = append(res, m.tSigma.ToAffineCompressed()...) + res = append(res, m.tRho.ToAffineCompressed()...) + res = append(res, m.capRE.Bytes()...) + res = append(res, m.capRSigma.ToAffineCompressed()...) + res = append(res, m.capRRho.ToAffineCompressed()...) + res = append(res, m.capRDeltaSigma.ToAffineCompressed()...) + res = append(res, m.capRDeltaRho.ToAffineCompressed()...) + challenge := curve.Scalar.Hash(res) + return challenge +} diff --git a/pkg/crypto/accumulator/proof_test.go b/pkg/crypto/accumulator/proof_test.go new file mode 100755 index 000000000..eedbde88e --- /dev/null +++ b/pkg/crypto/accumulator/proof_test.go @@ -0,0 +1,182 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestProofParamsMarshal(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + sk, _ := new(SecretKey).New(curve, []byte("1234567890")) + pk, _ := sk.GetPublicKey(curve) + + params, err := new(ProofParams).New(curve, pk, []byte("entropy")) + require.NoError(t, err) + require.NotNil(t, params.x) + require.NotNil(t, params.y) + require.NotNil(t, params.z) + + bytes, err := params.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, bytes) + + params2 := &ProofParams{ + curve.PointG1.Generator(), + curve.PointG1.Generator(), + curve.PointG1.Generator(), + } + err = params2.UnmarshalBinary(bytes) + require.NoError(t, err) + require.True(t, params.x.Equal(params2.x)) + require.True(t, params.y.Equal(params2.y)) + require.True(t, params.z.Equal(params2.z)) +} + +func TestMembershipProof(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + sk, _ := new(SecretKey).New(curve, []byte("1234567890")) + pk, _ := sk.GetPublicKey(curve) + + element1 := curve.Scalar.Hash([]byte("3")) + element2 := curve.Scalar.Hash([]byte("4")) + element3 := curve.Scalar.Hash([]byte("5")) + element4 := curve.Scalar.Hash([]byte("6")) + element5 := curve.Scalar.Hash([]byte("7")) + element6 := curve.Scalar.Hash([]byte("8")) + element7 := curve.Scalar.Hash([]byte("9")) + elements := []Element{element1, element2, element3, element4, element5, element6, element7} + + // Initiate a new accumulator + acc, err := new(Accumulator).WithElements(curve, sk, elements) + require.NoError(t, err) + require.NotNil(t, acc.value) + + // Initiate a new membership witness for value elements[3] + wit, err := new(MembershipWitness).New(elements[3], acc, sk) + require.NoError(t, err) + require.Equal(t, wit.y, elements[3]) + + // Create proof parameters, which contains randomly sampled G1 points X, Y, Z, K + params, err := new(ProofParams).New(curve, pk, []byte("entropy")) + require.NoError(t, err) + require.NotNil(t, params.x) + require.NotNil(t, params.y) + require.NotNil(t, params.z) + + mpc, err := new(MembershipProofCommitting).New(wit, acc, params, pk) + require.NoError(t, err) + testMPC(t, mpc) + + challenge := curve.Scalar.Hash(mpc.GetChallengeBytes()) + require.NotNil(t, challenge) + + proof := mpc.GenProof(challenge) + require.NotNil(t, proof) + testProof(t, proof) + + finalProof, err := proof.Finalize(acc, params, pk, challenge) + require.NoError(t, err) + require.NotNil(t, finalProof) + testFinalProof(t, finalProof) + + challenge2 := finalProof.GetChallenge(curve) + require.Equal(t, challenge, challenge2) + + // Check we can still have a valid proof even if accumulator and witness are updated + data1 := curve.Scalar.Hash([]byte("1")) + data2 := curve.Scalar.Hash([]byte("2")) + data3 := curve.Scalar.Hash([]byte("3")) + data4 := curve.Scalar.Hash([]byte("4")) + data5 := curve.Scalar.Hash([]byte("5")) + data := []Element{data1, data2, data3, data4, data5} + additions := data[0:2] + deletions := data[2:5] + _, coefficients, err := acc.Update(sk, additions, deletions) + require.NoError(t, err) + require.NotNil(t, coefficients) + + _, err = wit.BatchUpdate(additions, deletions, coefficients) + require.NoError(t, err) + + newParams, err := new(ProofParams).New(curve, pk, []byte("entropy")) + require.NoError(t, err) + require.NotNil(t, newParams.x) + require.NotNil(t, newParams.y) + require.NotNil(t, newParams.z) + + newMPC, err := new(MembershipProofCommitting).New(wit, acc, newParams, pk) + require.NoError(t, err) + testMPC(t, newMPC) + + challenge3 := curve.Scalar.Hash(newMPC.GetChallengeBytes()) + require.NotNil(t, challenge3) + + newProof := newMPC.GenProof(challenge3) + require.NotNil(t, newProof) + testProof(t, newProof) + + newFinalProof, err := newProof.Finalize(acc, newParams, pk, challenge3) + require.NoError(t, err) + require.NotNil(t, newFinalProof) + testFinalProof(t, newFinalProof) + + challenge4 := newFinalProof.GetChallenge(curve) + require.Equal(t, challenge3, challenge4) +} + +func testMPC(t *testing.T, mpc *MembershipProofCommitting) { + require.NotNil(t, mpc.eC) + require.NotNil(t, mpc.tSigma) + require.NotNil(t, mpc.tRho) + require.NotNil(t, mpc.deltaSigma) + require.NotNil(t, mpc.deltaRho) + require.NotNil(t, mpc.blindingFactor) + require.NotNil(t, mpc.rSigma) + require.NotNil(t, mpc.rRho) + require.NotNil(t, mpc.rDeltaSigma) + require.NotNil(t, mpc.rDeltaRho) + require.NotNil(t, mpc.sigma) + require.NotNil(t, mpc.rho) + require.NotNil(t, mpc.capRSigma) + require.NotNil(t, mpc.capRRho) + require.NotNil(t, mpc.capRDeltaSigma) + require.NotNil(t, mpc.capRDeltaRho) + require.NotNil(t, mpc.capRE) + require.NotNil(t, mpc.accumulator) + require.NotNil(t, mpc.witnessValue) + require.NotNil(t, mpc.xG1) + require.NotNil(t, mpc.yG1) + require.NotNil(t, mpc.zG1) +} + +func testProof(t *testing.T, proof *MembershipProof) { + require.NotNil(t, proof.eC) + require.NotNil(t, proof.tSigma) + require.NotNil(t, proof.tRho) + require.NotNil(t, proof.sSigma) + require.NotNil(t, proof.sRho) + require.NotNil(t, proof.sDeltaSigma) + require.NotNil(t, proof.sDeltaRho) + require.NotNil(t, proof.sY) +} + +func testFinalProof(t *testing.T, finalProof *MembershipProofFinal) { + require.NotNil(t, finalProof.accumulator) + require.NotNil(t, finalProof.eC) + require.NotNil(t, finalProof.tSigma) + require.NotNil(t, finalProof.tRho) + require.NotNil(t, finalProof.capRE) + require.NotNil(t, finalProof.capRSigma) + require.NotNil(t, finalProof.capRRho) + require.NotNil(t, finalProof.capRDeltaSigma) + require.NotNil(t, finalProof.capRDeltaRho) +} diff --git a/pkg/crypto/accumulator/witness.go b/pkg/crypto/accumulator/witness.go new file mode 100755 index 000000000..585ee5d88 --- /dev/null +++ b/pkg/crypto/accumulator/witness.go @@ -0,0 +1,375 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "errors" + "fmt" + + "git.sr.ht/~sircmpwn/go-bare" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// MembershipWitness contains the witness c and the value y respect to the accumulator state. +type MembershipWitness struct { + c curves.Point + y curves.Scalar +} + +// New creates a new membership witness +func (mw *MembershipWitness) New(y Element, acc *Accumulator, sk *SecretKey) (*MembershipWitness, error) { + if acc.value == nil || acc.value.IsIdentity() { + return nil, fmt.Errorf("value of accumulator should not be nil") + } + if sk.value == nil || sk.value.IsZero() { + return nil, fmt.Errorf("secret key should not be nil") + } + if y == nil || y.IsZero() { + return nil, fmt.Errorf("y should not be nil") + } + newAcc := &Accumulator{acc.value} + _, err := newAcc.Remove(sk, y) + if err != nil { + return nil, err + } + mw.c = newAcc.value + mw.y = y.Add(y.Zero()) + return mw, nil +} + +// Verify the MembershipWitness mw is a valid witness as per section 4 in +// +func (mw MembershipWitness) Verify(pk *PublicKey, acc *Accumulator) error { + if mw.c == nil || mw.y == nil || mw.c.IsIdentity() || mw.y.IsZero() { + return fmt.Errorf("c and y should not be nil") + } + + if pk.value == nil || pk.value.IsIdentity() { + return fmt.Errorf("invalid public key") + } + if acc.value == nil || acc.value.IsIdentity() { + return fmt.Errorf("accumulator value should not be nil") + } + + // Set -tildeP + g2, ok := pk.value.Generator().(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + + // y*tildeP + tildeQ, tildeP is a G2 generator. + p, ok := g2.Mul(mw.y).Add(pk.value).(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + + // Prepare + witness, ok := mw.c.(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + v, ok := acc.value.Neg().(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + + // Check e(witness, y*tildeP + tildeQ) * e(-acc, tildeP) == Identity + result := p.MultiPairing(witness, p, v, g2) + if !result.IsOne() { + return fmt.Errorf("invalid result") + } + + return nil +} + +// ApplyDelta returns C' = dA(y)/dD(y)*C + 1/dD(y) * +// according to the witness update protocol described in section 4 of +// https://eprint.iacr.org/2020/777.pdf +func (mw *MembershipWitness) ApplyDelta(delta *Delta) (*MembershipWitness, error) { + if mw.c == nil || mw.y == nil || delta == nil { + return nil, fmt.Errorf("y, c or delta should not be nil") + } + + // C' = dA(y)/dD(y)*C + 1/dD(y) * + mw.c = mw.c.Mul(delta.d).Add(delta.p) + return mw, nil +} + +// BatchUpdate performs batch update as described in section 4 +func (mw *MembershipWitness) BatchUpdate(additions []Element, deletions []Element, coefficients []Coefficient) (*MembershipWitness, error) { + delta, err := evaluateDelta(mw.y, additions, deletions, coefficients) + if err != nil { + return nil, err + } + mw, err = mw.ApplyDelta(delta) + if err != nil { + return nil, fmt.Errorf("applyDelta fails") + } + return mw, nil +} + +// MultiBatchUpdate performs multi-batch update using epoch as described in section 4.2 +func (mw *MembershipWitness) MultiBatchUpdate(A [][]Element, D [][]Element, C [][]Coefficient) (*MembershipWitness, error) { + delta, err := evaluateDeltas(mw.y, A, D, C) + if err != nil { + return nil, fmt.Errorf("evaluateDeltas fails") + } + mw, err = mw.ApplyDelta(delta) + if err != nil { + return nil, err + } + return mw, nil +} + +// MarshalBinary converts a membership witness to bytes +func (mw MembershipWitness) MarshalBinary() ([]byte, error) { + if mw.c == nil || mw.y == nil { + return nil, fmt.Errorf("c and y value should not be nil") + } + + result := append(mw.c.ToAffineCompressed(), mw.y.Bytes()...) + tv := &structMarshal{ + Value: result, + Curve: mw.c.CurveName(), + } + return bare.Marshal(tv) +} + +// UnmarshalBinary converts bytes into MembershipWitness +func (mw *MembershipWitness) UnmarshalBinary(data []byte) error { + if data == nil { + return fmt.Errorf("input data should not be nil") + } + tv := new(structMarshal) + err := bare.Unmarshal(data, tv) + if err != nil { + return err + } + curve := curves.GetCurveByName(tv.Curve) + if curve == nil { + return fmt.Errorf("invalid curve") + } + + ptLength := len(curve.Point.ToAffineCompressed()) + scLength := len(curve.Scalar.Bytes()) + expectedLength := ptLength + scLength + if len(tv.Value) != expectedLength { + return fmt.Errorf("invalid byte sequence") + } + cValue, err := curve.Point.FromAffineCompressed(tv.Value[:ptLength]) + if err != nil { + return err + } + yValue, err := curve.Scalar.SetBytes(tv.Value[ptLength:]) + if err != nil { + return err + } + mw.c = cValue + mw.y = yValue + return nil +} + +// Delta contains values d and p, where d should be the division dA(y)/dD(y) on some value y +// p should be equal to 1/dD * +type Delta struct { + d curves.Scalar + p curves.Point +} + +// MarshalBinary converts Delta into bytes +func (d *Delta) MarshalBinary() ([]byte, error) { + if d.d == nil || d.p == nil { + return nil, fmt.Errorf("d and p should not be nil") + } + var result []byte + result = append(result, d.p.ToAffineCompressed()...) + result = append(result, d.d.Bytes()...) + tv := &structMarshal{ + Value: result, + Curve: d.p.CurveName(), + } + return bare.Marshal(tv) +} + +// UnmarshalBinary converts data into Delta +func (d *Delta) UnmarshalBinary(data []byte) error { + if data == nil { + return fmt.Errorf("expected non-zero byte sequence") + } + + tv := new(structMarshal) + err := bare.Unmarshal(data, tv) + if err != nil { + return err + } + curve := curves.GetCurveByName(tv.Curve) + if curve == nil { + return fmt.Errorf("invalid curve") + } + + ptLength := len(curve.Point.ToAffineCompressed()) + scLength := len(curve.Scalar.Bytes()) + expectedLength := ptLength + scLength + if len(tv.Value) != expectedLength { + return fmt.Errorf("invalid byte sequence") + } + pValue, err := curve.NewIdentityPoint().FromAffineCompressed(tv.Value[:ptLength]) + if err != nil { + return err + } + dValue, err := curve.NewScalar().SetBytes(tv.Value[ptLength:]) + if err != nil { + return err + } + d.d = dValue + d.p = pValue + return nil +} + +// evaluateDeltas compute values used for membership witness batch update with epoch +// as described in section 4.2, page 11 of https://eprint.iacr.org/2020/777.pdf +func evaluateDeltas(y Element, A [][]Element, D [][]Element, C [][]Coefficient) (*Delta, error) { + if len(A) != len(D) || len(A) != len(C) { + return nil, fmt.Errorf("a, d, c should have same length") + } + + one := y.One() + size := len(A) + + // dA(x) = ∏ 1..n (yA_i - x) + aa := make([]curves.Scalar, 0) + // dD(x) = ∏ 1..m (yD_i - x) + dd := make([]curves.Scalar, 0) + + a := one + d := one + + // dA_{a->b}(y) = ∏ a..b dAs(y) + // dD_{a->b}(y) = ∏ a..b dDs(y) + for i := 0; i < size; i++ { + adds := A[i] + dels := D[i] + + // ta = dAs(y) + ta, err := dad(adds, y) + if err != nil { + return nil, fmt.Errorf("dad on additions fails") + } + // td = dDs(y) + td, err := dad(dels, y) + if err != nil { + return nil, fmt.Errorf("dad on deletions fails") + } + // ∏ a..b dAs(y) + a = a.Mul(ta) + // ∏ a..b dDs(y) + d = d.Mul(td) + + aa = append(aa, ta) + dd = append(dd, td) + } + + // If this fails, then this value was removed. + d, err := d.Invert() + if err != nil { + return nil, fmt.Errorf("no inverse exists") + } + + // + p := make(polynomialPoint, 0, size) + + // Ωi->j+1 = ∑ 1..t (dAt * dDt-1) · Ω + for i := 0; i < size; i++ { + // t = i+1 + // ∏^(t-1)_(h=i+1) + ddh := one + + // dDi→t−1 (y) + for h := 0; h < i; h++ { + ddh = ddh.Mul(dd[h]) + } + + // ∏^(j+1)_(k=t+1) + dak := one + // dAt->j(y) + for k := i + 1; k < size; k++ { + dak = dak.Mul(aa[k]) + } + + // dDi->t-1(y) * dAt->j(y) + dak = dak.Mul(ddh) + pp := make(polynomialPoint, len(C[i])) + for j := 0; j < len(pp); j++ { + pp[j] = C[i][j] + } + + // dDi->t-1(y) * dAt->j(y) · Ω + pp, err := pp.Mul(dak) + if err != nil { + return nil, fmt.Errorf("pp.Mul fails") + } + + p, err = p.Add(pp) + if err != nil { + return nil, fmt.Errorf("pp.Add fails") + } + } + // dAi->j(y)/dDi->j(y) + a = a.Mul(d) + + // Ωi->j(y) + v, err := p.evaluate(y) + if err != nil { + return nil, fmt.Errorf("p.evaluate fails") + } + + // (1/dDi->j(y)) * Ωi->j(y) + v = v.Mul(d) + + // return + return &Delta{d: a, p: v}, nil +} + +// evaluateDelta computes values used for membership witness batch update +// as described in section 4.1 of https://eprint.iacr.org/2020/777.pdf +func evaluateDelta(y Element, additions []Element, deletions []Element, coefficients []Coefficient) (*Delta, error) { + // dD(y) = ∏ 1..m (yD_i - y), d = 1/dD(y) + var err error + d, err := dad(deletions, y) + if err != nil { + return nil, fmt.Errorf("dad fails on deletions") + } + d, err = d.Invert() + if err != nil { + return nil, fmt.Errorf("no inverse exists") + } + + // dA(y) = ∏ 1..n (yA_i - y) + a, err := dad(additions, y) + if err != nil { + return nil, fmt.Errorf("dad fails on additions") + } + // dA(y)/dD(y) + a = a.Mul(d) + + // Create a PolynomialG1 from coefficients + p := make(polynomialPoint, len(coefficients)) + for i := 0; i < len(coefficients); i++ { + p[i] = coefficients[i] + } + + // + v, err := p.evaluate(y) + if err != nil { + return nil, fmt.Errorf("p.evaluate fails") + } + // 1/dD * + v = v.Mul(d) + + return &Delta{d: a, p: v}, nil +} diff --git a/pkg/crypto/accumulator/witness_test.go b/pkg/crypto/accumulator/witness_test.go new file mode 100755 index 000000000..bb0880c9b --- /dev/null +++ b/pkg/crypto/accumulator/witness_test.go @@ -0,0 +1,229 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package accumulator + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func Test_Membership_Witness_New(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + var seed [32]byte + key, _ := new(SecretKey).New(curve, seed[:]) + acc, _ := new(Accumulator).New(curve) + e := curve.Scalar.New(2) + mw, err := new(MembershipWitness).New(e, acc, key) + require.NoError(t, err) + require.NotNil(t, mw.c) + require.NotNil(t, mw.y) +} + +func Test_Membership_Witness_Marshal(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + mw := &MembershipWitness{ + curve.PointG1.Generator().Mul(curve.Scalar.New(10)), + curve.Scalar.New(15), + } + data, err := mw.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, data) + newMW := &MembershipWitness{} + err = newMW.UnmarshalBinary(data) + require.NoError(t, err) + require.True(t, mw.c.Equal(newMW.c)) + require.Equal(t, 0, mw.y.Cmp(newMW.y)) +} + +func Test_Membership(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + sk, _ := new(SecretKey).New(curve, []byte("1234567890")) + pk, _ := sk.GetPublicKey(curve) + + element1 := curve.Scalar.Hash([]byte("3")) + element2 := curve.Scalar.Hash([]byte("4")) + element3 := curve.Scalar.Hash([]byte("5")) + element4 := curve.Scalar.Hash([]byte("6")) + element5 := curve.Scalar.Hash([]byte("7")) + element6 := curve.Scalar.Hash([]byte("8")) + element7 := curve.Scalar.Hash([]byte("9")) + elements := []Element{element1, element2, element3, element4, element5, element6, element7} + + // nm_witness_max works as well if set to value larger than 0 for this test.x + acc, err := new(Accumulator).WithElements(curve, sk, elements) + require.NoError(t, err) + require.NotNil(t, acc.value) + require.False(t, acc.value.IsIdentity()) + require.True(t, acc.value.IsOnCurve()) + require.NotEqual(t, acc.value, curve.NewG1GeneratorPoint()) + + wit, err := new(MembershipWitness).New(elements[3], acc, sk) + require.NoError(t, err) + require.Equal(t, wit.y, elements[3]) + + err = wit.Verify(pk, acc) + require.NoError(t, err) + + // Test wrong cases, forge a wrong witness + wrongWit := MembershipWitness{ + curve.PointG1.Identity(), + curve.Scalar.One(), + } + err = wrongWit.Verify(pk, acc) + require.Error(t, err) + + // Test wrong cases, forge a wrong accumulator + wrongAcc := &Accumulator{ + curve.PointG1.Generator(), + } + err = wit.Verify(pk, wrongAcc) + require.Error(t, err) +} + +func Test_Membership_Batch_Update(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + sk, _ := new(SecretKey).New(curve, []byte("1234567890")) + pk, _ := sk.GetPublicKey(curve) + + element1 := curve.Scalar.Hash([]byte("3")) + element2 := curve.Scalar.Hash([]byte("4")) + element3 := curve.Scalar.Hash([]byte("5")) + element4 := curve.Scalar.Hash([]byte("6")) + element5 := curve.Scalar.Hash([]byte("7")) + element6 := curve.Scalar.Hash([]byte("8")) + element7 := curve.Scalar.Hash([]byte("9")) + elements := []Element{element1, element2, element3, element4, element5, element6, element7} + + // nm_witness_max works as well if set to value larger than 0 for this test. + acc, err := new(Accumulator).WithElements(curve, sk, elements) + require.NoError(t, err) + require.NotNil(t, acc.value) + + wit, err := new(MembershipWitness).New(elements[3], acc, sk) + require.NoError(t, err) + require.Equal(t, wit.y, elements[3]) + + err = wit.Verify(pk, acc) + require.Nil(t, err) + + data1 := curve.Scalar.Hash([]byte("1")) + data2 := curve.Scalar.Hash([]byte("2")) + data3 := curve.Scalar.Hash([]byte("3")) + data4 := curve.Scalar.Hash([]byte("4")) + data5 := curve.Scalar.Hash([]byte("5")) + data := []Element{data1, data2, data3, data4, data5} + additions := data[0:2] + deletions := data[2:5] + _, coefficients, err := acc.Update(sk, additions, deletions) + require.NoError(t, err) + require.NotNil(t, coefficients) + + _, err = wit.BatchUpdate(additions, deletions, coefficients) + require.NoError(t, err) + err = wit.Verify(pk, acc) + require.Nil(t, err) +} + +func Test_Membership_Multi_Batch_Update(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G1{}) + sk, _ := new(SecretKey).New(curve, []byte("1234567890")) + pk, _ := sk.GetPublicKey(curve) + + element1 := curve.Scalar.Hash([]byte("3")) + element2 := curve.Scalar.Hash([]byte("4")) + element3 := curve.Scalar.Hash([]byte("5")) + element4 := curve.Scalar.Hash([]byte("6")) + element5 := curve.Scalar.Hash([]byte("7")) + element6 := curve.Scalar.Hash([]byte("8")) + element7 := curve.Scalar.Hash([]byte("9")) + element8 := curve.Scalar.Hash([]byte("10")) + element9 := curve.Scalar.Hash([]byte("11")) + element10 := curve.Scalar.Hash([]byte("12")) + element11 := curve.Scalar.Hash([]byte("13")) + element12 := curve.Scalar.Hash([]byte("14")) + element13 := curve.Scalar.Hash([]byte("15")) + element14 := curve.Scalar.Hash([]byte("16")) + element15 := curve.Scalar.Hash([]byte("17")) + element16 := curve.Scalar.Hash([]byte("18")) + element17 := curve.Scalar.Hash([]byte("19")) + element18 := curve.Scalar.Hash([]byte("20")) + elements := []Element{ + element1, + element2, + element3, + element4, + element5, + element6, + element7, + element8, + element9, + element10, + element11, + element12, + element13, + element14, + element15, + element16, + element17, + element18, + } + acc, err := new(Accumulator).WithElements(curve, sk, elements) + require.NoError(t, err) + require.NotNil(t, acc.value) + + wit, err := new(MembershipWitness).New(elements[3], acc, sk) + require.NoError(t, err) + + err = wit.Verify(pk, acc) + require.Nil(t, err) + + data1 := curve.Scalar.Hash([]byte("1")) + data2 := curve.Scalar.Hash([]byte("2")) + data3 := curve.Scalar.Hash([]byte("3")) + data4 := curve.Scalar.Hash([]byte("4")) + data5 := curve.Scalar.Hash([]byte("5")) + data := []Element{data1, data2, data3, data4, data5} + adds1 := data[0:2] + dels1 := data[2:5] + _, coeffs1, err := acc.Update(sk, adds1, dels1) + require.NoError(t, err) + require.NotNil(t, coeffs1) + + dels2 := elements[8:10] + _, coeffs2, err := acc.Update(sk, []Element{}, dels2) + require.NoError(t, err) + require.NotNil(t, coeffs2) + + dels3 := elements[11:14] + _, coeffs3, err := acc.Update(sk, []Element{}, dels3) + require.NoError(t, err) + require.NotNil(t, coeffs3) + + a := make([][]Element, 3) + a[0] = adds1 + a[1] = []Element{} + a[2] = []Element{} + + d := make([][]Element, 3) + d[0] = dels1 + d[1] = dels2 + d[2] = dels3 + + c := make([][]Coefficient, 3) + c[0] = coeffs1 + c[1] = coeffs2 + c[2] = coeffs3 + + _, err = wit.MultiBatchUpdate(a, d, c) + require.NoError(t, err) + + err = wit.Verify(pk, acc) + require.Nil(t, err) +} diff --git a/pkg/crypto/bip32/bip32.go b/pkg/crypto/bip32/bip32.go new file mode 100644 index 000000000..3bc14cbeb --- /dev/null +++ b/pkg/crypto/bip32/bip32.go @@ -0,0 +1,66 @@ +package bip32 + +import ( + "crypto/hmac" + "crypto/sha512" + "encoding/binary" + "errors" + "math/big" + + "github.com/btcsuite/btcd/btcec/v2" +) + +// ComputePublicKey computes the public key of a child key given the extended public key, chain code, and index. +func ComputePublicKey(extPubKey []byte, chainCode uint32, index int) ([]byte, error) { + // Check if the index is a hardened child key + if chainCode&0x80000000 != 0 && index < 0 { + return nil, errors.New("invalid index") + } + + // Serialize the public key + pubKey, err := btcec.ParsePubKey(extPubKey) + if err != nil { + return nil, err + } + pubKeyBytes := pubKey.SerializeCompressed() + + // Serialize the index + indexBytes := make([]byte, 4) + binary.BigEndian.PutUint32(indexBytes, uint32(index)) + + // Compute the HMAC-SHA512 + mac := hmac.New(sha512.New, []byte{byte(chainCode)}) + mac.Write(pubKeyBytes) + mac.Write(indexBytes) + I := mac.Sum(nil) + + // Split I into two 32-byte sequences + IL := I[:32] + + // Convert IL to a big integer + ilNum := new(big.Int).SetBytes(IL) + + // Check if parse256(IL) >= n + curve := btcec.S256() + if ilNum.Cmp(curve.N) >= 0 { + return nil, errors.New("invalid child key") + } + + // Compute the child public key + ilx, ily := curve.ScalarBaseMult(IL) + childX, childY := curve.Add(ilx, ily, pubKey.X(), pubKey.Y()) + lx := newBigIntFieldVal(childX) + ly := newBigIntFieldVal(childY) + + // Create the child public key + childPubKey := btcec.NewPublicKey(lx, ly) + childPubKeyBytes := childPubKey.SerializeCompressed() + return childPubKeyBytes, nil +} + +// newBigIntFieldVal creates a new field value from a big integer. +func newBigIntFieldVal(val *big.Int) *btcec.FieldVal { + lx := new(btcec.FieldVal) + lx.SetByteSlice(val.Bytes()) + return lx +} diff --git a/pkg/crypto/bulletproof/generators.go b/pkg/crypto/bulletproof/generators.go new file mode 100755 index 000000000..71d793c8a --- /dev/null +++ b/pkg/crypto/bulletproof/generators.go @@ -0,0 +1,57 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bulletproof + +import ( + "github.com/pkg/errors" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// generators contains a list of points to be used as generators for bulletproofs. +type generators []curves.Point + +// ippGenerators holds generators necessary for an Inner Product Proof +// It includes a single u generator, and a list of generators divided in half to G and H +// See lines 10 on pg 16 of https://eprint.iacr.org/2017/1066.pdf +type ippGenerators struct { + G generators + H generators +} + +// getGeneratorPoints generates generators using HashToCurve with Shake256(domain) as input +// lenVector is the length of the scalars used for the Inner Product Proof +// getGeneratorPoints will return 2*lenVector + 1 total points, split between a single u generator +// and G and H lists of vectors per the IPP specification +// See lines 10 on pg 16 of https://eprint.iacr.org/2017/1066.pdf +func getGeneratorPoints(lenVector int, domain []byte, curve curves.Curve) (*ippGenerators, error) { + shake := sha3.NewShake256() + _, err := shake.Write(domain) + if err != nil { + return nil, errors.Wrap(err, "getGeneratorPoints shake.Write") + } + numPoints := lenVector * 2 + points := make([]curves.Point, numPoints) + for i := 0; i < numPoints; i++ { + bytes := [64]byte{} + _, err := shake.Read(bytes[:]) + if err != nil { + return nil, errors.Wrap(err, "getGeneratorPoints shake.Read") + } + nextPoint := curve.Point.Hash(bytes[:]) + points[i] = nextPoint + } + // Get G and H by splitting points in half + G, H, err := splitPointVector(points) + if err != nil { + return nil, errors.Wrap(err, "getGeneratorPoints splitPointVector") + } + out := ippGenerators{G: G, H: H} + + return &out, nil +} diff --git a/pkg/crypto/bulletproof/generators_test.go b/pkg/crypto/bulletproof/generators_test.go new file mode 100755 index 000000000..b3d0ff6b5 --- /dev/null +++ b/pkg/crypto/bulletproof/generators_test.go @@ -0,0 +1,61 @@ +package bulletproof + +import ( + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestGeneratorsHappyPath(t *testing.T) { + curve := curves.ED25519() + gs, err := getGeneratorPoints(10, []byte("test"), *curve) + gsConcatenated := concatIPPGenerators(*gs) + require.NoError(t, err) + require.Len(t, gs.G, 10) + require.Len(t, gs.H, 10) + require.True(t, noDuplicates(gsConcatenated)) +} + +func TestGeneratorsUniquePerDomain(t *testing.T) { + curve := curves.ED25519() + gs1, err := getGeneratorPoints(10, []byte("test"), *curve) + gs1Concatenated := concatIPPGenerators(*gs1) + require.NoError(t, err) + gs2, err := getGeneratorPoints(10, []byte("test2"), *curve) + gs2Concatenated := concatIPPGenerators(*gs2) + require.NoError(t, err) + require.True(t, areDisjoint(gs1Concatenated, gs2Concatenated)) +} + +func noDuplicates(gs generators) bool { + seen := map[[32]byte]bool{} + for _, G := range gs { + value := sha3.Sum256(G.ToAffineCompressed()) + if seen[value] { + return false + } + seen[value] = true + } + return true +} + +func areDisjoint(gs1, gs2 generators) bool { + for _, g1 := range gs1 { + for _, g2 := range gs2 { + if g1.Equal(g2) { + return false + } + } + } + return true +} + +func concatIPPGenerators(ippGens ippGenerators) generators { + var out generators + out = append(out, ippGens.G...) + out = append(out, ippGens.H...) + return out +} diff --git a/pkg/crypto/bulletproof/helpers.go b/pkg/crypto/bulletproof/helpers.go new file mode 100755 index 000000000..f7b14ba1f --- /dev/null +++ b/pkg/crypto/bulletproof/helpers.go @@ -0,0 +1,181 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bulletproof + +import ( + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// innerProduct takes two lists of scalars (a, b) and performs the dot product returning a single scalar. +func innerProduct(a, b []curves.Scalar) (curves.Scalar, error) { + if len(a) != len(b) { + return nil, errors.New("length of scalar vectors must be the same") + } + if len(a) < 1 { + return nil, errors.New("length of vectors must be at least one") + } + // Get a new scalar of value zero of the same curve as input arguments + innerProduct := a[0].Zero() + for i, aElem := range a { + bElem := b[i] + // innerProduct = aElem*bElem + innerProduct + innerProduct = aElem.MulAdd(bElem, innerProduct) + } + + return innerProduct, nil +} + +// splitPointVector takes a vector of points, splits it in half returning each half. +func splitPointVector(points []curves.Point) ([]curves.Point, []curves.Point, error) { + if len(points) < 1 { + return nil, nil, errors.New("length of points must be at least one") + } + if len(points)&0x01 != 0 { + return nil, nil, errors.New("length of points must be even") + } + nPrime := len(points) >> 1 + firstHalf := points[:nPrime] + secondHalf := points[nPrime:] + return firstHalf, secondHalf, nil +} + +// splitScalarVector takes a vector of scalars, splits it in half returning each half. +func splitScalarVector(scalars []curves.Scalar) ([]curves.Scalar, []curves.Scalar, error) { + if len(scalars) < 1 { + return nil, nil, errors.New("length of scalars must be at least one") + } + if len(scalars)&0x01 != 0 { + return nil, nil, errors.New("length of scalars must be even") + } + nPrime := len(scalars) >> 1 + firstHalf := scalars[:nPrime] + secondHalf := scalars[nPrime:] + return firstHalf, secondHalf, nil +} + +// multiplyScalarToPointVector takes a single scalar and a list of points, multiplies each point by scalar. +func multiplyScalarToPointVector(x curves.Scalar, g []curves.Point) []curves.Point { + products := make([]curves.Point, len(g)) + for i, gElem := range g { + product := gElem.Mul(x) + products[i] = product + } + + return products +} + +// multiplyScalarToScalarVector takes a single scalar (x) and a list of scalars (a), multiplies each scalar in the vector by the scalar. +func multiplyScalarToScalarVector(x curves.Scalar, a []curves.Scalar) []curves.Scalar { + products := make([]curves.Scalar, len(a)) + for i, aElem := range a { + product := aElem.Mul(x) + products[i] = product + } + + return products +} + +// multiplyPairwisePointVectors takes two lists of points (g, h) and performs a pairwise multiplication returning a list of points. +func multiplyPairwisePointVectors(g, h []curves.Point) ([]curves.Point, error) { + if len(g) != len(h) { + return nil, errors.New("length of point vectors must be the same") + } + product := make([]curves.Point, len(g)) + for i, gElem := range g { + product[i] = gElem.Add(h[i]) + } + + return product, nil +} + +// multiplyPairwiseScalarVectors takes two lists of points (a, b) and performs a pairwise multiplication returning a list of scalars. +func multiplyPairwiseScalarVectors(a, b []curves.Scalar) ([]curves.Scalar, error) { + if len(a) != len(b) { + return nil, errors.New("length of point vectors must be the same") + } + product := make([]curves.Scalar, len(a)) + for i, aElem := range a { + product[i] = aElem.Mul(b[i]) + } + + return product, nil +} + +// addPairwiseScalarVectors takes two lists of scalars (a, b) and performs a pairwise addition returning a list of scalars. +func addPairwiseScalarVectors(a, b []curves.Scalar) ([]curves.Scalar, error) { + if len(a) != len(b) { + return nil, errors.New("length of scalar vectors must be the same") + } + sum := make([]curves.Scalar, len(a)) + for i, aElem := range a { + sum[i] = aElem.Add(b[i]) + } + + return sum, nil +} + +// subtractPairwiseScalarVectors takes two lists of scalars (a, b) and performs a pairwise subtraction returning a list of scalars. +func subtractPairwiseScalarVectors(a, b []curves.Scalar) ([]curves.Scalar, error) { + if len(a) != len(b) { + return nil, errors.New("length of scalar vectors must be the same") + } + diff := make([]curves.Scalar, len(a)) + for i, aElem := range a { + diff[i] = aElem.Sub(b[i]) + } + return diff, nil +} + +// invertScalars takes a list of scalars then returns a list with each element inverted. +func invertScalars(xs []curves.Scalar) ([]curves.Scalar, error) { + xinvs := make([]curves.Scalar, len(xs)) + for i, x := range xs { + xinv, err := x.Invert() + if err != nil { + return nil, errors.Wrap(err, "bulletproof helpers invertx") + } + xinvs[i] = xinv + } + + return xinvs, nil +} + +// isPowerOfTwo returns whether a number i is a power of two or not. +func isPowerOfTwo(i int) bool { + return i&(i-1) == 0 +} + +// get2nVector returns a scalar vector 2^n such that [1, 2, 4, ... 2^(n-1)] +// See k^n and 2^n definitions on pg 12 of https://eprint.iacr.org/2017/1066.pdf +func get2nVector(length int, curve curves.Curve) []curves.Scalar { + vector2n := make([]curves.Scalar, length) + vector2n[0] = curve.Scalar.One() + for i := 1; i < length; i++ { + vector2n[i] = vector2n[i-1].Double() + } + return vector2n +} + +func get1nVector(length int, curve curves.Curve) []curves.Scalar { + vector1n := make([]curves.Scalar, length) + for i := 0; i < length; i++ { + vector1n[i] = curve.Scalar.One() + } + return vector1n +} + +func getknVector(k curves.Scalar, length int, curve curves.Curve) []curves.Scalar { + vectorkn := make([]curves.Scalar, length) + vectorkn[0] = curve.Scalar.One() + vectorkn[1] = k + for i := 2; i < length; i++ { + vectorkn[i] = vectorkn[i-1].Mul(k) + } + return vectorkn +} diff --git a/pkg/crypto/bulletproof/helpers_test.go b/pkg/crypto/bulletproof/helpers_test.go new file mode 100755 index 000000000..1ab891ea6 --- /dev/null +++ b/pkg/crypto/bulletproof/helpers_test.go @@ -0,0 +1,85 @@ +package bulletproof + +import ( + crand "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestInnerProductHappyPath(t *testing.T) { + curve := curves.ED25519() + a := randScalarVec(3, *curve) + b := randScalarVec(3, *curve) + _, err := innerProduct(a, b) + require.NoError(t, err) +} + +func TestInnerProductMismatchedLengths(t *testing.T) { + curve := curves.ED25519() + a := randScalarVec(3, *curve) + b := randScalarVec(4, *curve) + _, err := innerProduct(a, b) + require.Error(t, err) +} + +func TestInnerProductEmptyVector(t *testing.T) { + curve := curves.ED25519() + a := randScalarVec(0, *curve) + b := randScalarVec(0, *curve) + _, err := innerProduct(a, b) + require.Error(t, err) +} + +func TestInnerProductOut(t *testing.T) { + curve := curves.ED25519() + a := randScalarVec(2, *curve) + b := randScalarVec(2, *curve) + c, err := innerProduct(a, b) + require.NoError(t, err) + + // Calculate manually a0*b0 + a1*b1 + cPrime := a[0].Mul(b[0]).Add(a[1].Mul(b[1])) + require.Equal(t, c, cPrime) +} + +func TestSplitListofPointsHappyPath(t *testing.T) { + curve := curves.ED25519() + points := randPointVec(10, *curve) + firstHalf, secondHalf, err := splitPointVector(points) + require.NoError(t, err) + require.Len(t, firstHalf, 5) + require.Len(t, secondHalf, 5) +} + +func TestSplitListofPointsOddLength(t *testing.T) { + curve := curves.ED25519() + points := randPointVec(11, *curve) + _, _, err := splitPointVector(points) + require.Error(t, err) +} + +func TestSplitListofPointsZeroLength(t *testing.T) { + curve := curves.ED25519() + points := randPointVec(0, *curve) + _, _, err := splitPointVector(points) + require.Error(t, err) +} + +func randScalarVec(length int, curve curves.Curve) []curves.Scalar { + out := make([]curves.Scalar, length) + for i := 0; i < length; i++ { + out[i] = curve.Scalar.Random(crand.Reader) + } + return out +} + +func randPointVec(length int, curve curves.Curve) []curves.Point { + out := make([]curves.Point, length) + for i := 0; i < length; i++ { + out[i] = curve.Point.Random(crand.Reader) + } + return out +} diff --git a/pkg/crypto/bulletproof/ipp_prover.go b/pkg/crypto/bulletproof/ipp_prover.go new file mode 100755 index 000000000..f059a9cca --- /dev/null +++ b/pkg/crypto/bulletproof/ipp_prover.go @@ -0,0 +1,396 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package bulletproof implements the zero knowledge protocol bulletproofs as defined in https://eprint.iacr.org/2017/1066.pdf +package bulletproof + +import ( + "github.com/gtank/merlin" + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// InnerProductProver is the struct used to create InnerProductProofs +// It specifies which curve to use and holds precomputed generators +// See NewInnerProductProver() for prover initialization. +type InnerProductProver struct { + curve curves.Curve + generators ippGenerators +} + +// InnerProductProof contains necessary output for the inner product proof +// a and b are the final input vectors of scalars, they should be of length 1 +// Ls and Rs are calculated per recursion of the IPP and are necessary for verification +// See section 3.1 on pg 15 of https://eprint.iacr.org/2017/1066.pdf +type InnerProductProof struct { + a, b curves.Scalar + capLs, capRs []curves.Point + curve *curves.Curve +} + +// ippRecursion is the same as IPP but tracks recursive a', b', g', h' and Ls and Rs +// It should only be used internally by InnerProductProver.Prove() +// See L35 on pg 16 of https://eprint.iacr.org/2017/1066.pdf +type ippRecursion struct { + a, b []curves.Scalar + c curves.Scalar + capLs, capRs []curves.Point + g, h []curves.Point + u, capP curves.Point + transcript *merlin.Transcript +} + +// NewInnerProductProver initializes a new prover +// It uses the specified domain to generate generators for vectors of at most maxVectorLength +// A prover can be used to construct inner product proofs for vectors of length less than or equal to maxVectorLength +// A prover is defined by an explicit curve. +func NewInnerProductProver(maxVectorLength int, domain []byte, curve curves.Curve) (*InnerProductProver, error) { + generators, err := getGeneratorPoints(maxVectorLength, domain, curve) + if err != nil { + return nil, errors.Wrap(err, "ipp getGenerators") + } + return &InnerProductProver{curve: curve, generators: *generators}, nil +} + +// NewInnerProductProof initializes a new InnerProductProof for a specified curve +// This should be used in tandem with UnmarshalBinary() to convert a marshaled proof into the struct. +func NewInnerProductProof(curve *curves.Curve) *InnerProductProof { + var capLs, capRs []curves.Point + newProof := InnerProductProof{ + a: curve.NewScalar(), + b: curve.NewScalar(), + capLs: capLs, + capRs: capRs, + curve: curve, + } + return &newProof +} + +// rangeToIPP takes the output of a range proof and converts it into an inner product proof +// See section 4.2 on pg 20 +// The conversion specifies generators to use (g and hPrime), as well as the two vectors l, r of which the inner product is tHat +// Additionally, note that the P used for the IPP is in fact P*h^-mu from the range proof. +func (prover *InnerProductProver) rangeToIPP(proofG, proofH []curves.Point, l, r []curves.Scalar, tHat curves.Scalar, capPhmuinv, u curves.Point, transcript *merlin.Transcript) (*InnerProductProof, error) { + // Note that P as a witness is only g^l * h^r + // P needs to be in the form of g^l * h^r * u^ + // Calculate the final P including the u^ term + utHat := u.Mul(tHat) + capP := capPhmuinv.Add(utHat) + + // Use params to prove inner product + recursionParams := &ippRecursion{ + a: l, + b: r, + capLs: []curves.Point{}, + capRs: []curves.Point{}, + c: tHat, + g: proofG, + h: proofH, + capP: capP, + u: u, + transcript: transcript, + } + + return prover.proveRecursive(recursionParams) +} + +// getP returns the initial P value given two scalars a,b and point u +// This method should only be used for testing +// See (3) on page 13 of https://eprint.iacr.org/2017/1066.pdf +func (prover *InnerProductProver) getP(a, b []curves.Scalar, u curves.Point) (curves.Point, error) { + // Vectors must have length power of two + if !isPowerOfTwo(len(a)) { + return nil, errors.New("ipp vector length must be power of two") + } + // Generator vectors must be same length + if len(prover.generators.G) != len(prover.generators.H) { + return nil, errors.New("ipp generator lengths of g and h must be equal") + } + // Inner product requires len(a) == len(b) else error is returned + c, err := innerProduct(a, b) + if err != nil { + return nil, errors.Wrap(err, "ipp getInnerProduct") + } + + // In case where len(a) is less than number of generators precomputed by prover, trim to length + proofG := prover.generators.G[0:len(a)] + proofH := prover.generators.H[0:len(b)] + + // initial P = g^a * h^b * u^(a dot b) (See (3) on page 13 of https://eprint.iacr.org/2017/1066.pdf) + ga := prover.curve.NewGeneratorPoint().SumOfProducts(proofG, a) + hb := prover.curve.NewGeneratorPoint().SumOfProducts(proofH, b) + uadotb := u.Mul(c) + capP := ga.Add(hb).Add(uadotb) + + return capP, nil +} + +// Prove executes the prover protocol on pg 16 of https://eprint.iacr.org/2017/1066.pdf +// It generates an inner product proof for vectors a and b, using u to blind the inner product in P +// A transcript is used for the Fiat Shamir heuristic. +func (prover *InnerProductProver) Prove(a, b []curves.Scalar, u curves.Point, transcript *merlin.Transcript) (*InnerProductProof, error) { + // Vectors must have length power of two + if !isPowerOfTwo(len(a)) { + return nil, errors.New("ipp vector length must be power of two") + } + // Generator vectors must be same length + if len(prover.generators.G) != len(prover.generators.H) { + return nil, errors.New("ipp generator lengths of g and h must be equal") + } + // Inner product requires len(a) == len(b) else error is returned + c, err := innerProduct(a, b) + if err != nil { + return nil, errors.Wrap(err, "ipp getInnerProduct") + } + + // Length of vectors must be less than the number of generators generated + if len(a) > len(prover.generators.G) { + return nil, errors.New("ipp vector length must be less than maxVectorLength") + } + // In case where len(a) is less than number of generators precomputed by prover, trim to length + proofG := prover.generators.G[0:len(a)] + proofH := prover.generators.H[0:len(b)] + + // initial P = g^a * h^b * u^(a dot b) (See (3) on page 13 of https://eprint.iacr.org/2017/1066.pdf) + ga := prover.curve.NewGeneratorPoint().SumOfProducts(proofG, a) + hb := prover.curve.NewGeneratorPoint().SumOfProducts(proofH, b) + uadotb := u.Mul(c) + capP := ga.Add(hb).Add(uadotb) + + recursionParams := &ippRecursion{ + a: a, + b: b, + capLs: []curves.Point{}, + capRs: []curves.Point{}, + c: c, + g: proofG, + h: proofH, + capP: capP, + u: u, + transcript: transcript, + } + return prover.proveRecursive(recursionParams) +} + +// proveRecursive executes the recursion on pg 16 of https://eprint.iacr.org/2017/1066.pdf +func (prover *InnerProductProver) proveRecursive(recursionParams *ippRecursion) (*InnerProductProof, error) { + // length checks + if len(recursionParams.a) != len(recursionParams.b) { + return nil, errors.New("ipp proveRecursive a and b different lengths") + } + if len(recursionParams.g) != len(recursionParams.h) { + return nil, errors.New("ipp proveRecursive g and h different lengths") + } + if len(recursionParams.a) != len(recursionParams.g) { + return nil, errors.New("ipp proveRecursive scalar and point vectors different lengths") + } + // Base case (L14, pg16 of https://eprint.iacr.org/2017/1066.pdf) + if len(recursionParams.a) == 1 { + proof := &InnerProductProof{ + a: recursionParams.a[0], + b: recursionParams.b[0], + capLs: recursionParams.capLs, + capRs: recursionParams.capRs, + curve: &prover.curve, + } + return proof, nil + } + + // Split current state into low (first half) vs high (second half) vectors + aLo, aHi, err := splitScalarVector(recursionParams.a) + if err != nil { + return nil, errors.Wrap(err, "recursionParams splitScalarVector") + } + bLo, bHi, err := splitScalarVector(recursionParams.b) + if err != nil { + return nil, errors.Wrap(err, "recursionParams splitScalarVector") + } + gLo, gHi, err := splitPointVector(recursionParams.g) + if err != nil { + return nil, errors.Wrap(err, "recursionParams splitPointVector") + } + hLo, hHi, err := splitPointVector(recursionParams.h) + if err != nil { + return nil, errors.Wrap(err, "recursionParams splitPointVector") + } + + // c_l, c_r (L21,22, pg16 of https://eprint.iacr.org/2017/1066.pdf) + cL, err := innerProduct(aLo, bHi) + if err != nil { + return nil, errors.Wrap(err, "recursionParams innerProduct") + } + + cR, err := innerProduct(aHi, bLo) + if err != nil { + return nil, errors.Wrap(err, "recursionParams innerProduct") + } + + // L, R (L23,24, pg16 of https://eprint.iacr.org/2017/1066.pdf) + lga := prover.curve.Point.SumOfProducts(gHi, aLo) + lhb := prover.curve.Point.SumOfProducts(hLo, bHi) + ucL := recursionParams.u.Mul(cL) + capL := lga.Add(lhb).Add(ucL) + + rga := prover.curve.Point.SumOfProducts(gLo, aHi) + rhb := prover.curve.Point.SumOfProducts(hHi, bLo) + ucR := recursionParams.u.Mul(cR) + capR := rga.Add(rhb).Add(ucR) + + // Add L,R for verifier to use to calculate final g, h + newL := recursionParams.capLs + newL = append(newL, capL) + newR := recursionParams.capRs + newR = append(newR, capR) + + // Get x from L, R for non-interactive (See section 4.4 pg22 of https://eprint.iacr.org/2017/1066.pdf) + // Note this replaces the interactive model, i.e. L36-28 of pg16 of https://eprint.iacr.org/2017/1066.pdf + x, err := prover.calcx(capL, capR, recursionParams.transcript) + if err != nil { + return nil, errors.Wrap(err, "recursionParams calcx") + } + + // Calculate recursive inputs + xInv, err := x.Invert() + if err != nil { + return nil, errors.Wrap(err, "recursionParams x.Invert") + } + + // g', h' (L29,30, pg16 of https://eprint.iacr.org/2017/1066.pdf) + gLoxInverse := multiplyScalarToPointVector(xInv, gLo) + gHix := multiplyScalarToPointVector(x, gHi) + gPrime, err := multiplyPairwisePointVectors(gLoxInverse, gHix) + if err != nil { + return nil, errors.Wrap(err, "recursionParams multiplyPairwisePointVectors") + } + + hLox := multiplyScalarToPointVector(x, hLo) + hHixInv := multiplyScalarToPointVector(xInv, hHi) + hPrime, err := multiplyPairwisePointVectors(hLox, hHixInv) + if err != nil { + return nil, errors.Wrap(err, "recursionParams multiplyPairwisePointVectors") + } + + // P' (L31, pg16 of https://eprint.iacr.org/2017/1066.pdf) + xSquare := x.Square() + xInvSquare := xInv.Square() + LxSquare := capL.Mul(xSquare) + RxInvSquare := capR.Mul(xInvSquare) + PPrime := LxSquare.Add(recursionParams.capP).Add(RxInvSquare) + + // a', b' (L33, 34, pg16 of https://eprint.iacr.org/2017/1066.pdf) + aLox := multiplyScalarToScalarVector(x, aLo) + aHixIn := multiplyScalarToScalarVector(xInv, aHi) + aPrime, err := addPairwiseScalarVectors(aLox, aHixIn) + if err != nil { + return nil, errors.Wrap(err, "recursionParams addPairwiseScalarVectors") + } + + bLoxInv := multiplyScalarToScalarVector(xInv, bLo) + bHix := multiplyScalarToScalarVector(x, bHi) + bPrime, err := addPairwiseScalarVectors(bLoxInv, bHix) + if err != nil { + return nil, errors.Wrap(err, "recursionParams addPairwiseScalarVectors") + } + + // c' + cPrime, err := innerProduct(aPrime, bPrime) + if err != nil { + return nil, errors.Wrap(err, "recursionParams innerProduct") + } + + // Make recursive call (L35, pg16 of https://eprint.iacr.org/2017/1066.pdf) + recursiveIPP := &ippRecursion{ + a: aPrime, + b: bPrime, + capLs: newL, + capRs: newR, + c: cPrime, + g: gPrime, + h: hPrime, + capP: PPrime, + u: recursionParams.u, + transcript: recursionParams.transcript, + } + + out, err := prover.proveRecursive(recursiveIPP) + if err != nil { + return nil, errors.Wrap(err, "recursionParams proveRecursive") + } + return out, nil +} + +// calcx uses a merlin transcript for Fiat Shamir +// For each recursion, it takes the current state of the transcript and appends the newly calculated L and R values +// A new scalar is then read from the transcript +// See section 4.4 pg22 of https://eprint.iacr.org/2017/1066.pdf +func (prover *InnerProductProver) calcx(capL, capR curves.Point, transcript *merlin.Transcript) (curves.Scalar, error) { + // Add the newest capL and capR values to transcript + transcript.AppendMessage([]byte("addRecursiveL"), capL.ToAffineUncompressed()) + transcript.AppendMessage([]byte("addRecursiveR"), capR.ToAffineUncompressed()) + // Read 64 bytes from, set to scalar + outBytes := transcript.ExtractBytes([]byte("getx"), 64) + x, err := prover.curve.NewScalar().SetBytesWide(outBytes) + if err != nil { + return nil, errors.Wrap(err, "calcx NewScalar SetBytesWide") + } + + return x, nil +} + +// MarshalBinary takes an inner product proof and marshals into bytes. +func (proof *InnerProductProof) MarshalBinary() []byte { + var out []byte + out = append(out, proof.a.Bytes()...) + out = append(out, proof.b.Bytes()...) + for i, capLElem := range proof.capLs { + capRElem := proof.capRs[i] + out = append(out, capLElem.ToAffineCompressed()...) + out = append(out, capRElem.ToAffineCompressed()...) + } + return out +} + +// UnmarshalBinary takes bytes of a marshaled proof and writes them into an inner product proof +// The inner product proof used should be from the output of NewInnerProductProof(). +func (proof *InnerProductProof) UnmarshalBinary(data []byte) error { + scalarLen := len(proof.curve.NewScalar().Bytes()) + pointLen := len(proof.curve.NewGeneratorPoint().ToAffineCompressed()) + ptr := 0 + // Get scalars + a, err := proof.curve.NewScalar().SetBytes(data[ptr : ptr+scalarLen]) + if err != nil { + return errors.New("innerProductProof UnmarshalBinary SetBytes") + } + proof.a = a + ptr += scalarLen + b, err := proof.curve.NewScalar().SetBytes(data[ptr : ptr+scalarLen]) + if err != nil { + return errors.New("innerProductProof UnmarshalBinary SetBytes") + } + proof.b = b + ptr += scalarLen + // Get points + var capLs, capRs []curves.Point //nolint:prealloc // pointer arithmetic makes it too unreadable. + for ptr < len(data) { + capLElem, err := proof.curve.Point.FromAffineCompressed(data[ptr : ptr+pointLen]) + if err != nil { + return errors.New("innerProductProof UnmarshalBinary FromAffineCompressed") + } + capLs = append(capLs, capLElem) + ptr += pointLen + capRElem, err := proof.curve.Point.FromAffineCompressed(data[ptr : ptr+pointLen]) + if err != nil { + return errors.New("innerProductProof UnmarshalBinary FromAffineCompressed") + } + capRs = append(capRs, capRElem) + ptr += pointLen + } + proof.capLs = capLs + proof.capRs = capRs + + return nil +} diff --git a/pkg/crypto/bulletproof/ipp_prover_test.go b/pkg/crypto/bulletproof/ipp_prover_test.go new file mode 100755 index 000000000..6482adbdd --- /dev/null +++ b/pkg/crypto/bulletproof/ipp_prover_test.go @@ -0,0 +1,99 @@ +package bulletproof + +import ( + crand "crypto/rand" + "testing" + + "github.com/gtank/merlin" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestIPPHappyPath(t *testing.T) { + curve := curves.ED25519() + prover, err := NewInnerProductProver(8, []byte("test"), *curve) + require.NoError(t, err) + a := randScalarVec(8, *curve) + b := randScalarVec(8, *curve) + u := curve.Point.Random(crand.Reader) + transcript := merlin.NewTranscript("test") + proof, err := prover.Prove(a, b, u, transcript) + require.NoError(t, err) + require.Equal(t, 3, len(proof.capLs)) + require.Equal(t, 3, len(proof.capRs)) +} + +func TestIPPMismatchedVectors(t *testing.T) { + curve := curves.ED25519() + prover, err := NewInnerProductProver(8, []byte("test"), *curve) + require.NoError(t, err) + a := randScalarVec(4, *curve) + b := randScalarVec(8, *curve) + u := curve.Point.Random(crand.Reader) + transcript := merlin.NewTranscript("test") + _, err = prover.Prove(a, b, u, transcript) + require.Error(t, err) +} + +func TestIPPNonPowerOfTwoLengthVectors(t *testing.T) { + curve := curves.ED25519() + prover, err := NewInnerProductProver(8, []byte("test"), *curve) + require.NoError(t, err) + a := randScalarVec(3, *curve) + b := randScalarVec(3, *curve) + u := curve.Point.Random(crand.Reader) + transcript := merlin.NewTranscript("test") + _, err = prover.Prove(a, b, u, transcript) + require.Error(t, err) +} + +func TestIPPZeroLengthVectors(t *testing.T) { + curve := curves.ED25519() + prover, err := NewInnerProductProver(8, []byte("test"), *curve) + require.NoError(t, err) + a := randScalarVec(0, *curve) + b := randScalarVec(0, *curve) + u := curve.Point.Random(crand.Reader) + transcript := merlin.NewTranscript("test") + _, err = prover.Prove(a, b, u, transcript) + require.Error(t, err) +} + +func TestIPPGreaterThanMaxLengthVectors(t *testing.T) { + curve := curves.ED25519() + prover, err := NewInnerProductProver(8, []byte("test"), *curve) + require.NoError(t, err) + a := randScalarVec(16, *curve) + b := randScalarVec(16, *curve) + u := curve.Point.Random(crand.Reader) + transcript := merlin.NewTranscript("test") + _, err = prover.Prove(a, b, u, transcript) + require.Error(t, err) +} + +func TestIPPMarshal(t *testing.T) { + curve := curves.ED25519() + prover, err := NewInnerProductProver(8, []byte("test"), *curve) + require.NoError(t, err) + a := randScalarVec(8, *curve) + b := randScalarVec(8, *curve) + u := curve.Point.Random(crand.Reader) + transcript := merlin.NewTranscript("test") + proof, err := prover.Prove(a, b, u, transcript) + require.NoError(t, err) + + proofMarshaled := proof.MarshalBinary() + proofPrime := NewInnerProductProof(curve) + err = proofPrime.UnmarshalBinary(proofMarshaled) + require.NoError(t, err) + require.Zero(t, proof.a.Cmp(proofPrime.a)) + require.Zero(t, proof.b.Cmp(proofPrime.b)) + for i, proofCapLElem := range proof.capLs { + proofPrimeCapLElem := proofPrime.capLs[i] + require.True(t, proofCapLElem.Equal(proofPrimeCapLElem)) + proofCapRElem := proof.capRs[i] + proofPrimeCapRElem := proofPrime.capRs[i] + require.True(t, proofCapRElem.Equal(proofPrimeCapRElem)) + } +} diff --git a/pkg/crypto/bulletproof/ipp_verifier.go b/pkg/crypto/bulletproof/ipp_verifier.go new file mode 100755 index 000000000..cdfbdf069 --- /dev/null +++ b/pkg/crypto/bulletproof/ipp_verifier.go @@ -0,0 +1,209 @@ +package bulletproof + +import ( + "github.com/gtank/merlin" + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// InnerProductVerifier is the struct used to verify inner product proofs +// It specifies which curve to use and holds precomputed generators +// See NewInnerProductProver() for prover initialization. +type InnerProductVerifier struct { + curve curves.Curve + generators ippGenerators +} + +// NewInnerProductVerifier initializes a new verifier +// It uses the specified domain to generate generators for vectors of at most maxVectorLength +// A verifier can be used to verify inner product proofs for vectors of length less than or equal to maxVectorLength +// A verifier is defined by an explicit curve. +func NewInnerProductVerifier(maxVectorLength int, domain []byte, curve curves.Curve) (*InnerProductVerifier, error) { + generators, err := getGeneratorPoints(maxVectorLength, domain, curve) + if err != nil { + return nil, errors.Wrap(err, "ipp getGenerators") + } + return &InnerProductVerifier{curve: curve, generators: *generators}, nil +} + +// Verify verifies the given proof inputs +// It implements the final comparison of section 3.1 on pg17 of https://eprint.iacr.org/2017/1066.pdf +func (verifier *InnerProductVerifier) Verify(capP, u curves.Point, proof *InnerProductProof, transcript *merlin.Transcript) (bool, error) { + if len(proof.capLs) != len(proof.capRs) { + return false, errors.New("ipp capLs and capRs must be same length") + } + // Generator vectors must be same length + if len(verifier.generators.G) != len(verifier.generators.H) { + return false, errors.New("ipp generator lengths of g and h must be equal") + } + + // Get generators for each elem in a, b and one more for u + // len(Ls) = log n, therefore can just exponentiate + n := 1 << len(proof.capLs) + + // Length of vectors must be less than the number of generators generated + if n > len(verifier.generators.G) { + return false, errors.New("ipp vector length must be less than maxVectorLength") + } + // In case where len(a) is less than number of generators precomputed by prover, trim to length + proofG := verifier.generators.G[0:n] + proofH := verifier.generators.H[0:n] + + xs, err := getxs(transcript, proof.capLs, proof.capRs, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "verifier getxs") + } + s, err := verifier.getsNew(xs, n) + if err != nil { + return false, errors.Wrap(err, "verifier getss") + } + lhs, err := verifier.getLHS(u, proof, proofG, proofH, s) + if err != nil { + return false, errors.Wrap(err, "verify getLHS") + } + rhs, err := verifier.getRHS(capP, proof, xs) + if err != nil { + return false, errors.Wrap(err, "verify getRHS") + } + return lhs.Equal(rhs), nil +} + +// Verify verifies the given proof inputs +// It implements the final comparison of section 3.1 on pg17 of https://eprint.iacr.org/2017/1066.pdf +func (verifier *InnerProductVerifier) VerifyFromRangeProof(proofG, proofH []curves.Point, capPhmuinv, u curves.Point, tHat curves.Scalar, proof *InnerProductProof, transcript *merlin.Transcript) (bool, error) { + // Get generators for each elem in a, b and one more for u + // len(Ls) = log n, therefore can just exponentiate + n := 1 << len(proof.capLs) + + xs, err := getxs(transcript, proof.capLs, proof.capRs, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "verifier getxs") + } + s, err := verifier.gets(xs, n) + if err != nil { + return false, errors.Wrap(err, "verifier getss") + } + lhs, err := verifier.getLHS(u, proof, proofG, proofH, s) + if err != nil { + return false, errors.Wrap(err, "verify getLHS") + } + utHat := u.Mul(tHat) + capP := capPhmuinv.Add(utHat) + rhs, err := verifier.getRHS(capP, proof, xs) + if err != nil { + return false, errors.Wrap(err, "verify getRHS") + } + return lhs.Equal(rhs), nil +} + +// getRHS gets the right hand side of the final comparison of section 3.1 on pg17. +func (*InnerProductVerifier) getRHS(capP curves.Point, proof *InnerProductProof, xs []curves.Scalar) (curves.Point, error) { + product := capP + for j, Lj := range proof.capLs { + Rj := proof.capRs[j] + xj := xs[j] + xjSquare := xj.Square() + xjSquareInv, err := xjSquare.Invert() + if err != nil { + return nil, errors.Wrap(err, "verify invert") + } + LjxjSquare := Lj.Mul(xjSquare) + RjxjSquareInv := Rj.Mul(xjSquareInv) + product = product.Add(LjxjSquare).Add(RjxjSquareInv) + } + return product, nil +} + +// getLHS gets the left hand side of the final comparison of section 3.1 on pg17. +func (verifier *InnerProductVerifier) getLHS(u curves.Point, proof *InnerProductProof, g, h []curves.Point, s []curves.Scalar) (curves.Point, error) { + sInv, err := invertScalars(s) + if err != nil { + return nil, errors.Wrap(err, "verify invertScalars") + } + // g^(a*s) + as := multiplyScalarToScalarVector(proof.a, s) + gas := verifier.curve.Point.SumOfProducts(g, as) + // h^(b*s^-1) + bsInv := multiplyScalarToScalarVector(proof.b, sInv) + hbsInv := verifier.curve.Point.SumOfProducts(h, bsInv) + // u^a*b + ab := proof.a.Mul(proof.b) + uab := u.Mul(ab) + // g^(a*s) * h^(b*s^-1) * u^a*b + out := gas.Add(hbsInv).Add(uab) + + return out, nil +} + +// getxs calculates the x values from Ls and Rs +// Note that each x is read from the transcript, then the L and R at a certain index are written to the transcript +// This mirrors the reading of xs and writing of Ls and Rs in the prover. +func getxs(transcript *merlin.Transcript, capLs, capRs []curves.Point, curve curves.Curve) ([]curves.Scalar, error) { + xs := make([]curves.Scalar, len(capLs)) + for i, capLi := range capLs { + capRi := capRs[i] + // Add the newest L and R values to transcript + transcript.AppendMessage([]byte("addRecursiveL"), capLi.ToAffineUncompressed()) + transcript.AppendMessage([]byte("addRecursiveR"), capRi.ToAffineUncompressed()) + // Read 64 bytes from, set to scalar + outBytes := transcript.ExtractBytes([]byte("getx"), 64) + x, err := curve.NewScalar().SetBytesWide(outBytes) + if err != nil { + return nil, errors.Wrap(err, "calcx NewScalar SetBytesWide") + } + xs[i] = x + } + + return xs, nil +} + +// gets calculates the vector s of values used for verification +// See the second expression of section 3.1 on pg15 +// nolint +func (verifier *InnerProductVerifier) gets(xs []curves.Scalar, n int) ([]curves.Scalar, error) { + ss := make([]curves.Scalar, n) + for i := 0; i < n; i++ { + si := verifier.curve.Scalar.One() + for j, xj := range xs { + if i>>(len(xs)-j-1)&0x01 == 1 { + si = si.Mul(xj) + } else { + xjInverse, err := xj.Invert() + if err != nil { + return nil, errors.Wrap(err, "getss invert") + } + si = si.Mul(xjInverse) + } + } + ss[i] = si + } + + return ss, nil +} + +// getsNew calculates the vector s of values used for verification +// It provides analogous functionality as gets(), but uses a O(n) algorithm vs O(nlogn) +// The algorithm inverts all xs, then begins multiplying the inversion by the square of x elements to +// calculate all s values thus minimizing necessary inversions/ computation. +func (verifier *InnerProductVerifier) getsNew(xs []curves.Scalar, n int) ([]curves.Scalar, error) { + var err error + ss := make([]curves.Scalar, n) + // First element is all xs inverted mul'd + ss[0] = verifier.curve.Scalar.One() + for _, xj := range xs { + ss[0] = ss[0].Mul(xj) + } + ss[0], err = ss[0].Invert() + if err != nil { + return nil, errors.Wrap(err, "ipp gets inv ss0") + } + for j, xj := range xs { + xjSquared := xj.Square() + for i := 0; i < n; i += 1 << (len(xs) - j) { + ss[i+1<<(len(xs)-j-1)] = ss[i].Mul(xjSquared) + } + } + + return ss, nil +} diff --git a/pkg/crypto/bulletproof/ipp_verifier_test.go b/pkg/crypto/bulletproof/ipp_verifier_test.go new file mode 100755 index 000000000..2ef604529 --- /dev/null +++ b/pkg/crypto/bulletproof/ipp_verifier_test.go @@ -0,0 +1,79 @@ +package bulletproof + +import ( + crand "crypto/rand" + "testing" + + "github.com/gtank/merlin" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestIPPVerifyHappyPath(t *testing.T) { + curve := curves.ED25519() + vecLength := 256 + prover, err := NewInnerProductProver(vecLength, []byte("test"), *curve) + require.NoError(t, err) + a := randScalarVec(vecLength, *curve) + b := randScalarVec(vecLength, *curve) + u := curve.Point.Random(crand.Reader) + transcriptProver := merlin.NewTranscript("test") + proof, err := prover.Prove(a, b, u, transcriptProver) + require.NoError(t, err) + + verifier, err := NewInnerProductVerifier(vecLength, []byte("test"), *curve) + require.NoError(t, err) + capP, err := prover.getP(a, b, u) + require.NoError(t, err) + transcriptVerifier := merlin.NewTranscript("test") + verified, err := verifier.Verify(capP, u, proof, transcriptVerifier) + require.NoError(t, err) + require.True(t, verified) +} + +func BenchmarkIPPVerification(bench *testing.B) { + curve := curves.ED25519() + vecLength := 1024 + prover, _ := NewInnerProductProver(vecLength, []byte("test"), *curve) + a := randScalarVec(vecLength, *curve) + b := randScalarVec(vecLength, *curve) + u := curve.Point.Random(crand.Reader) + transcriptProver := merlin.NewTranscript("test") + proof, _ := prover.Prove(a, b, u, transcriptProver) + + verifier, _ := NewInnerProductVerifier(vecLength, []byte("test"), *curve) + capP, _ := prover.getP(a, b, u) + transcriptVerifier := merlin.NewTranscript("test") + verified, _ := verifier.Verify(capP, u, proof, transcriptVerifier) + require.True(bench, verified) +} + +func TestIPPVerifyInvalidProof(t *testing.T) { + curve := curves.ED25519() + vecLength := 64 + prover, err := NewInnerProductProver(vecLength, []byte("test"), *curve) + require.NoError(t, err) + + a := randScalarVec(vecLength, *curve) + b := randScalarVec(vecLength, *curve) + u := curve.Point.Random(crand.Reader) + + aPrime := randScalarVec(64, *curve) + bPrime := randScalarVec(64, *curve) + uPrime := curve.Point.Random(crand.Reader) + transcriptProver := merlin.NewTranscript("test") + + proofPrime, err := prover.Prove(aPrime, bPrime, uPrime, transcriptProver) + require.NoError(t, err) + + verifier, err := NewInnerProductVerifier(vecLength, []byte("test"), *curve) + require.NoError(t, err) + capP, err := prover.getP(a, b, u) + require.NoError(t, err) + transcriptVerifier := merlin.NewTranscript("test") + // Check for different capP, u from proof + verified, err := verifier.Verify(capP, u, proofPrime, transcriptVerifier) + require.NoError(t, err) + require.False(t, verified) +} diff --git a/pkg/crypto/bulletproof/range_batch_prover.go b/pkg/crypto/bulletproof/range_batch_prover.go new file mode 100755 index 000000000..46413979a --- /dev/null +++ b/pkg/crypto/bulletproof/range_batch_prover.go @@ -0,0 +1,348 @@ +package bulletproof + +import ( + crand "crypto/rand" + + "github.com/gtank/merlin" + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// BatchProve proves that a list of scalars v are in the range n. +// It implements the aggregating logarithmic proofs defined on pg21. +// Instead of taking a single value and a single blinding factor, BatchProve takes in a list of values and list of +// blinding factors. +func (prover *RangeProver) BatchProve(v, gamma []curves.Scalar, n int, proofGenerators RangeProofGenerators, transcript *merlin.Transcript) (*RangeProof, error) { + // Define nm as the total bits required for secrets, calculated as number of secrets * n + m := len(v) + nm := n * m + // nm must be less than or equal to the number of generators generated + if nm > len(prover.generators.G) { + return nil, errors.New("ipp vector length must be less than or equal to maxVectorLength") + } + + // In case where nm is less than number of generators precomputed by prover, trim to length + proofG := prover.generators.G[0:nm] + proofH := prover.generators.H[0:nm] + + // Check that each elem in v is in range [0, 2^n] + for _, vi := range v { + checkedRange := checkRange(vi, n) + if checkedRange != nil { + return nil, checkedRange + } + } + + // L40 on pg19 + aL, err := getaLBatched(v, n, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + onenm := get1nVector(nm, prover.curve) + // L41 on pg19 + aR, err := subtractPairwiseScalarVectors(aL, onenm) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + alpha := prover.curve.Scalar.Random(crand.Reader) + // Calc A (L44, pg19) + halpha := proofGenerators.h.Mul(alpha) + gaL := prover.curve.Point.SumOfProducts(proofG, aL) + haR := prover.curve.Point.SumOfProducts(proofH, aR) + capA := halpha.Add(gaL).Add(haR) + + // L45, 46, pg19 + sL := getBlindingVector(nm, prover.curve) + sR := getBlindingVector(nm, prover.curve) + rho := prover.curve.Scalar.Random(crand.Reader) + + // Calc S (L47, pg19) + hrho := proofGenerators.h.Mul(rho) + gsL := prover.curve.Point.SumOfProducts(proofG, sL) + hsR := prover.curve.Point.SumOfProducts(proofH, sR) + capS := hrho.Add(gsL).Add(hsR) + + // Fiat Shamir for y,z (L49, pg19) + capV := getcapVBatched(v, gamma, proofGenerators.g, proofGenerators.h) + y, z, err := calcyzBatched(capV, capA, capS, transcript, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // Calc t_1, t_2 + // See the l(X), r(X), equations on pg 21 + // Use l(X)'s and r(X)'s constant and linear terms to derive t_1 and t_2 + // (a_l - z*1^n) + zonenm := multiplyScalarToScalarVector(z, onenm) + constantTerml, err := subtractPairwiseScalarVectors(aL, zonenm) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + linearTerml := sL + + // zSum term, see equation 71 on pg21 + zSum := getSumTermrXBatched(z, n, len(v), prover.curve) + // a_r + z*1^nm + aRPluszonenm, err := addPairwiseScalarVectors(aR, zonenm) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + ynm := getknVector(y, nm, prover.curve) + hadamard, err := multiplyPairwiseScalarVectors(ynm, aRPluszonenm) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + constantTermr, err := addPairwiseScalarVectors(hadamard, zSum) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + linearTermr, err := multiplyPairwiseScalarVectors(ynm, sR) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // t_1 (as the linear coefficient) is the sum of the dot products of l(X)'s linear term dot r(X)'s constant term + // and r(X)'s linear term dot l(X)'s constant term + t1FirstTerm, err := innerProduct(linearTerml, constantTermr) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + t1SecondTerm, err := innerProduct(linearTermr, constantTerml) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + t1 := t1FirstTerm.Add(t1SecondTerm) + + // t_2 (as the quadratic coefficient) is the dot product of l(X)'s and r(X)'s linear terms + t2, err := innerProduct(linearTerml, linearTermr) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // L52, pg20 + tau1 := prover.curve.Scalar.Random(crand.Reader) + tau2 := prover.curve.Scalar.Random(crand.Reader) + + // T_1, T_2 (L53, pg20) + capT1 := proofGenerators.g.Mul(t1).Add(proofGenerators.h.Mul(tau1)) + capT2 := proofGenerators.g.Mul(t2).Add(proofGenerators.h.Mul(tau2)) + + // Fiat shamir for x (L55, pg20) + x, err := calcx(capT1, capT2, transcript, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // Calc l + // Instead of using the expression in the line, evaluate l() at x + sLx := multiplyScalarToScalarVector(x, linearTerml) + l, err := addPairwiseScalarVectors(constantTerml, sLx) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // Calc r + // Instead of using the expression in the line, evaluate r() at x + ynsRx := multiplyScalarToScalarVector(x, linearTermr) + r, err := addPairwiseScalarVectors(constantTermr, ynsRx) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // Calc t hat + // For efficiency, instead of calculating the dot product, evaluate t() at x + zm := getknVector(z, m, prover.curve) + zsquarezm := multiplyScalarToScalarVector(z.Square(), zm) + sumv := prover.curve.Scalar.Zero() + for i := 0; i < m; i++ { + elem := zsquarezm[i].Mul(v[i]) + sumv = sumv.Add(elem) + } + + deltayzBatched, err := deltayzBatched(y, z, n, m, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + t0 := sumv.Add(deltayzBatched) + tLinear := t1.Mul(x) + tQuadratic := t2.Mul(x.Square()) + tHat := t0.Add(tLinear).Add(tQuadratic) + + // Calc tau_x (L61, pg20) + tau2xsquare := tau2.Mul(x.Square()) + tau1x := tau1.Mul(x) + zsum := prover.curve.Scalar.Zero() + zExp := z.Clone() + for j := 1; j < m+1; j++ { + zExp = zExp.Mul(z) + zsum = zsum.Add(zExp.Mul(gamma[j-1])) + } + taux := tau2xsquare.Add(tau1x).Add(zsum) + + // Calc mu (L62, pg20) + mu := alpha.Add(rho.Mul(x)) + + // Calc IPP (See section 4.2) + hPrime, err := gethPrime(proofH, y, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // P is redefined in batched case, see bottom equation on pg21. + capPhmu := getPhmuBatched(proofG, hPrime, proofGenerators.h, capA, capS, x, y, z, mu, n, m, prover.curve) + + wBytes := transcript.ExtractBytes([]byte("getw"), 64) + w, err := prover.curve.NewScalar().SetBytesWide(wBytes) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + ipp, err := prover.ippProver.rangeToIPP(proofG, hPrime, l, r, tHat, capPhmu, proofGenerators.u.Mul(w), transcript) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + out := &RangeProof{ + capA: capA, + capS: capS, + capT1: capT1, + capT2: capT2, + taux: taux, + mu: mu, + tHat: tHat, + ipp: ipp, + curve: &prover.curve, + } + return out, nil +} + +// See final term of L71 on pg 21 +// Sigma_{j=1}^{m} z^{1+j} * (0^{(j-1)*n} || 2^{n} || 0^{(m-j)*n}). +func getSumTermrXBatched(z curves.Scalar, n, m int, curve curves.Curve) []curves.Scalar { + twoN := get2nVector(n, curve) + var out []curves.Scalar + // The final power should be one more than m + zExp := z.Clone() + for j := 0; j < m; j++ { + zExp = zExp.Mul(z) + elem := multiplyScalarToScalarVector(zExp, twoN) + out = append(out, elem...) + } + + return out +} + +func getcapVBatched(v, gamma []curves.Scalar, g, h curves.Point) []curves.Point { + out := make([]curves.Point, len(v)) + for i, vi := range v { + out[i] = getcapV(vi, gamma[i], g, h) + } + return out +} + +func getaLBatched(v []curves.Scalar, n int, curve curves.Curve) ([]curves.Scalar, error) { + var aL []curves.Scalar + for _, vi := range v { + aLi, err := getaL(vi, n, curve) + if err != nil { + return nil, err + } + aL = append(aL, aLi...) + } + return aL, nil +} + +func calcyzBatched(capV []curves.Point, capA, capS curves.Point, transcript *merlin.Transcript, curve curves.Curve) (curves.Scalar, curves.Scalar, error) { + // Add the A,S values to transcript + for _, capVi := range capV { + transcript.AppendMessage([]byte("addV"), capVi.ToAffineUncompressed()) + } + transcript.AppendMessage([]byte("addcapA"), capA.ToAffineUncompressed()) + transcript.AppendMessage([]byte("addcapS"), capS.ToAffineUncompressed()) + // Read 64 bytes twice from, set to scalar for y and z + yBytes := transcript.ExtractBytes([]byte("gety"), 64) + y, err := curve.NewScalar().SetBytesWide(yBytes) + if err != nil { + return nil, nil, errors.Wrap(err, "calcyz NewScalar SetBytesWide") + } + zBytes := transcript.ExtractBytes([]byte("getz"), 64) + z, err := curve.NewScalar().SetBytesWide(zBytes) + if err != nil { + return nil, nil, errors.Wrap(err, "calcyz NewScalar SetBytesWide") + } + + return y, z, nil +} + +func deltayzBatched(y, z curves.Scalar, n, m int, curve curves.Curve) (curves.Scalar, error) { + // z - z^2 + zMinuszsquare := z.Sub(z.Square()) + // 1^(n*m) + onenm := get1nVector(n*m, curve) + // <1^nm, y^nm> + onenmdotynm, err := innerProduct(onenm, getknVector(y, n*m, curve)) + if err != nil { + return nil, errors.Wrap(err, "deltayz") + } + // (z - z^2)*<1^n, y^n> + termFirst := zMinuszsquare.Mul(onenmdotynm) + + // <1^n, 2^n> + onendottwon, err := innerProduct(get1nVector(n, curve), get2nVector(n, curve)) + if err != nil { + return nil, errors.Wrap(err, "deltayz") + } + + termSecond := curve.Scalar.Zero() + zExp := z.Square() + for j := 1; j < m+1; j++ { + zExp = zExp.Mul(z) + elem := zExp.Mul(onendottwon) + termSecond = termSecond.Add(elem) + } + + // (z - z^2)*<1^n, y^n> - z^3*<1^n, 2^n> + out := termFirst.Sub(termSecond) + + return out, nil +} + +// Bottom equation on pg21. +func getPhmuBatched(proofG, proofHPrime []curves.Point, h, capA, capS curves.Point, x, y, z, mu curves.Scalar, n, m int, curve curves.Curve) curves.Point { + twoN := get2nVector(n, curve) + // h'^(z*y^n + z^2*2^n) + lastElem := curve.NewIdentityPoint() + zExp := z.Clone() + for j := 1; j < m+1; j++ { + // Get subvector of h + hSubvector := proofHPrime[(j-1)*n : j*n] + // z^(j+1) + zExp = zExp.Mul(z) + exp := multiplyScalarToScalarVector(zExp, twoN) + // Final elem + elem := curve.Point.SumOfProducts(hSubvector, exp) + lastElem = lastElem.Add(elem) + } + + zynm := multiplyScalarToScalarVector(z, getknVector(y, n*m, curve)) + hPrimezynm := curve.Point.SumOfProducts(proofHPrime, zynm) + lastElem = lastElem.Add(hPrimezynm) + + // S^x + capSx := capS.Mul(x) + + // g^-z --> -z*<1,g> + onenm := get1nVector(n*m, curve) + zNeg := z.Neg() + zinvonen := multiplyScalarToScalarVector(zNeg, onenm) + zgdotonen := curve.Point.SumOfProducts(proofG, zinvonen) + + // L66 on pg20 + P := capA.Add(capSx).Add(zgdotonen).Add(lastElem) + hmu := h.Mul(mu) + Phmu := P.Sub(hmu) + + return Phmu +} diff --git a/pkg/crypto/bulletproof/range_batch_prover_test.go b/pkg/crypto/bulletproof/range_batch_prover_test.go new file mode 100755 index 000000000..d44e5365d --- /dev/null +++ b/pkg/crypto/bulletproof/range_batch_prover_test.go @@ -0,0 +1,102 @@ +package bulletproof + +import ( + crand "crypto/rand" + "testing" + + "github.com/gtank/merlin" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestRangeBatchProverHappyPath(t *testing.T) { + curve := curves.ED25519() + n := 256 + prover, err := NewRangeProver(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v1 := curve.Scalar.Random(crand.Reader) + v2 := curve.Scalar.Random(crand.Reader) + v3 := curve.Scalar.Random(crand.Reader) + v4 := curve.Scalar.Random(crand.Reader) + v := []curves.Scalar{v1, v2, v3, v4} + + gamma1 := curve.Scalar.Random(crand.Reader) + gamma2 := curve.Scalar.Random(crand.Reader) + gamma3 := curve.Scalar.Random(crand.Reader) + gamma4 := curve.Scalar.Random(crand.Reader) + gamma := []curves.Scalar{gamma1, gamma2, gamma3, gamma4} + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.BatchProve(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + require.NotNil(t, proof) + require.Equal(t, 10, len(proof.ipp.capLs)) + require.Equal(t, 10, len(proof.ipp.capRs)) +} + +func TestGetaLBatched(t *testing.T) { + curve := curves.ED25519() + v1 := curve.Scalar.Random(crand.Reader) + v2 := curve.Scalar.Random(crand.Reader) + v3 := curve.Scalar.Random(crand.Reader) + v4 := curve.Scalar.Random(crand.Reader) + v := []curves.Scalar{v1, v2, v3, v4} + aL, err := getaLBatched(v, 256, *curve) + require.NoError(t, err) + twoN := get2nVector(256, *curve) + for i := 1; i < len(v)+1; i++ { + vec := aL[(i-1)*256 : i*256] + product, err := innerProduct(vec, twoN) + require.NoError(t, err) + require.Zero(t, product.Cmp(v[i-1])) + } +} + +func TestRangeBatchProverMarshal(t *testing.T) { + curve := curves.ED25519() + n := 256 + prover, err := NewRangeProver(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v1 := curve.Scalar.Random(crand.Reader) + v2 := curve.Scalar.Random(crand.Reader) + v3 := curve.Scalar.Random(crand.Reader) + v4 := curve.Scalar.Random(crand.Reader) + v := []curves.Scalar{v1, v2, v3, v4} + + gamma1 := curve.Scalar.Random(crand.Reader) + gamma2 := curve.Scalar.Random(crand.Reader) + gamma3 := curve.Scalar.Random(crand.Reader) + gamma4 := curve.Scalar.Random(crand.Reader) + gamma := []curves.Scalar{gamma1, gamma2, gamma3, gamma4} + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.BatchProve(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + + proofMarshaled := proof.MarshalBinary() + proofPrime := NewRangeProof(curve) + err = proofPrime.UnmarshalBinary(proofMarshaled) + require.NoError(t, err) + require.True(t, proof.capA.Equal(proofPrime.capA)) + require.True(t, proof.capS.Equal(proofPrime.capS)) + require.True(t, proof.capT1.Equal(proofPrime.capT1)) + require.True(t, proof.capT2.Equal(proofPrime.capT2)) + require.Zero(t, proof.taux.Cmp(proofPrime.taux)) + require.Zero(t, proof.mu.Cmp(proofPrime.mu)) + require.Zero(t, proof.tHat.Cmp(proofPrime.tHat)) +} diff --git a/pkg/crypto/bulletproof/range_batch_verifier.go b/pkg/crypto/bulletproof/range_batch_verifier.go new file mode 100755 index 000000000..f8057ccf9 --- /dev/null +++ b/pkg/crypto/bulletproof/range_batch_verifier.go @@ -0,0 +1,91 @@ +package bulletproof + +import ( + "github.com/gtank/merlin" + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// VerifyBatched verifies a given batched range proof. +// It takes in a list of commitments to the secret values as capV instead of a single commitment to a single point +// when compared to the unbatched single range proof case. +func (verifier *RangeVerifier) VerifyBatched(proof *RangeProof, capV []curves.Point, proofGenerators RangeProofGenerators, n int, transcript *merlin.Transcript) (bool, error) { + // Define nm as the total bits required for secrets, calculated as number of secrets * n + m := len(capV) + nm := n * m + // nm must be less than the number of generators generated + if nm > len(verifier.generators.G) { + return false, errors.New("ipp vector length must be less than maxVectorLength") + } + + // In case where len(a) is less than number of generators precomputed by prover, trim to length + proofG := verifier.generators.G[0:nm] + proofH := verifier.generators.H[0:nm] + + // Calc y,z,x from Fiat Shamir heuristic + y, z, err := calcyzBatched(capV, proof.capA, proof.capS, transcript, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + x, err := calcx(proof.capT1, proof.capT2, transcript, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + wBytes := transcript.ExtractBytes([]byte("getw"), 64) + w, err := verifier.curve.NewScalar().SetBytesWide(wBytes) + if err != nil { + return false, errors.Wrap(err, "rangeproof prove") + } + + // Calc delta(y,z), redefined for batched case on pg21 + deltayzBatched, err := deltayzBatched(y, z, n, m, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + // Check tHat: L65, pg20 + // See equation 72 on pg21 + tHatIsValid := verifier.checktHatBatched(proof, capV, proofGenerators.g, proofGenerators.h, deltayzBatched, x, z, m) + if !tHatIsValid { + return false, errors.New("rangeproof verify tHat is invalid") + } + + // Verify IPP + hPrime, err := gethPrime(proofH, y, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + capPhmu := getPhmuBatched(proofG, hPrime, proofGenerators.h, proof.capA, proof.capS, x, y, z, proof.mu, n, m, verifier.curve) + + ippVerified, err := verifier.ippVerifier.VerifyFromRangeProof(proofG, hPrime, capPhmu, proofGenerators.u.Mul(w), proof.tHat, proof.ipp, transcript) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + return ippVerified, nil +} + +// L65, pg20. +func (verifier *RangeVerifier) checktHatBatched(proof *RangeProof, capV []curves.Point, g, h curves.Point, deltayz, x, z curves.Scalar, m int) bool { + // g^tHat * h^tau_x + gtHat := g.Mul(proof.tHat) + htaux := h.Mul(proof.taux) + lhs := gtHat.Add(htaux) + + // V^z^2 * g^delta(y,z) * Tau_1^x * Tau_2^x^2 + // g^delta(y,z) * V^(z^2*z^m) * Tau_1^x * Tau_2^x^2 + zm := getknVector(z, m, verifier.curve) + zsquarezm := multiplyScalarToScalarVector(z.Square(), zm) + capVzsquaretwom := verifier.curve.Point.SumOfProducts(capV, zsquarezm) + gdeltayz := g.Mul(deltayz) + capTau1x := proof.capT1.Mul(x) + capTau2xsquare := proof.capT2.Mul(x.Square()) + rhs := capVzsquaretwom.Add(gdeltayz).Add(capTau1x).Add(capTau2xsquare) + + // Compare lhs =? rhs + return lhs.Equal(rhs) +} diff --git a/pkg/crypto/bulletproof/range_batch_verifier_test.go b/pkg/crypto/bulletproof/range_batch_verifier_test.go new file mode 100755 index 000000000..49e0e5e29 --- /dev/null +++ b/pkg/crypto/bulletproof/range_batch_verifier_test.go @@ -0,0 +1,148 @@ +package bulletproof + +import ( + crand "crypto/rand" + "testing" + + "github.com/gtank/merlin" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestRangeBatchVerifyHappyPath(t *testing.T) { + curve := curves.ED25519() + n := 256 + prover, err := NewRangeProver(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v1 := curve.Scalar.Random(crand.Reader) + v2 := curve.Scalar.Random(crand.Reader) + v3 := curve.Scalar.Random(crand.Reader) + v4 := curve.Scalar.Random(crand.Reader) + v := []curves.Scalar{v1, v2, v3, v4} + gamma1 := curve.Scalar.Random(crand.Reader) + gamma2 := curve.Scalar.Random(crand.Reader) + gamma3 := curve.Scalar.Random(crand.Reader) + gamma4 := curve.Scalar.Random(crand.Reader) + gamma := []curves.Scalar{gamma1, gamma2, gamma3, gamma4} + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.BatchProve(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + + verifier, err := NewRangeVerifier(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + transcriptVerifier := merlin.NewTranscript("test") + capV := getcapVBatched(v, gamma, g, h) + verified, err := verifier.VerifyBatched(proof, capV, proofGenerators, n, transcriptVerifier) + require.NoError(t, err) + require.True(t, verified) +} + +func TestRangeBatchVerifyNotInRange(t *testing.T) { + curve := curves.ED25519() + n := 2 + prover, err := NewRangeProver(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v1 := curve.Scalar.One() + v2 := curve.Scalar.Random(crand.Reader) + v3 := curve.Scalar.Random(crand.Reader) + v4 := curve.Scalar.Random(crand.Reader) + v := []curves.Scalar{v1, v2, v3, v4} + gamma1 := curve.Scalar.Random(crand.Reader) + gamma2 := curve.Scalar.Random(crand.Reader) + gamma3 := curve.Scalar.Random(crand.Reader) + gamma4 := curve.Scalar.Random(crand.Reader) + gamma := []curves.Scalar{gamma1, gamma2, gamma3, gamma4} + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + _, err = prover.BatchProve(v, gamma, n, proofGenerators, transcript) + require.Error(t, err) +} + +func TestRangeBatchVerifyNonRandom(t *testing.T) { + curve := curves.ED25519() + n := 2 + prover, err := NewRangeProver(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v1 := curve.Scalar.One() + v2 := curve.Scalar.One() + v3 := curve.Scalar.One() + v4 := curve.Scalar.One() + v := []curves.Scalar{v1, v2, v3, v4} + gamma1 := curve.Scalar.Random(crand.Reader) + gamma2 := curve.Scalar.Random(crand.Reader) + gamma3 := curve.Scalar.Random(crand.Reader) + gamma4 := curve.Scalar.Random(crand.Reader) + gamma := []curves.Scalar{gamma1, gamma2, gamma3, gamma4} + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.BatchProve(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + + verifier, err := NewRangeVerifier(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + transcriptVerifier := merlin.NewTranscript("test") + capV := getcapVBatched(v, gamma, g, h) + verified, err := verifier.VerifyBatched(proof, capV, proofGenerators, n, transcriptVerifier) + require.NoError(t, err) + require.True(t, verified) +} + +func TestRangeBatchVerifyInvalid(t *testing.T) { + curve := curves.ED25519() + n := 2 + prover, err := NewRangeProver(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v1 := curve.Scalar.One() + v2 := curve.Scalar.One() + v3 := curve.Scalar.One() + v4 := curve.Scalar.One() + v := []curves.Scalar{v1, v2, v3, v4} + gamma1 := curve.Scalar.Random(crand.Reader) + gamma2 := curve.Scalar.Random(crand.Reader) + gamma3 := curve.Scalar.Random(crand.Reader) + gamma4 := curve.Scalar.Random(crand.Reader) + gamma := []curves.Scalar{gamma1, gamma2, gamma3, gamma4} + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.BatchProve(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + + verifier, err := NewRangeVerifier(n*4, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + transcriptVerifier := merlin.NewTranscript("test") + capV := getcapVBatched(v, gamma, g, h) + capV[0] = curve.Point.Random(crand.Reader) + verified, err := verifier.VerifyBatched(proof, capV, proofGenerators, n, transcriptVerifier) + require.Error(t, err) + require.False(t, verified) +} diff --git a/pkg/crypto/bulletproof/range_prover.go b/pkg/crypto/bulletproof/range_prover.go new file mode 100755 index 000000000..4f6dcd9b4 --- /dev/null +++ b/pkg/crypto/bulletproof/range_prover.go @@ -0,0 +1,476 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package bulletproof implements the zero knowledge protocol bulletproofs as defined in https://eprint.iacr.org/2017/1066.pdf +package bulletproof + +import ( + crand "crypto/rand" + "math/big" + + "github.com/gtank/merlin" + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// RangeProver is the struct used to create RangeProofs +// It specifies which curve to use and holds precomputed generators +// See NewRangeProver() for prover initialization. +type RangeProver struct { + curve curves.Curve + generators *ippGenerators + ippProver *InnerProductProver +} + +// RangeProof is the struct used to hold a range proof +// capA is a commitment to a_L and a_R using randomness alpha +// capS is a commitment to s_L and s_R using randomness rho +// capTau1,2 are commitments to t1,t2 respectively using randomness tau_1,2 +// tHat represents t(X) as defined on page 19 +// taux is the blinding factor for tHat +// ipp is the inner product proof used for compacting the transfer of l,r (See 4.2 on pg20). +type RangeProof struct { + capA, capS, capT1, capT2 curves.Point + taux, mu, tHat curves.Scalar + ipp *InnerProductProof + curve *curves.Curve +} + +type RangeProofGenerators struct { + g, h, u curves.Point +} + +// NewRangeProver initializes a new prover +// It uses the specified domain to generate generators for vectors of at most maxVectorLength +// A prover can be used to construct range proofs for vectors of length less than or equal to maxVectorLength +// A prover is defined by an explicit curve. +func NewRangeProver(maxVectorLength int, rangeDomain, ippDomain []byte, curve curves.Curve) (*RangeProver, error) { + generators, err := getGeneratorPoints(maxVectorLength, rangeDomain, curve) + if err != nil { + return nil, errors.Wrap(err, "range NewRangeProver") + } + ippProver, err := NewInnerProductProver(maxVectorLength, ippDomain, curve) + if err != nil { + return nil, errors.Wrap(err, "range NewRangeProver") + } + return &RangeProver{curve: curve, generators: generators, ippProver: ippProver}, nil +} + +// NewRangeProof initializes a new RangeProof for a specified curve +// This should be used in tandem with UnmarshalBinary() to convert a marshaled proof into the struct. +func NewRangeProof(curve *curves.Curve) *RangeProof { + out := RangeProof{ + capA: nil, + capS: nil, + capT1: nil, + capT2: nil, + taux: nil, + mu: nil, + tHat: nil, + ipp: NewInnerProductProof(curve), + curve: curve, + } + + return &out +} + +// Prove uses the range prover to prove that some value v is within the range [0, 2^n] +// It implements the protocol defined on pgs 19,20 in https://eprint.iacr.org/2017/1066.pdf +// v is the value of which to prove the range +// n is the power that specifies the upper bound of the range, ie. 2^n +// gamma is a scalar used for as a blinding factor +// g, h, u are unique points used as generators for the blinding factor +// transcript is a merlin transcript to be used for the fiat shamir heuristic. +func (prover *RangeProver) Prove(v, gamma curves.Scalar, n int, proofGenerators RangeProofGenerators, transcript *merlin.Transcript) (*RangeProof, error) { + // n must be less than or equal to the number of generators generated + if n > len(prover.generators.G) { + return nil, errors.New("ipp vector length must be less than or equal to maxVectorLength") + } + // In case where len(a) is less than number of generators precomputed by prover, trim to length + proofG := prover.generators.G[0:n] + proofH := prover.generators.H[0:n] + + // Check that v is in range [0, 2^n] + if bigZero := big.NewInt(0); v.BigInt().Cmp(bigZero) == -1 { + return nil, errors.New("v is less than 0") + } + + bigTwo := big.NewInt(2) + if n < 0 { + return nil, errors.New("n cannot be less than 0") + } + bigN := big.NewInt(int64(n)) + var bigTwoToN big.Int + bigTwoToN.Exp(bigTwo, bigN, nil) + if v.BigInt().Cmp(&bigTwoToN) == 1 { + return nil, errors.New("v is greater than 2^n") + } + + // L40 on pg19 + aL, err := getaL(v, n, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + onen := get1nVector(n, prover.curve) + // L41 on pg19 + aR, err := subtractPairwiseScalarVectors(aL, onen) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + alpha := prover.curve.Scalar.Random(crand.Reader) + // Calc A (L44, pg19) + halpha := proofGenerators.h.Mul(alpha) + gaL := prover.curve.Point.SumOfProducts(proofG, aL) + haR := prover.curve.Point.SumOfProducts(proofH, aR) + capA := halpha.Add(gaL).Add(haR) + + // L45, 46, pg19 + sL := getBlindingVector(n, prover.curve) + sR := getBlindingVector(n, prover.curve) + rho := prover.curve.Scalar.Random(crand.Reader) + + // Calc S (L47, pg19) + hrho := proofGenerators.h.Mul(rho) + gsL := prover.curve.Point.SumOfProducts(proofG, sL) + hsR := prover.curve.Point.SumOfProducts(proofH, sR) + capS := hrho.Add(gsL).Add(hsR) + + // Fiat Shamir for y,z (L49, pg19) + capV := getcapV(v, gamma, proofGenerators.g, proofGenerators.h) + y, z, err := calcyz(capV, capA, capS, transcript, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // Calc t_1, t_2 + // See the l(X), r(X), t(X) equations on pg 19 + // Use l(X)'s and r(X)'s constant and linear terms to derive t_1 and t_2 + // (a_l - z*1^n) + zonen := multiplyScalarToScalarVector(z, onen) + constantTerml, err := subtractPairwiseScalarVectors(aL, zonen) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + linearTerml := sL + + // z^2 * 2^N + twoN := get2nVector(n, prover.curve) + zSquareTwon := multiplyScalarToScalarVector(z.Square(), twoN) + // a_r + z*1^n + aRPluszonen, err := addPairwiseScalarVectors(aR, zonen) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + yn := getknVector(y, n, prover.curve) + hadamard, err := multiplyPairwiseScalarVectors(yn, aRPluszonen) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + constantTermr, err := addPairwiseScalarVectors(hadamard, zSquareTwon) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + linearTermr, err := multiplyPairwiseScalarVectors(yn, sR) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // t_1 (as the linear coefficient) is the sum of the dot products of l(X)'s linear term dot r(X)'s constant term + // and r(X)'s linear term dot l(X)'s constant term + t1FirstTerm, err := innerProduct(linearTerml, constantTermr) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + t1SecondTerm, err := innerProduct(linearTermr, constantTerml) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + t1 := t1FirstTerm.Add(t1SecondTerm) + + // t_2 (as the quadratic coefficient) is the dot product of l(X)'s and r(X)'s linear terms + t2, err := innerProduct(linearTerml, linearTermr) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // L52, pg20 + tau1 := prover.curve.Scalar.Random(crand.Reader) + tau2 := prover.curve.Scalar.Random(crand.Reader) + + // T_1, T_2 (L53, pg20) + capT1 := proofGenerators.g.Mul(t1).Add(proofGenerators.h.Mul(tau1)) + capT2 := proofGenerators.g.Mul(t2).Add(proofGenerators.h.Mul(tau2)) + + // Fiat shamir for x (L55, pg20) + x, err := calcx(capT1, capT2, transcript, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // Calc l (L58, pg20) + // Instead of using the expression in the line, evaluate l() at x + sLx := multiplyScalarToScalarVector(x, linearTerml) + l, err := addPairwiseScalarVectors(constantTerml, sLx) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // Calc r (L59, pg20) + // Instead of using the expression in the line, evaluate r() at x + ynsRx := multiplyScalarToScalarVector(x, linearTermr) + r, err := addPairwiseScalarVectors(constantTermr, ynsRx) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + // Calc t hat (L60, pg20) + // For efficiency, instead of calculating the dot product, evaluate t() at x + deltayz, err := deltayz(y, z, n, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + t0 := v.Mul(z.Square()).Add(deltayz) + tLinear := t1.Mul(x) + tQuadratic := t2.Mul(x.Square()) + tHat := t0.Add(tLinear).Add(tQuadratic) + + // Calc tau_x (L61, pg20) + tau2xsquare := tau2.Mul(x.Square()) + tau1x := tau1.Mul(x) + zsquaregamma := z.Square().Mul(gamma) + taux := tau2xsquare.Add(tau1x).Add(zsquaregamma) + + // Calc mu (L62, pg20) + mu := alpha.Add(rho.Mul(x)) + + // Calc IPP (See section 4.2) + hPrime, err := gethPrime(proofH, y, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + capPhmu, err := getPhmu(proofG, hPrime, proofGenerators.h, capA, capS, x, y, z, mu, n, prover.curve) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + wBytes := transcript.ExtractBytes([]byte("getw"), 64) + w, err := prover.curve.NewScalar().SetBytesWide(wBytes) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + ipp, err := prover.ippProver.rangeToIPP(proofG, hPrime, l, r, tHat, capPhmu, proofGenerators.u.Mul(w), transcript) + if err != nil { + return nil, errors.Wrap(err, "rangeproof prove") + } + + out := &RangeProof{ + capA: capA, + capS: capS, + capT1: capT1, + capT2: capT2, + taux: taux, + mu: mu, + tHat: tHat, + ipp: ipp, + curve: &prover.curve, + } + return out, nil +} + +// MarshalBinary takes a range proof and marshals into bytes. +func (proof *RangeProof) MarshalBinary() []byte { + var out []byte + out = append(out, proof.capA.ToAffineCompressed()...) + out = append(out, proof.capS.ToAffineCompressed()...) + out = append(out, proof.capT1.ToAffineCompressed()...) + out = append(out, proof.capT2.ToAffineCompressed()...) + out = append(out, proof.taux.Bytes()...) + out = append(out, proof.mu.Bytes()...) + out = append(out, proof.tHat.Bytes()...) + out = append(out, proof.ipp.MarshalBinary()...) + + return out +} + +// UnmarshalBinary takes bytes of a marshaled proof and writes them into a range proof +// The range proof used should be from the output of NewRangeProof(). +func (proof *RangeProof) UnmarshalBinary(data []byte) error { + scalarLen := len(proof.curve.NewScalar().Bytes()) + pointLen := len(proof.curve.NewGeneratorPoint().ToAffineCompressed()) + ptr := 0 + // Get points + capA, err := proof.curve.Point.FromAffineCompressed(data[ptr : ptr+pointLen]) + if err != nil { + return errors.New("rangeProof UnmarshalBinary FromAffineCompressed") + } + proof.capA = capA + ptr += pointLen + capS, err := proof.curve.Point.FromAffineCompressed(data[ptr : ptr+pointLen]) + if err != nil { + return errors.New("rangeProof UnmarshalBinary FromAffineCompressed") + } + proof.capS = capS + ptr += pointLen + capT1, err := proof.curve.Point.FromAffineCompressed(data[ptr : ptr+pointLen]) + if err != nil { + return errors.New("rangeProof UnmarshalBinary FromAffineCompressed") + } + proof.capT1 = capT1 + ptr += pointLen + capT2, err := proof.curve.Point.FromAffineCompressed(data[ptr : ptr+pointLen]) + if err != nil { + return errors.New("rangeProof UnmarshalBinary FromAffineCompressed") + } + proof.capT2 = capT2 + ptr += pointLen + + // Get scalars + taux, err := proof.curve.NewScalar().SetBytes(data[ptr : ptr+scalarLen]) + if err != nil { + return errors.New("rangeProof UnmarshalBinary SetBytes") + } + proof.taux = taux + ptr += scalarLen + mu, err := proof.curve.NewScalar().SetBytes(data[ptr : ptr+scalarLen]) + if err != nil { + return errors.New("rangeProof UnmarshalBinary SetBytes") + } + proof.mu = mu + ptr += scalarLen + tHat, err := proof.curve.NewScalar().SetBytes(data[ptr : ptr+scalarLen]) + if err != nil { + return errors.New("rangeProof UnmarshalBinary SetBytes") + } + proof.tHat = tHat + ptr += scalarLen + + // Get IPP + err = proof.ipp.UnmarshalBinary(data[ptr:]) + if err != nil { + return errors.New("rangeProof UnmarshalBinary") + } + + return nil +} + +// checkRange validates whether some scalar v is within the range [0, 2^n - 1] +// It will return an error if v is less than 0 or greater than 2^n - 1 +// Otherwise it will return nil. +func checkRange(v curves.Scalar, n int) error { + bigOne := big.NewInt(1) + if n < 0 { + return errors.New("n cannot be less than 0") + } + var bigTwoToN big.Int + bigTwoToN.Lsh(bigOne, uint(n)) + if v.BigInt().Cmp(&bigTwoToN) == 1 { + return errors.New("v is greater than 2^n") + } + + return nil +} + +// getBlindingVector returns a vector of scalars used as blinding factors for commitments. +func getBlindingVector(length int, curve curves.Curve) []curves.Scalar { + vec := make([]curves.Scalar, length) + for i := 0; i < length; i++ { + vec[i] = curve.Scalar.Random(crand.Reader) + } + return vec +} + +// getcapV returns a commitment to v using blinding factor gamma. +func getcapV(v, gamma curves.Scalar, g, h curves.Point) curves.Point { + return h.Mul(gamma).Add(g.Mul(v)) +} + +// getaL obtains the bit vector representation of v +// See the a_L definition towards the bottom of pg 17 of https://eprint.iacr.org/2017/1066.pdf +func getaL(v curves.Scalar, n int, curve curves.Curve) ([]curves.Scalar, error) { + var err error + + vBytes := v.Bytes() + zero := curve.Scalar.Zero() + one := curve.Scalar.One() + aL := make([]curves.Scalar, n) + for j := 0; j < len(aL); j++ { + aL[j] = zero + } + for i := 0; i < n; i++ { + ithBit := vBytes[i>>3] >> (i & 0x07) & 0x01 + aL[i], err = cmoveScalar(zero, one, int(ithBit), curve) + if err != nil { + return nil, errors.Wrap(err, "getaL") + } + } + + return aL, nil +} + +// cmoveScalar provides a constant time operation that returns x if which is 0 and returns y if which is 1. +func cmoveScalar(x, y curves.Scalar, which int, curve curves.Curve) (curves.Scalar, error) { + if which != 0 && which != 1 { + return nil, errors.New("cmoveScalar which must be 0 or 1") + } + mask := -byte(which) + xBytes := x.Bytes() + yBytes := y.Bytes() + for i, xByte := range xBytes { + xBytes[i] ^= (xByte ^ yBytes[i]) & mask + } + out, err := curve.NewScalar().SetBytes(xBytes) + if err != nil { + return nil, errors.Wrap(err, "cmoveScalar SetBytes") + } + + return out, nil +} + +// calcyz uses a merlin transcript for Fiat Shamir +// It takes the current state of the transcript and appends the newly calculated capA and capS values +// Two new scalars are then read from the transcript +// See section 4.4 pg22 of https://eprint.iacr.org/2017/1066.pdf +func calcyz(capV, capA, capS curves.Point, transcript *merlin.Transcript, curve curves.Curve) (curves.Scalar, curves.Scalar, error) { + // Add the A,S values to transcript + transcript.AppendMessage([]byte("addV"), capV.ToAffineUncompressed()) + transcript.AppendMessage([]byte("addcapA"), capA.ToAffineUncompressed()) + transcript.AppendMessage([]byte("addcapS"), capS.ToAffineUncompressed()) + // Read 64 bytes twice from, set to scalar for y and z + yBytes := transcript.ExtractBytes([]byte("gety"), 64) + y, err := curve.NewScalar().SetBytesWide(yBytes) + if err != nil { + return nil, nil, errors.Wrap(err, "calcyz NewScalar SetBytesWide") + } + zBytes := transcript.ExtractBytes([]byte("getz"), 64) + z, err := curve.NewScalar().SetBytesWide(zBytes) + if err != nil { + return nil, nil, errors.Wrap(err, "calcyz NewScalar SetBytesWide") + } + + return y, z, nil +} + +// calcx uses a merlin transcript for Fiat Shamir +// It takes the current state of the transcript and appends the newly calculated capT1 and capT2 values +// A new scalar is then read from the transcript +// See section 4.4 pg22 of https://eprint.iacr.org/2017/1066.pdf +func calcx(capT1, capT2 curves.Point, transcript *merlin.Transcript, curve curves.Curve) (curves.Scalar, error) { + // Add the Tau1,2 values to transcript + transcript.AppendMessage([]byte("addcapT1"), capT1.ToAffineUncompressed()) + transcript.AppendMessage([]byte("addcapT2"), capT2.ToAffineUncompressed()) + // Read 64 bytes from, set to scalar + outBytes := transcript.ExtractBytes([]byte("getx"), 64) + x, err := curve.NewScalar().SetBytesWide(outBytes) + if err != nil { + return nil, errors.Wrap(err, "calcx NewScalar SetBytesWide") + } + + return x, nil +} diff --git a/pkg/crypto/bulletproof/range_prover_test.go b/pkg/crypto/bulletproof/range_prover_test.go new file mode 100755 index 000000000..a5deb8da1 --- /dev/null +++ b/pkg/crypto/bulletproof/range_prover_test.go @@ -0,0 +1,86 @@ +package bulletproof + +import ( + crand "crypto/rand" + "testing" + + "github.com/gtank/merlin" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestRangeProverHappyPath(t *testing.T) { + curve := curves.ED25519() + n := 256 + prover, err := NewRangeProver(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v := curve.Scalar.Random(crand.Reader) + gamma := curve.Scalar.Random(crand.Reader) + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.Prove(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + require.NotNil(t, proof) + require.Equal(t, 8, len(proof.ipp.capLs)) + require.Equal(t, 8, len(proof.ipp.capRs)) +} + +func TestGetaL(t *testing.T) { + curve := curves.ED25519() + v := curve.Scalar.Random(crand.Reader) + aL, err := getaL(v, 256, *curve) + require.NoError(t, err) + twoN := get2nVector(256, *curve) + product, err := innerProduct(aL, twoN) + require.NoError(t, err) + require.Zero(t, product.Cmp(v)) +} + +func TestCmove(t *testing.T) { + curve := curves.ED25519() + two := curve.Scalar.One().Double() + four := two.Double() + out, err := cmoveScalar(two, four, 1, *curve) + require.NoError(t, err) + require.Zero(t, out.Cmp(four)) +} + +func TestRangeProverMarshal(t *testing.T) { + curve := curves.ED25519() + n := 256 + prover, err := NewRangeProver(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v := curve.Scalar.Random(crand.Reader) + gamma := curve.Scalar.Random(crand.Reader) + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.Prove(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + + proofMarshaled := proof.MarshalBinary() + proofPrime := NewRangeProof(curve) + err = proofPrime.UnmarshalBinary(proofMarshaled) + require.NoError(t, err) + require.True(t, proof.capA.Equal(proofPrime.capA)) + require.True(t, proof.capS.Equal(proofPrime.capS)) + require.True(t, proof.capT1.Equal(proofPrime.capT1)) + require.True(t, proof.capT2.Equal(proofPrime.capT2)) + require.Zero(t, proof.taux.Cmp(proofPrime.taux)) + require.Zero(t, proof.mu.Cmp(proofPrime.mu)) + require.Zero(t, proof.tHat.Cmp(proofPrime.tHat)) +} diff --git a/pkg/crypto/bulletproof/range_verifier.go b/pkg/crypto/bulletproof/range_verifier.go new file mode 100755 index 000000000..76c94e243 --- /dev/null +++ b/pkg/crypto/bulletproof/range_verifier.go @@ -0,0 +1,187 @@ +package bulletproof + +import ( + "github.com/gtank/merlin" + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// RangeVerifier is the struct used to verify RangeProofs +// It specifies which curve to use and holds precomputed generators +// See NewRangeVerifier() for verifier initialization. +type RangeVerifier struct { + curve curves.Curve + generators *ippGenerators + ippVerifier *InnerProductVerifier +} + +// NewRangeVerifier initializes a new verifier +// It uses the specified domain to generate generators for vectors of at most maxVectorLength +// A verifier can be used to verify range proofs for vectors of length less than or equal to maxVectorLength +// A verifier is defined by an explicit curve. +func NewRangeVerifier(maxVectorLength int, rangeDomain, ippDomain []byte, curve curves.Curve) (*RangeVerifier, error) { + generators, err := getGeneratorPoints(maxVectorLength, rangeDomain, curve) + if err != nil { + return nil, errors.Wrap(err, "range NewRangeProver") + } + ippVerifier, err := NewInnerProductVerifier(maxVectorLength, ippDomain, curve) + if err != nil { + return nil, errors.Wrap(err, "range NewRangeProver") + } + return &RangeVerifier{curve: curve, generators: generators, ippVerifier: ippVerifier}, nil +} + +// Verify verifies the given range proof inputs +// It implements the checking of L65 on pg 20 +// It also verifies the dot product of using the inner product proof\ +// capV is a commitment to v using blinding factor gamma +// n is the power that specifies the upper bound of the range, ie. 2^n +// g, h, u are unique points used as generators for the blinding factor +// transcript is a merlin transcript to be used for the fiat shamir heuristic. +func (verifier *RangeVerifier) Verify(proof *RangeProof, capV curves.Point, proofGenerators RangeProofGenerators, n int, transcript *merlin.Transcript) (bool, error) { + // Length of vectors must be less than the number of generators generated + if n > len(verifier.generators.G) { + return false, errors.New("ipp vector length must be less than maxVectorLength") + } + // In case where len(a) is less than number of generators precomputed by prover, trim to length + proofG := verifier.generators.G[0:n] + proofH := verifier.generators.H[0:n] + + // Calc y,z,x from Fiat Shamir heuristic + y, z, err := calcyz(capV, proof.capA, proof.capS, transcript, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + x, err := calcx(proof.capT1, proof.capT2, transcript, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + wBytes := transcript.ExtractBytes([]byte("getw"), 64) + w, err := verifier.curve.NewScalar().SetBytesWide(wBytes) + if err != nil { + return false, errors.Wrap(err, "rangeproof prove") + } + + // Calc delta(y,z) + deltayz, err := deltayz(y, z, n, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + // Check tHat: L65, pg20 + tHatIsValid := verifier.checktHat(proof, capV, proofGenerators.g, proofGenerators.h, deltayz, x, z) + if !tHatIsValid { + return false, errors.New("rangeproof verify tHat is invalid") + } + + // Verify IPP + hPrime, err := gethPrime(proofH, y, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + capPhmu, err := getPhmu(proofG, hPrime, proofGenerators.h, proof.capA, proof.capS, x, y, z, proof.mu, n, verifier.curve) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + ippVerified, err := verifier.ippVerifier.VerifyFromRangeProof(proofG, hPrime, capPhmu, proofGenerators.u.Mul(w), proof.tHat, proof.ipp, transcript) + if err != nil { + return false, errors.Wrap(err, "rangeproof verify") + } + + return ippVerified, nil +} + +// L65, pg20. +func (*RangeVerifier) checktHat(proof *RangeProof, capV, g, h curves.Point, deltayz, x, z curves.Scalar) bool { + // g^tHat * h^tau_x + gtHat := g.Mul(proof.tHat) + htaux := h.Mul(proof.taux) + lhs := gtHat.Add(htaux) + + // V^z^2 * g^delta(y,z) * Tau_1^x * Tau_2^x^2 + capVzsquare := capV.Mul(z.Square()) + gdeltayz := g.Mul(deltayz) + capTau1x := proof.capT1.Mul(x) + capTau2xsquare := proof.capT2.Mul(x.Square()) + rhs := capVzsquare.Add(gdeltayz).Add(capTau1x).Add(capTau2xsquare) + + // Compare lhs =? rhs + return lhs.Equal(rhs) +} + +// gethPrime calculates new h prime generators as defined in L64 on pg20. +func gethPrime(h []curves.Point, y curves.Scalar, curve curves.Curve) ([]curves.Point, error) { + hPrime := make([]curves.Point, len(h)) + yInv, err := y.Invert() + yInvn := getknVector(yInv, len(h), curve) + if err != nil { + return nil, errors.Wrap(err, "gethPrime") + } + for i, hElem := range h { + hPrime[i] = hElem.Mul(yInvn[i]) + } + return hPrime, nil +} + +// Obtain P used for IPP verification +// See L67 on pg20 +// Note P on L66 includes blinding factor hmu, this method removes that factor. +func getPhmu(proofG, proofHPrime []curves.Point, h, capA, capS curves.Point, x, y, z, mu curves.Scalar, n int, curve curves.Curve) (curves.Point, error) { + // h'^(z*y^n + z^2*2^n) + zyn := multiplyScalarToScalarVector(z, getknVector(y, n, curve)) + zsquaretwon := multiplyScalarToScalarVector(z.Square(), get2nVector(n, curve)) + elemLastExponent, err := addPairwiseScalarVectors(zyn, zsquaretwon) + if err != nil { + return nil, errors.Wrap(err, "getPhmu") + } + lastElem := curve.Point.SumOfProducts(proofHPrime, elemLastExponent) + + // S^x + capSx := capS.Mul(x) + + // g^-z --> -z*<1,g> + onen := get1nVector(n, curve) + zNeg := z.Neg() + zinvonen := multiplyScalarToScalarVector(zNeg, onen) + zgdotonen := curve.Point.SumOfProducts(proofG, zinvonen) + + // L66 on pg20 + P := capA.Add(capSx).Add(zgdotonen).Add(lastElem) + hmu := h.Mul(mu) + Phmu := P.Sub(hmu) + + return Phmu, nil +} + +// Delta function for delta(y,z), See (39) on pg18. +func deltayz(y, z curves.Scalar, n int, curve curves.Curve) (curves.Scalar, error) { + // z - z^2 + zMinuszsquare := z.Sub(z.Square()) + // 1^n + onen := get1nVector(n, curve) + // <1^n, y^n> + onendotyn, err := innerProduct(onen, getknVector(y, n, curve)) + if err != nil { + return nil, errors.Wrap(err, "deltayz") + } + // (z - z^2)*<1^n, y^n> + termFirst := zMinuszsquare.Mul(onendotyn) + + // <1^n, 2^n> + onendottwon, err := innerProduct(onen, get2nVector(n, curve)) + if err != nil { + return nil, errors.Wrap(err, "deltayz") + } + // z^3*<1^n, 2^n> + termSecond := z.Cube().Mul(onendottwon) + + // (z - z^2)*<1^n, y^n> - z^3*<1^n, 2^n> + out := termFirst.Sub(termSecond) + + return out, nil +} diff --git a/pkg/crypto/bulletproof/range_verifier_test.go b/pkg/crypto/bulletproof/range_verifier_test.go new file mode 100755 index 000000000..3880ccfd4 --- /dev/null +++ b/pkg/crypto/bulletproof/range_verifier_test.go @@ -0,0 +1,87 @@ +package bulletproof + +import ( + crand "crypto/rand" + "testing" + + "github.com/gtank/merlin" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestRangeVerifyHappyPath(t *testing.T) { + curve := curves.ED25519() + n := 256 + prover, err := NewRangeProver(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v := curve.Scalar.Random(crand.Reader) + gamma := curve.Scalar.Random(crand.Reader) + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.Prove(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + + verifier, err := NewRangeVerifier(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + transcriptVerifier := merlin.NewTranscript("test") + capV := getcapV(v, gamma, g, h) + verified, err := verifier.Verify(proof, capV, proofGenerators, n, transcriptVerifier) + require.NoError(t, err) + require.True(t, verified) +} + +func TestRangeVerifyNotInRange(t *testing.T) { + curve := curves.ED25519() + n := 2 + prover, err := NewRangeProver(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v := curve.Scalar.Random(crand.Reader) + gamma := curve.Scalar.Random(crand.Reader) + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + _, err = prover.Prove(v, gamma, n, proofGenerators, transcript) + require.Error(t, err) +} + +func TestRangeVerifyNonRandom(t *testing.T) { + curve := curves.ED25519() + n := 2 + prover, err := NewRangeProver(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + v := curve.Scalar.One() + gamma := curve.Scalar.Random(crand.Reader) + g := curve.Point.Random(crand.Reader) + h := curve.Point.Random(crand.Reader) + u := curve.Point.Random(crand.Reader) + proofGenerators := RangeProofGenerators{ + g: g, + h: h, + u: u, + } + transcript := merlin.NewTranscript("test") + proof, err := prover.Prove(v, gamma, n, proofGenerators, transcript) + require.NoError(t, err) + + verifier, err := NewRangeVerifier(n, []byte("rangeDomain"), []byte("ippDomain"), *curve) + require.NoError(t, err) + transcriptVerifier := merlin.NewTranscript("test") + capV := getcapV(v, gamma, g, h) + verified, err := verifier.Verify(proof, capV, proofGenerators, n, transcriptVerifier) + require.NoError(t, err) + require.True(t, verified) +} diff --git a/pkg/crypto/core/README.md b/pkg/crypto/core/README.md new file mode 100755 index 000000000..8cc6599f1 --- /dev/null +++ b/pkg/crypto/core/README.md @@ -0,0 +1,14 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## Core Package + +The core package contains a set of primitives, including but not limited to various +elliptic curves, hashes, and commitment schemes. These primitives are used internally +and can also be used independently on their own externally. diff --git a/pkg/crypto/core/commit.go b/pkg/crypto/core/commit.go new file mode 100755 index 000000000..8cfe0423b --- /dev/null +++ b/pkg/crypto/core/commit.go @@ -0,0 +1,115 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package core + +import ( + "crypto/hmac" + crand "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "encoding/json" + "fmt" + "hash" +) + +// Size of random values and hash outputs are determined by our hash function +const Size = sha256.Size + +type ( + // Commitment to a given message which can be later revealed. + // This is sent to and held by a verifier until the corresponding + // witness is provided. + Commitment []byte + + // Witness is sent to and opened by the verifier. This proves that + // committed message hasn't been altered by later information. + Witness struct { + Msg []byte + r [Size]byte + } + + // witnessJSON is used for un/marshaling. + witnessJSON struct { + Msg []byte + R [Size]byte + } +) + +// MarshalJSON encodes Witness in JSON +func (w Witness) MarshalJSON() ([]byte, error) { + return json.Marshal(witnessJSON{w.Msg, w.r}) +} + +// UnmarshalJSON decodes JSON into a Witness struct +func (w *Witness) UnmarshalJSON(data []byte) error { + witness := &witnessJSON{} + err := json.Unmarshal(data, witness) + if err != nil { + return err + } + w.Msg = witness.Msg + w.r = witness.R + return nil +} + +// Commit to a given message. Uses SHA256 as the hash function. +func Commit(msg []byte) (Commitment, *Witness, error) { + // Initialize our decommitment + d := Witness{msg, [Size]byte{}} + + // Generate a random nonce of the required length + n, err := crand.Read(d.r[:]) + // Ensure no errors retrieving nonce + if err != nil { + return nil, nil, err + } + + // Ensure we read all the bytes expected + if n != Size { + return nil, nil, fmt.Errorf("failed to read %v bytes from crypto/rand: received %v bytes", Size, n) + } + // Compute the commitment: HMAC(Sha2, msg, key) + c, err := ComputeHMAC(sha256.New, msg, d.r[:]) + if err != nil { + return nil, nil, err + } + return c, &d, nil +} + +// Open a commitment and return true if the commitment/decommitment pair are valid. +// reference: spec.§2.4: Commitment Scheme +func Open(c Commitment, d Witness) (bool, error) { + // Ensure commitment is well-formed. + if len(c) != Size { + return false, fmt.Errorf("invalid commitment, wrong length. %v != %v", len(c), Size) + } + + // Re-compute the commitment: HMAC(Sha2, msg, key) + cʹ, err := ComputeHMAC(sha256.New, d.Msg, d.r[:]) + if err != nil { + return false, err + } + return subtle.ConstantTimeCompare(cʹ, c) == 1, nil +} + +// ComputeHMAC computes HMAC(hash_fn, msg, key) +// Takes in a hash function to use for HMAC +func ComputeHMAC(f func() hash.Hash, msg []byte, k []byte) ([]byte, error) { + if f == nil { + return nil, fmt.Errorf("hash function cannot be nil") + } + + mac := hmac.New(f, k) + w, err := mac.Write(msg) + + if w != len(msg) { + return nil, fmt.Errorf("bytes written to hash doesn't match expected: %v != %v", w, len(msg)) + } else if err != nil { + return nil, err + } + return mac.Sum(nil), nil +} diff --git a/pkg/crypto/core/commit_test.go b/pkg/crypto/core/commit_test.go new file mode 100755 index 000000000..03ad88f54 --- /dev/null +++ b/pkg/crypto/core/commit_test.go @@ -0,0 +1,374 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package core + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +// An entry into our test table +type entry struct { + // Input + msg []byte + + // Result (actual, not expected) + commit Commitment + decommit *Witness + err error +} + +// Test inputs and placeholders for results that will be filled in +// during init() +var testResults = []entry{ + {[]byte("This is a test message"), nil, nil, nil}, + {[]byte("short msg"), nil, nil, nil}, + {[]byte("This input field is intentionally longer than the SHA256 block size to ensure that the entire message is processed"), + nil, nil, nil}, + {[]byte{0xFB, 0x1A, 0x18, 0x47, 0x39, 0x3C, 0x9F, 0x45, 0x5F, 0x29, 0x4C, 0x51, 0x42, 0x30, 0xA6, 0xB9}, + nil, nil, nil}, + // msg = \epsilon (empty string) + {[]byte{}, nil, nil, nil}, + // msg == nil + {nil, nil, nil, nil}, +} + +// Run our inputs through commit and record the outputs +func init() { + for i := range testResults { + entry := &testResults[i] + entry.commit, entry.decommit, entry.err = Commit(entry.msg) + } +} + +// Computing commitments should never produce errors +func TestCommitWithoutErrors(t *testing.T) { + for _, entry := range testResults { + if entry.err != nil { + t.Errorf("received Commit(%v): %v", entry.msg, entry.err) + } + } +} + +// Commitments should be 256b == 64B in length +func TestCommitmentsAreExpectedLength(t *testing.T) { + const expLen = 256 / 8 + for _, entry := range testResults { + if len(entry.commit) != expLen { + t.Errorf("commitment is not expected length: %v != %v", len(entry.commit), expLen) + } + } +} + +// Decommit cannot be nil +func TestCommmitProducesDecommit(t *testing.T) { + for _, entry := range testResults { + if entry.decommit == nil { + t.Errorf("decommit cannot be nil: Commit(%v)", entry.msg) + } + } +} + +// Decommit value should contain the same message +func TestCommmitProducesDecommitWithSameMessage(t *testing.T) { + for _, entry := range testResults { + if !bytes.Equal(entry.msg, entry.decommit.Msg) { + t.Errorf("decommit.msg != msg: %v != %v", entry.msg, entry.decommit.Msg) + } + } +} + +// Commitments should be unique +func TestCommmitProducesDistinctCommitments(t *testing.T) { + seen := make(map[[Size]byte]bool) + + // Check the pre-computed commitments for uniquness + for _, entry := range testResults { + + // Slices cannot be used as hash keys, so we need to copy into + // an array. Oh, go-lang. + var cee [Size]byte + copy(cee[:], entry.commit) + + // Ensure each commit is unique + if seen[cee] { + t.Errorf("duplicate commit found: %v", cee) + } + seen[cee] = true + } +} + +// Commitments should be unique even for the same message since the nonce is +// randomly selected +func TestCommmitDistinctCommitments(t *testing.T) { + seen := make(map[[Size]byte]bool) + msg := []byte("black lives matter") + const iterations = 1000 + + // Check the pre-computed commitments for uniquness + for i := 0; i < iterations; i++ { + // Compute a commitment + c, _, err := Commit(msg) + if err != nil { + t.Error(err) + } + + // Slices cannot be used as hash keys, so copy into an array + var cee [Size]byte + copy(cee[:], []byte(c)) + + // Ensure each commit is unique + if seen[cee] { + t.Errorf("duplicate commit found: %v", cee) + } + seen[cee] = true + } +} + +// Nonces must be 256b = 64B +func TestCommmitNonceIsExpectedLength(t *testing.T) { + const expLen = 256 / 8 + + // Check the pre-computed nonces + for _, entry := range testResults { + if len(entry.decommit.r) != expLen { + t.Errorf("nonce is not expected length: %v != %v", len(entry.decommit.r), expLen) + } + } +} + +// Randomly selected nonces will be unique with overwhelming probability +func TestCommmitProducesDistinctNonces(t *testing.T) { + seen := make(map[[Size]byte]bool) + msg := []byte("black lives matter") + const iterations = 1000 + + // Check the pre-computed commitments for uniquness + for i := 0; i < iterations; i++ { + // Compute a commitment + _, dee, err := Commit(msg) + if err != nil { + t.Error(err) + } + + // Ensure each nonce is unique + if seen[dee.r] { + t.Errorf("duplicate nonce found: %v", dee.r) + } + seen[dee.r] = true + } +} + +func TestOpenOnValidCommitments(t *testing.T) { + for _, entry := range testResults { + + // Open each commitment + ok, err := Open(entry.commit, *entry.decommit) + + // There should be no error + if err != nil { + t.Error(err) + } + + // The commitments should verify + if !ok { + t.Errorf("commitment failed to open: %v", entry.msg) + } + } +} + +func TestOpenOnModifiedNonce(t *testing.T) { + for _, entry := range testResults { + dʹ := copyWitness(entry.decommit) + + // Modify the nonce + dʹ.r[0] ^= 0x40 + + // Open and check for failure + ok, err := Open(entry.commit, *dʹ) + assertFailedOpen(t, ok, err) + } +} + +func TestOpenOnZeroPrefixNonce(t *testing.T) { + for _, entry := range testResults { + dʹ := copyWitness(entry.decommit) + + // Modify the nonce + dʹ.r[0] = 0x00 + dʹ.r[1] = 0x00 + dʹ.r[2] = 0x00 + dʹ.r[3] = 0x00 + dʹ.r[4] = 0x00 + dʹ.r[5] = 0x00 + dʹ.r[6] = 0x00 + dʹ.r[7] = 0x00 + dʹ.r[8] = 0x00 + dʹ.r[9] = 0x00 + dʹ.r[10] = 0x00 + + // Open and check for failure + ok, err := Open(entry.commit, *dʹ) + assertFailedOpen(t, ok, err) + } +} + +// Makes a deep copy of a Witness +func copyWitness(d *Witness) *Witness { + msg := make([]byte, len(d.Msg)) + var r [Size]byte + + copy(msg, d.Msg) + copy(r[:], d.r[:]) + return &Witness{msg, r} +} + +// Asserts that err != nil, and ok == false. +func assertFailedOpen(t *testing.T, ok bool, err error) { + // There should be no error + if err != nil { + t.Error(err) + } + + // But the commitments should fail + if ok { + t.Error("commitment was verified but was expected to fail") + } +} + +// An unrelated message should fail on open +func TestOpenOnNewMessage(t *testing.T) { + for _, entry := range testResults { + dʹ := copyWitness(entry.decommit) + + // Use a distinct message + dʹ.Msg = []byte("no one expects the spanish inquisition") + + // Open and check for failure + ok, err := Open(entry.commit, *dʹ) + assertFailedOpen(t, ok, err) + } +} + +// An appended message should fail on open +func TestOpenOnAppendedMessage(t *testing.T) { + for _, entry := range testResults { + dʹ := copyWitness(entry.decommit) + + // Modify the message + dʹ.Msg = []byte("no one expects the spanish inquisition") + + // Open and check for failure + ok, err := Open(entry.commit, *dʹ) + assertFailedOpen(t, ok, err) + } +} + +// A modified message should fail on open +func TestOpenOnModifiedMessage(t *testing.T) { + for _, entry := range testResults { + // Skip the empty string message for this test case + if len(entry.msg) == 0 { + continue + } + + // Modify the message _in situ_ + dʹ := copyWitness(entry.decommit) + dʹ.Msg[1] ^= 0x99 + + // Open and check for failure + ok, err := Open(entry.commit, *dʹ) + assertFailedOpen(t, ok, err) + } +} + +// A modified commitment should fail on open +func TestOpenOnModifiedCommitment(t *testing.T) { + for _, entry := range testResults { + // Copy and then modify the commitment + cʹ := make([]byte, Size) + copy(cʹ[:], entry.commit) + cʹ[6] ^= 0x33 + + // Open and check for failure + ok, err := Open(cʹ, *entry.decommit) + assertFailedOpen(t, ok, err) + } +} + +// An empty decommit should fail to open +func TestOpenOnDefaultDecommitObject(t *testing.T) { + for _, entry := range testResults { + // Open and check for failure + ok, err := Open(entry.commit, Witness{}) + assertFailedOpen(t, ok, err) + } +} + +// A nil commit should return an error +func TestOpenOnNilCommitment(t *testing.T) { + _, err := Open(nil, Witness{}) + assertError(t, err) +} + +// Verifies that err != nil +func assertError(t *testing.T, err error) { + if err == nil { + t.Error("expected an error but received nil") + } +} + +// Ill-formed commitment should produce an error +func TestOpenOnLongCommitment(t *testing.T) { + tooLong := make([]byte, Size+1) + _, err := Open(tooLong, Witness{}) + assertError(t, err) +} + +// Ill-formed commitment should produce an error +func TestOpenOnShortCommitment(t *testing.T) { + tooShort := make([]byte, Size-1) + _, err := Open(tooShort, Witness{}) + assertError(t, err) +} + +// Tests that marshal-unmarshal is the identity function +func TestWitnessMarshalRoundTrip(t *testing.T) { + expected := &Witness{ + []byte("I'm the dude. So that's what you call me"), + [Size]byte{0xAC}, + } + + // Marhal and test + jsonBytes, err := json.Marshal(expected) + require.NoError(t, err) + require.NotNil(t, jsonBytes) + + // Unmarshal and test + actual := &Witness{} + require.NoError(t, json.Unmarshal(jsonBytes, actual)) + require.Equal(t, expected.Msg, actual.Msg) + require.Equal(t, expected.r, actual.r) +} + +// Tests that marshal-unmarshal is the identity function +func TestCommitmentMarshalRoundTrip(t *testing.T) { + expected := Commitment([]byte("That or uh his-dudeness or duder or el duderino.")) + + // Marhal and test + jsonBytes, err := json.Marshal(expected) + require.NoError(t, err) + require.NotNil(t, jsonBytes) + + // Unmarshal and test + actual := Commitment{} + require.NoError(t, json.Unmarshal(jsonBytes, &actual)) + require.Equal(t, []byte(expected), []byte(actual)) +} diff --git a/pkg/crypto/core/curves/bls12377_curve.go b/pkg/crypto/core/curves/bls12377_curve.go new file mode 100755 index 000000000..59bbee16b --- /dev/null +++ b/pkg/crypto/core/curves/bls12377_curve.go @@ -0,0 +1,1226 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// NOTE that the bls curves are NOT constant time. There is an open issue to address it: https://github.com/sonr-eco/kryptology/issues/233 + +package curves + +import ( + "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "fmt" + "io" + "math/big" + + bls12377 "github.com/consensys/gnark-crypto/ecc/bls12-377" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core" +) + +// See 'r' = https://eprint.iacr.org/2018/962.pdf Figure 16 +var ( + bls12377modulus = bhex("12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001") + g1Inf = bls12377.G1Affine{X: [6]uint64{}, Y: [6]uint64{}} + g2Inf = bls12377.G2Affine{ + X: bls12377.E2{A0: [6]uint64{}, A1: [6]uint64{}}, + Y: bls12377.E2{A0: [6]uint64{}, A1: [6]uint64{}}, + } +) + +type ScalarBls12377 struct { + value *big.Int + point Point +} + +type PointBls12377G1 struct { + value *bls12377.G1Affine +} + +type PointBls12377G2 struct { + value *bls12377.G2Affine +} + +type ScalarBls12377Gt struct { + value *bls12377.GT +} + +func (s *ScalarBls12377) Random(reader io.Reader) Scalar { + if reader == nil { + return nil + } + var seed [64]byte + _, _ = reader.Read(seed[:]) + return s.Hash(seed[:]) +} + +func (s *ScalarBls12377) Hash(bytes []byte) Scalar { + xmd, err := expandMsgXmd(sha256.New(), bytes, []byte("BLS12377_XMD:SHA-256_SSWU_RO_"), 48) + if err != nil { + return nil + } + v := new(big.Int).SetBytes(xmd) + return &ScalarBls12377{ + value: v.Mod(v, bls12377modulus), + point: s.point, + } +} + +func (s *ScalarBls12377) Zero() Scalar { + return &ScalarBls12377{ + value: big.NewInt(0), + point: s.point, + } +} + +func (s *ScalarBls12377) One() Scalar { + return &ScalarBls12377{ + value: big.NewInt(1), + point: s.point, + } +} + +func (s *ScalarBls12377) IsZero() bool { + return subtle.ConstantTimeCompare(s.value.Bytes(), []byte{}) == 1 +} + +func (s *ScalarBls12377) IsOne() bool { + return subtle.ConstantTimeCompare(s.value.Bytes(), []byte{1}) == 1 +} + +func (s *ScalarBls12377) IsOdd() bool { + return s.value.Bit(0) == 1 +} + +func (s *ScalarBls12377) IsEven() bool { + return s.value.Bit(0) == 0 +} + +func (s *ScalarBls12377) New(value int) Scalar { + v := big.NewInt(int64(value)) + if value < 0 { + v.Mod(v, bls12377modulus) + } + return &ScalarBls12377{ + value: v, + point: s.point, + } +} + +func (s *ScalarBls12377) Cmp(rhs Scalar) int { + r, ok := rhs.(*ScalarBls12377) + if ok { + return s.value.Cmp(r.value) + } else { + return -2 + } +} + +func (s *ScalarBls12377) Square() Scalar { + return &ScalarBls12377{ + value: new(big.Int).Exp(s.value, big.NewInt(2), bls12377modulus), + point: s.point, + } +} + +func (s *ScalarBls12377) Double() Scalar { + v := new(big.Int).Add(s.value, s.value) + return &ScalarBls12377{ + value: v.Mod(v, bls12377modulus), + point: s.point, + } +} + +func (s *ScalarBls12377) Invert() (Scalar, error) { + return &ScalarBls12377{ + value: new(big.Int).ModInverse(s.value, bls12377modulus), + point: s.point, + }, nil +} + +func (s *ScalarBls12377) Sqrt() (Scalar, error) { + return &ScalarBls12377{ + value: new(big.Int).ModSqrt(s.value, bls12377modulus), + point: s.point, + }, nil +} + +func (s *ScalarBls12377) Cube() Scalar { + return &ScalarBls12377{ + value: new(big.Int).Exp(s.value, big.NewInt(3), bls12377modulus), + point: s.point, + } +} + +func (s *ScalarBls12377) Add(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12377) + if ok { + v := new(big.Int).Add(s.value, r.value) + return &ScalarBls12377{ + value: v.Mod(v, bls12377modulus), + point: s.point, + } + } else { + return nil + } +} + +func (s *ScalarBls12377) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12377) + if ok { + v := new(big.Int).Sub(s.value, r.value) + return &ScalarBls12377{ + value: v.Mod(v, bls12377modulus), + point: s.point, + } + } else { + return nil + } +} + +func (s *ScalarBls12377) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12377) + if ok { + v := new(big.Int).Mul(s.value, r.value) + return &ScalarBls12377{ + value: v.Mod(v, bls12377modulus), + point: s.point, + } + } else { + return nil + } +} + +func (s *ScalarBls12377) MulAdd(y, z Scalar) Scalar { + return s.Mul(y).Add(z) +} + +func (s *ScalarBls12377) Div(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12377) + if ok { + v := new(big.Int).ModInverse(r.value, bls12377modulus) + v.Mul(v, s.value) + return &ScalarBls12377{ + value: v.Mod(v, bls12377modulus), + point: s.point, + } + } else { + return nil + } +} + +func (s *ScalarBls12377) Neg() Scalar { + z := new(big.Int).Neg(s.value) + return &ScalarBls12377{ + value: z.Mod(z, bls12377modulus), + point: s.point, + } +} + +func (s *ScalarBls12377) SetBigInt(v *big.Int) (Scalar, error) { + if v == nil { + return nil, fmt.Errorf("invalid value") + } + t := new(big.Int).Mod(v, bls12377modulus) + if t.Cmp(v) != 0 { + return nil, fmt.Errorf("invalid value") + } + return &ScalarBls12377{ + value: t, + point: s.point, + }, nil +} + +func (s *ScalarBls12377) BigInt() *big.Int { + return new(big.Int).Set(s.value) +} + +func (s *ScalarBls12377) Bytes() []byte { + var out [32]byte + return s.value.FillBytes(out[:]) +} + +func (s *ScalarBls12377) SetBytes(bytes []byte) (Scalar, error) { + value := new(big.Int).SetBytes(bytes) + t := new(big.Int).Mod(value, bls12377modulus) + if t.Cmp(value) != 0 { + return nil, fmt.Errorf("invalid byte sequence") + } + return &ScalarBls12377{ + value: t, + point: s.point, + }, nil +} + +func (s *ScalarBls12377) SetBytesWide(bytes []byte) (Scalar, error) { + if len(bytes) < 32 || len(bytes) > 128 { + return nil, fmt.Errorf("invalid byte sequence") + } + value := new(big.Int).SetBytes(bytes) + t := new(big.Int).Mod(value, bls12377modulus) + return &ScalarBls12377{ + value: t, + point: s.point, + }, nil +} + +func (s *ScalarBls12377) Point() Point { + return s.point.Identity() +} + +func (s *ScalarBls12377) Clone() Scalar { + return &ScalarBls12377{ + value: new(big.Int).Set(s.value), + point: s.point, + } +} + +func (s *ScalarBls12377) SetPoint(p Point) PairingScalar { + return &ScalarBls12377{ + value: new(big.Int).Set(s.value), + point: p, + } +} + +func (s *ScalarBls12377) Order() *big.Int { + return bls12377modulus +} + +func (s *ScalarBls12377) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *ScalarBls12377) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarBls12377) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + s.point = ss.point + return nil +} + +func (s *ScalarBls12377) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *ScalarBls12377) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarBls12377) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + s.point = ss.point + return nil +} + +func (s *ScalarBls12377) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *ScalarBls12377) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*ScalarBls12377) + if !ok { + return fmt.Errorf("invalid type") + } + s.value = S.value + return nil +} + +func (p *PointBls12377G1) Random(reader io.Reader) Point { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *PointBls12377G1) Hash(bytes []byte) Point { + domain := []byte("BLS12377G1_XMD:SHA-256_SVDW_RO_") + pt, err := bls12377.HashToG1(bytes, domain) + if err != nil { + return nil + } + return &PointBls12377G1{value: &pt} +} + +func (p *PointBls12377G1) Identity() Point { + t := bls12377.G1Affine{} + return &PointBls12377G1{ + value: t.Set(&g1Inf), + } +} + +func (p *PointBls12377G1) Generator() Point { + t := bls12377.G1Affine{} + _, _, g1Aff, _ := bls12377.Generators() + return &PointBls12377G1{ + value: t.Set(&g1Aff), + } +} + +func (p *PointBls12377G1) IsIdentity() bool { + return p.value.IsInfinity() +} + +func (p *PointBls12377G1) IsNegative() bool { + // According to https://github.com/zcash/librustzcash/blob/6e0364cd42a2b3d2b958a54771ef51a8db79dd29/pairing/src/bls12_381/README.md#serialization + // This bit represents the sign of the `y` coordinate which is what we want + + return (p.value.Bytes()[0]>>5)&1 == 1 +} + +func (p *PointBls12377G1) IsOnCurve() bool { + return p.value.IsOnCurve() +} + +func (p *PointBls12377G1) Double() Point { + t := &bls12377.G1Jac{} + t.FromAffine(p.value) + t.DoubleAssign() + value := bls12377.G1Affine{} + return &PointBls12377G1{value.FromJacobian(t)} +} + +func (p *PointBls12377G1) Scalar() Scalar { + return &ScalarBls12377{ + value: new(big.Int), + point: new(PointBls12377G1), + } +} + +func (p *PointBls12377G1) Neg() Point { + value := &bls12377.G1Affine{} + value.Neg(p.value) + return &PointBls12377G1{value} +} + +func (p *PointBls12377G1) Add(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointBls12377G1) + if ok { + value := &bls12377.G1Affine{} + return &PointBls12377G1{value.Add(p.value, r.value)} + } else { + return nil + } +} + +func (p *PointBls12377G1) Sub(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointBls12377G1) + if ok { + value := &bls12377.G1Affine{} + return &PointBls12377G1{value.Sub(p.value, r.value)} + } else { + return nil + } +} + +func (p *PointBls12377G1) Mul(rhs Scalar) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*ScalarBls12377) + if ok { + value := &bls12377.G1Affine{} + return &PointBls12377G1{value.ScalarMultiplication(p.value, r.value)} + } else { + return nil + } +} + +func (p *PointBls12377G1) Equal(rhs Point) bool { + r, ok := rhs.(*PointBls12377G1) + if ok { + return p.value.Equal(r.value) + } else { + return false + } +} + +func (p *PointBls12377G1) Set(x, y *big.Int) (Point, error) { + if x.Cmp(core.Zero) == 0 && + y.Cmp(core.Zero) == 0 { + return p.Identity(), nil + } + var data [96]byte + x.FillBytes(data[:48]) + y.FillBytes(data[48:]) + value := &bls12377.G1Affine{} + _, err := value.SetBytes(data[:]) + if err != nil { + return nil, fmt.Errorf("invalid coordinates") + } + return &PointBls12377G1{value}, nil +} + +func (p *PointBls12377G1) ToAffineCompressed() []byte { + v := p.value.Bytes() + return v[:] +} + +func (p *PointBls12377G1) ToAffineUncompressed() []byte { + v := p.value.RawBytes() + return v[:] +} + +func (p *PointBls12377G1) FromAffineCompressed(bytes []byte) (Point, error) { + if len(bytes) != bls12377.SizeOfG1AffineCompressed { + return nil, fmt.Errorf("invalid point") + } + value := &bls12377.G1Affine{} + _, err := value.SetBytes(bytes) + if err != nil { + return nil, err + } + return &PointBls12377G1{value}, nil +} + +func (p *PointBls12377G1) FromAffineUncompressed(bytes []byte) (Point, error) { + if len(bytes) != bls12377.SizeOfG1AffineUncompressed { + return nil, fmt.Errorf("invalid point") + } + value := &bls12377.G1Affine{} + _, err := value.SetBytes(bytes) + if err != nil { + return nil, err + } + return &PointBls12377G1{value}, nil +} + +func (p *PointBls12377G1) CurveName() string { + return "BLS12377G1" +} + +func (p *PointBls12377G1) SumOfProducts(points []Point, scalars []Scalar) Point { + nScalars := make([]*big.Int, len(scalars)) + for i, sc := range scalars { + s, ok := sc.(*ScalarBls12377) + if !ok { + return nil + } + nScalars[i] = s.value + } + return sumOfProductsPippenger(points, nScalars) +} + +func (p *PointBls12377G1) OtherGroup() PairingPoint { + return new(PointBls12377G2).Identity().(PairingPoint) +} + +func (p *PointBls12377G1) Pairing(rhs PairingPoint) Scalar { + pt, ok := rhs.(*PointBls12377G2) + if !ok { + return nil + } + if !p.value.IsInSubGroup() || + !pt.value.IsInSubGroup() { + return nil + } + value := bls12377.GT{} + if p.value.IsInfinity() || pt.value.IsInfinity() { + return &ScalarBls12377Gt{&value} + } + value, err := bls12377.Pair([]bls12377.G1Affine{*p.value}, []bls12377.G2Affine{*pt.value}) + if err != nil { + return nil + } + + return &ScalarBls12377Gt{&value} +} + +func (p *PointBls12377G1) MultiPairing(points ...PairingPoint) Scalar { + return multiPairingBls12377(points...) +} + +func (p *PointBls12377G1) X() *big.Int { + b := p.value.RawBytes() + return new(big.Int).SetBytes(b[:48]) +} + +func (p *PointBls12377G1) Y() *big.Int { + b := p.value.RawBytes() + return new(big.Int).SetBytes(b[48:]) +} + +func (p *PointBls12377G1) Modulus() *big.Int { + return bls12377modulus +} + +func (p *PointBls12377G1) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *PointBls12377G1) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointBls12377G1) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointBls12377G1) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *PointBls12377G1) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointBls12377G1) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointBls12377G1) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *PointBls12377G1) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*PointBls12377G1) + if !ok { + return fmt.Errorf("invalid type") + } + p.value = P.value + return nil +} + +func (p *PointBls12377G2) Random(reader io.Reader) Point { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *PointBls12377G2) Hash(bytes []byte) Point { + domain := []byte("BLS12377G2_XMD:SHA-256_SVDW_RO_") + pt, err := bls12377.HashToG2(bytes, domain) + if err != nil { + return nil + } + return &PointBls12377G2{value: &pt} +} + +func (p *PointBls12377G2) Identity() Point { + t := bls12377.G2Affine{} + return &PointBls12377G2{ + value: t.Set(&g2Inf), + } +} + +func (p *PointBls12377G2) Generator() Point { + t := bls12377.G2Affine{} + _, _, _, g2Aff := bls12377.Generators() + return &PointBls12377G2{ + value: t.Set(&g2Aff), + } +} + +func (p *PointBls12377G2) IsIdentity() bool { + return p.value.IsInfinity() +} + +func (p *PointBls12377G2) IsNegative() bool { + // According to https://github.com/zcash/librustzcash/blob/6e0364cd42a2b3d2b958a54771ef51a8db79dd29/pairing/src/bls12_381/README.md#serialization + // This bit represents the sign of the `y` coordinate which is what we want + return (p.value.Bytes()[0]>>5)&1 == 1 +} + +func (p *PointBls12377G2) IsOnCurve() bool { + return p.value.IsOnCurve() +} + +func (p *PointBls12377G2) Double() Point { + t := &bls12377.G2Jac{} + t.FromAffine(p.value) + t.DoubleAssign() + value := bls12377.G2Affine{} + return &PointBls12377G2{value.FromJacobian(t)} +} + +func (p *PointBls12377G2) Scalar() Scalar { + return &ScalarBls12377{ + value: new(big.Int), + point: new(PointBls12377G2), + } +} + +func (p *PointBls12377G2) Neg() Point { + value := &bls12377.G2Affine{} + value.Neg(p.value) + return &PointBls12377G2{value} +} + +func (p *PointBls12377G2) Add(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointBls12377G2) + if ok { + value := &bls12377.G2Affine{} + return &PointBls12377G2{value.Add(p.value, r.value)} + } else { + return nil + } +} + +func (p *PointBls12377G2) Sub(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointBls12377G2) + if ok { + value := &bls12377.G2Affine{} + return &PointBls12377G2{value.Sub(p.value, r.value)} + } else { + return nil + } +} + +func (p *PointBls12377G2) Mul(rhs Scalar) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*ScalarBls12377) + if ok { + value := &bls12377.G2Affine{} + return &PointBls12377G2{value.ScalarMultiplication(p.value, r.value)} + } else { + return nil + } +} + +func (p *PointBls12377G2) Equal(rhs Point) bool { + r, ok := rhs.(*PointBls12377G2) + if ok { + return p.value.Equal(r.value) + } else { + return false + } +} + +func (p *PointBls12377G2) Set(x, y *big.Int) (Point, error) { + if x.Cmp(core.Zero) == 0 && + y.Cmp(core.Zero) == 0 { + return p.Identity(), nil + } + var data [192]byte + x.FillBytes(data[:96]) + y.FillBytes(data[96:]) + value := &bls12377.G2Affine{} + _, err := value.SetBytes(data[:]) + if err != nil { + return nil, fmt.Errorf("invalid coordinates") + } + return &PointBls12377G2{value}, nil +} + +func (p *PointBls12377G2) ToAffineCompressed() []byte { + v := p.value.Bytes() + return v[:] +} + +func (p *PointBls12377G2) ToAffineUncompressed() []byte { + v := p.value.RawBytes() + return v[:] +} + +func (p *PointBls12377G2) FromAffineCompressed(bytes []byte) (Point, error) { + if len(bytes) != bls12377.SizeOfG2AffineCompressed { + return nil, fmt.Errorf("invalid point") + } + value := &bls12377.G2Affine{} + _, err := value.SetBytes(bytes) + if err != nil { + return nil, err + } + return &PointBls12377G2{value}, nil +} + +func (p *PointBls12377G2) FromAffineUncompressed(bytes []byte) (Point, error) { + if len(bytes) != bls12377.SizeOfG2AffineUncompressed { + return nil, fmt.Errorf("invalid point") + } + value := &bls12377.G2Affine{} + _, err := value.SetBytes(bytes) + if err != nil { + return nil, err + } + return &PointBls12377G2{value}, nil +} + +func (p *PointBls12377G2) CurveName() string { + return "BLS12377G2" +} + +func (p *PointBls12377G2) SumOfProducts(points []Point, scalars []Scalar) Point { + nScalars := make([]*big.Int, len(scalars)) + for i, sc := range scalars { + s, ok := sc.(*ScalarBls12377) + if !ok { + return nil + } + nScalars[i] = s.value + } + return sumOfProductsPippenger(points, nScalars) +} + +func (p *PointBls12377G2) OtherGroup() PairingPoint { + return new(PointBls12377G1).Identity().(PairingPoint) +} + +func (p *PointBls12377G2) Pairing(rhs PairingPoint) Scalar { + pt, ok := rhs.(*PointBls12377G1) + if !ok { + return nil + } + if !p.value.IsInSubGroup() || + !pt.value.IsInSubGroup() { + return nil + } + value := bls12377.GT{} + if p.value.IsInfinity() || pt.value.IsInfinity() { + return &ScalarBls12377Gt{&value} + } + value, err := bls12377.Pair([]bls12377.G1Affine{*pt.value}, []bls12377.G2Affine{*p.value}) + if err != nil { + return nil + } + + return &ScalarBls12377Gt{&value} +} + +func (p *PointBls12377G2) MultiPairing(points ...PairingPoint) Scalar { + return multiPairingBls12377(points...) +} + +func (p *PointBls12377G2) X() *big.Int { + b := p.value.RawBytes() + return new(big.Int).SetBytes(b[:96]) +} + +func (p *PointBls12377G2) Y() *big.Int { + b := p.value.RawBytes() + return new(big.Int).SetBytes(b[96:]) +} + +func (p *PointBls12377G2) Modulus() *big.Int { + return bls12377modulus +} + +func (p *PointBls12377G2) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *PointBls12377G2) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointBls12377G2) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointBls12377G2) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *PointBls12377G2) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointBls12377G2) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointBls12377G2) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *PointBls12377G2) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*PointBls12377G2) + if !ok { + return fmt.Errorf("invalid type") + } + p.value = P.value + return nil +} + +func multiPairingBls12377(points ...PairingPoint) Scalar { + if len(points)%2 != 0 { + return nil + } + g1Arr := make([]bls12377.G1Affine, 0, len(points)/2) + g2Arr := make([]bls12377.G2Affine, 0, len(points)/2) + valid := true + for i := 0; i < len(points); i += 2 { + pt1, ok := points[i].(*PointBls12377G1) + valid = valid && ok + pt2, ok := points[i+1].(*PointBls12377G2) + valid = valid && ok + if valid { + valid = valid && pt1.value.IsInSubGroup() + valid = valid && pt2.value.IsInSubGroup() + } + if valid { + g1Arr = append(g1Arr, *pt1.value) + g2Arr = append(g2Arr, *pt2.value) + } + } + if !valid { + return nil + } + + value, err := bls12377.Pair(g1Arr, g2Arr) + if err != nil { + return nil + } + + return &ScalarBls12377Gt{&value} +} + +func (s *ScalarBls12377Gt) Random(reader io.Reader) Scalar { + const width = 48 + offset := 0 + var data [bls12377.SizeOfGT]byte + for i := 0; i < 12; i++ { + tv, err := rand.Int(reader, bls12377modulus) + if err != nil { + return nil + } + tv.FillBytes(data[offset*width : (offset+1)*width]) + offset++ + } + value := bls12377.GT{} + err := value.SetBytes(data[:]) + if err != nil { + return nil + } + return &ScalarBls12377Gt{&value} +} + +func (s *ScalarBls12377Gt) Hash(bytes []byte) Scalar { + reader := sha3.NewShake256() + n, err := reader.Write(bytes) + if err != nil { + return nil + } + if n != len(bytes) { + return nil + } + return s.Random(reader) +} + +func (s *ScalarBls12377Gt) Zero() Scalar { + var t [bls12377.SizeOfGT]byte + value := bls12377.GT{} + err := value.SetBytes(t[:]) + if err != nil { + return nil + } + return &ScalarBls12377Gt{&value} +} + +func (s *ScalarBls12377Gt) One() Scalar { + value := bls12377.GT{} + return &ScalarBls12377Gt{value.SetOne()} +} + +func (s *ScalarBls12377Gt) IsZero() bool { + r := byte(0) + b := s.value.Bytes() + for _, i := range b { + r |= i + } + return r == 0 +} + +func (s *ScalarBls12377Gt) IsOne() bool { + o := bls12377.GT{} + return s.value.Equal(o.SetOne()) +} + +func (s *ScalarBls12377Gt) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *ScalarBls12377Gt) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarBls12377Gt) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarBls12377Gt) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *ScalarBls12377Gt) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarBls12377Gt) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarBls12377Gt) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *ScalarBls12377Gt) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*ScalarBls12377Gt) + if !ok { + return fmt.Errorf("invalid type") + } + s.value = S.value + return nil +} + +func (s *ScalarBls12377Gt) IsOdd() bool { + data := s.value.Bytes() + return data[len(data)-1]&1 == 1 +} + +func (s *ScalarBls12377Gt) IsEven() bool { + data := s.value.Bytes() + return data[len(data)-1]&1 == 0 +} + +func (s *ScalarBls12377Gt) New(input int) Scalar { + var data [576]byte + data[3] = byte(input >> 24 & 0xFF) + data[2] = byte(input >> 16 & 0xFF) + data[1] = byte(input >> 8 & 0xFF) + data[0] = byte(input & 0xFF) + + value := bls12377.GT{} + err := value.SetBytes(data[:]) + if err != nil { + return nil + } + return &ScalarBls12377Gt{&value} +} + +func (s *ScalarBls12377Gt) Cmp(rhs Scalar) int { + r, ok := rhs.(*ScalarBls12377Gt) + if ok && s.value.Equal(r.value) { + return 0 + } else { + return -2 + } +} + +func (s *ScalarBls12377Gt) Square() Scalar { + value := bls12377.GT{} + return &ScalarBls12377Gt{ + value.Square(s.value), + } +} + +func (s *ScalarBls12377Gt) Double() Scalar { + value := &bls12377.GT{} + return &ScalarBls12377Gt{ + value.Add(s.value, s.value), + } +} + +func (s *ScalarBls12377Gt) Invert() (Scalar, error) { + value := &bls12377.GT{} + return &ScalarBls12377Gt{ + value.Inverse(s.value), + }, nil +} + +func (s *ScalarBls12377Gt) Sqrt() (Scalar, error) { + // Not implemented + return nil, nil +} + +func (s *ScalarBls12377Gt) Cube() Scalar { + value := &bls12377.GT{} + value.Square(s.value) + value.Mul(value, s.value) + return &ScalarBls12377Gt{ + value, + } +} + +func (s *ScalarBls12377Gt) Add(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12377Gt) + if ok { + value := &bls12377.GT{} + return &ScalarBls12377Gt{ + value.Add(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarBls12377Gt) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12377Gt) + if ok { + value := &bls12377.GT{} + return &ScalarBls12377Gt{ + value.Sub(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarBls12377Gt) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12377Gt) + if ok { + value := &bls12377.GT{} + return &ScalarBls12377Gt{ + value.Mul(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarBls12377Gt) MulAdd(y, z Scalar) Scalar { + return s.Mul(y).Add(z) +} + +func (s *ScalarBls12377Gt) Div(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12377Gt) + if ok { + value := &bls12377.GT{} + value.Inverse(r.value) + value.Mul(value, s.value) + return &ScalarBls12377Gt{ + value, + } + } else { + return nil + } +} + +func (s *ScalarBls12377Gt) Neg() Scalar { + sValue := &bls12377.GT{} + sValue.SetOne() + value := &bls12377.GT{} + value.SetOne() + value.Sub(value, sValue) + return &ScalarBls12377Gt{ + value.Sub(value, s.value), + } +} + +func (s *ScalarBls12377Gt) SetBigInt(v *big.Int) (Scalar, error) { + var bytes [576]byte + v.FillBytes(bytes[:]) + return s.SetBytes(bytes[:]) +} + +func (s *ScalarBls12377Gt) BigInt() *big.Int { + b := s.value.Bytes() + return new(big.Int).SetBytes(b[:]) +} + +func (s *ScalarBls12377Gt) Point() Point { + p := &PointBls12377G1{} + return p.Identity() +} + +func (s *ScalarBls12377Gt) Bytes() []byte { + b := s.value.Bytes() + return b[:] +} + +func (s *ScalarBls12377Gt) SetBytes(bytes []byte) (Scalar, error) { + value := &bls12377.GT{} + err := value.SetBytes(bytes) + if err != nil { + return nil, err + } + return &ScalarBls12377Gt{value}, nil +} + +func (s *ScalarBls12377Gt) SetBytesWide(bytes []byte) (Scalar, error) { + l := len(bytes) + if l != 1152 { + return nil, fmt.Errorf("invalid byte sequence") + } + value := &bls12377.GT{} + err := value.SetBytes(bytes[:l/2]) + if err != nil { + return nil, err + } + value2 := &bls12377.GT{} + err = value2.SetBytes(bytes[l/2:]) + if err != nil { + return nil, err + } + value.Add(value, value2) + return &ScalarBls12377Gt{value}, nil +} + +func (s *ScalarBls12377Gt) Clone() Scalar { + value := &bls12377.GT{} + return &ScalarBls12377Gt{ + value.Set(s.value), + } +} diff --git a/pkg/crypto/core/curves/bls12381_curve.go b/pkg/crypto/core/curves/bls12381_curve.go new file mode 100755 index 000000000..71b270fb1 --- /dev/null +++ b/pkg/crypto/core/curves/bls12381_curve.go @@ -0,0 +1,1129 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "fmt" + "io" + "math/big" + + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var bls12381modulus = bhex("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab") + +type ScalarBls12381 struct { + Value *native.Field + point Point +} + +type PointBls12381G1 struct { + Value *bls12381.G1 +} + +type PointBls12381G2 struct { + Value *bls12381.G2 +} + +type ScalarBls12381Gt struct { + Value *bls12381.Gt +} + +func (s *ScalarBls12381) Random(reader io.Reader) Scalar { + if reader == nil { + return nil + } + var seed [64]byte + _, _ = reader.Read(seed[:]) + return s.Hash(seed[:]) +} + +func (s *ScalarBls12381) Hash(bytes []byte) Scalar { + dst := []byte("BLS12381_XMD:SHA-256_SSWU_RO_") + xmd := native.ExpandMsgXmd(native.EllipticPointHasherSha256(), bytes, dst, 48) + var t [64]byte + copy(t[:48], internal.ReverseScalarBytes(xmd)) + + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().SetBytesWide(&t), + point: s.point, + } +} + +func (s *ScalarBls12381) Zero() Scalar { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().SetZero(), + point: s.point, + } +} + +func (s *ScalarBls12381) One() Scalar { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().SetOne(), + point: s.point, + } +} + +func (s *ScalarBls12381) IsZero() bool { + return s.Value.IsZero() == 1 +} + +func (s *ScalarBls12381) IsOne() bool { + return s.Value.IsOne() == 1 +} + +func (s *ScalarBls12381) IsOdd() bool { + bytes := s.Value.Bytes() + return bytes[0]&1 == 1 +} + +func (s *ScalarBls12381) IsEven() bool { + bytes := s.Value.Bytes() + return bytes[0]&1 == 0 +} + +func (s *ScalarBls12381) New(value int) Scalar { + t := bls12381.Bls12381FqNew() + v := big.NewInt(int64(value)) + if value < 0 { + v.Mod(v, t.Params.BiModulus) + } + return &ScalarBls12381{ + Value: t.SetBigInt(v), + point: s.point, + } +} + +func (s *ScalarBls12381) Cmp(rhs Scalar) int { + r, ok := rhs.(*ScalarBls12381) + if ok { + return s.Value.Cmp(r.Value) + } else { + return -2 + } +} + +func (s *ScalarBls12381) Square() Scalar { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().Square(s.Value), + point: s.point, + } +} + +func (s *ScalarBls12381) Double() Scalar { + v := bls12381.Bls12381FqNew().Double(s.Value) + return &ScalarBls12381{ + Value: v, + point: s.point, + } +} + +func (s *ScalarBls12381) Invert() (Scalar, error) { + value, wasInverted := bls12381.Bls12381FqNew().Invert(s.Value) + if !wasInverted { + return nil, fmt.Errorf("inverse doesn't exist") + } + return &ScalarBls12381{ + Value: value, + point: s.point, + }, nil +} + +func (s *ScalarBls12381) Sqrt() (Scalar, error) { + value, wasSquare := bls12381.Bls12381FqNew().Sqrt(s.Value) + if !wasSquare { + return nil, fmt.Errorf("not a square") + } + return &ScalarBls12381{ + Value: value, + point: s.point, + }, nil +} + +func (s *ScalarBls12381) Cube() Scalar { + value := bls12381.Bls12381FqNew().Square(s.Value) + value.Mul(value, s.Value) + return &ScalarBls12381{ + Value: value, + point: s.point, + } +} + +func (s *ScalarBls12381) Add(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12381) + if ok { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().Add(s.Value, r.Value), + point: s.point, + } + } else { + return nil + } +} + +func (s *ScalarBls12381) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12381) + if ok { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().Sub(s.Value, r.Value), + point: s.point, + } + } else { + return nil + } +} + +func (s *ScalarBls12381) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12381) + if ok { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().Mul(s.Value, r.Value), + point: s.point, + } + } else { + return nil + } +} + +func (s *ScalarBls12381) MulAdd(y, z Scalar) Scalar { + return s.Mul(y).Add(z) +} + +func (s *ScalarBls12381) Div(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12381) + if ok { + v, wasInverted := bls12381.Bls12381FqNew().Invert(r.Value) + if !wasInverted { + return nil + } + v.Mul(v, s.Value) + return &ScalarBls12381{ + Value: v, + point: s.point, + } + } else { + return nil + } +} + +func (s *ScalarBls12381) Neg() Scalar { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().Neg(s.Value), + point: s.point, + } +} + +func (s *ScalarBls12381) SetBigInt(v *big.Int) (Scalar, error) { + if v == nil { + return nil, fmt.Errorf("invalid value") + } + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().SetBigInt(v), + point: s.point, + }, nil +} + +func (s *ScalarBls12381) BigInt() *big.Int { + return s.Value.BigInt() +} + +func (s *ScalarBls12381) Bytes() []byte { + t := s.Value.Bytes() + return internal.ReverseScalarBytes(t[:]) +} + +func (s *ScalarBls12381) SetBytes(bytes []byte) (Scalar, error) { + if len(bytes) != 32 { + return nil, fmt.Errorf("invalid length") + } + var seq [32]byte + copy(seq[:], internal.ReverseScalarBytes(bytes)) + value, err := bls12381.Bls12381FqNew().SetBytes(&seq) + if err != nil { + return nil, err + } + return &ScalarBls12381{ + value, s.point, + }, nil +} + +func (s *ScalarBls12381) SetBytesWide(bytes []byte) (Scalar, error) { + if len(bytes) != 64 { + return nil, fmt.Errorf("invalid length") + } + var seq [64]byte + copy(seq[:], bytes) + return &ScalarBls12381{ + bls12381.Bls12381FqNew().SetBytesWide(&seq), s.point, + }, nil +} + +func (s *ScalarBls12381) Point() Point { + return s.point.Identity() +} + +func (s *ScalarBls12381) Clone() Scalar { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().Set(s.Value), + point: s.point, + } +} + +func (s *ScalarBls12381) SetPoint(p Point) PairingScalar { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew().Set(s.Value), + point: p, + } +} + +func (s *ScalarBls12381) Order() *big.Int { + return s.Value.Params.BiModulus +} + +func (s *ScalarBls12381) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *ScalarBls12381) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarBls12381) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.Value = ss.Value + s.point = ss.point + return nil +} + +func (s *ScalarBls12381) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *ScalarBls12381) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarBls12381) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.Value = ss.Value + s.point = ss.point + return nil +} + +func (s *ScalarBls12381) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *ScalarBls12381) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*ScalarBls12381) + if !ok { + return fmt.Errorf("invalid type") + } + s.Value = S.Value + return nil +} + +func (p *PointBls12381G1) Random(reader io.Reader) Point { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *PointBls12381G1) Hash(bytes []byte) Point { + domain := []byte("BLS12381G1_XMD:SHA-256_SSWU_RO_") + pt := new(bls12381.G1).Hash(native.EllipticPointHasherSha256(), bytes, domain) + return &PointBls12381G1{Value: pt} +} + +func (p *PointBls12381G1) Identity() Point { + return &PointBls12381G1{ + Value: new(bls12381.G1).Identity(), + } +} + +func (p *PointBls12381G1) Generator() Point { + return &PointBls12381G1{ + Value: new(bls12381.G1).Generator(), + } +} + +func (p *PointBls12381G1) IsIdentity() bool { + return p.Value.IsIdentity() == 1 +} + +func (p *PointBls12381G1) IsNegative() bool { + // According to https://github.com/zcash/librustzcash/blob/6e0364cd42a2b3d2b958a54771ef51a8db79dd29/pairing/src/bls12_381/README.md#serialization + // This bit represents the sign of the `y` coordinate which is what we want + return (p.Value.ToCompressed()[0]>>5)&1 == 1 +} + +func (p *PointBls12381G1) IsOnCurve() bool { + return p.Value.IsOnCurve() == 1 +} + +func (p *PointBls12381G1) Double() Point { + return &PointBls12381G1{new(bls12381.G1).Double(p.Value)} +} + +func (p *PointBls12381G1) Scalar() Scalar { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew(), + point: new(PointBls12381G1), + } +} + +func (p *PointBls12381G1) Neg() Point { + return &PointBls12381G1{new(bls12381.G1).Neg(p.Value)} +} + +func (p *PointBls12381G1) Add(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointBls12381G1) + if ok { + return &PointBls12381G1{new(bls12381.G1).Add(p.Value, r.Value)} + } else { + return nil + } +} + +func (p *PointBls12381G1) Sub(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointBls12381G1) + if ok { + return &PointBls12381G1{new(bls12381.G1).Sub(p.Value, r.Value)} + } else { + return nil + } +} + +func (p *PointBls12381G1) Mul(rhs Scalar) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*ScalarBls12381) + if ok { + return &PointBls12381G1{new(bls12381.G1).Mul(p.Value, r.Value)} + } else { + return nil + } +} + +func (p *PointBls12381G1) Equal(rhs Point) bool { + r, ok := rhs.(*PointBls12381G1) + if ok { + return p.Value.Equal(r.Value) == 1 + } else { + return false + } +} + +func (p *PointBls12381G1) Set(x, y *big.Int) (Point, error) { + value, err := new(bls12381.G1).SetBigInt(x, y) + if err != nil { + return nil, fmt.Errorf("invalid coordinates") + } + return &PointBls12381G1{value}, nil +} + +func (p *PointBls12381G1) ToAffineCompressed() []byte { + out := p.Value.ToCompressed() + return out[:] +} + +func (p *PointBls12381G1) ToAffineUncompressed() []byte { + out := p.Value.ToUncompressed() + return out[:] +} + +func (p *PointBls12381G1) FromAffineCompressed(bytes []byte) (Point, error) { + var b [bls12381.FieldBytes]byte + copy(b[:], bytes) + value, err := new(bls12381.G1).FromCompressed(&b) + if err != nil { + return nil, err + } + return &PointBls12381G1{value}, nil +} + +func (p *PointBls12381G1) FromAffineUncompressed(bytes []byte) (Point, error) { + var b [96]byte + copy(b[:], bytes) + value, err := new(bls12381.G1).FromUncompressed(&b) + if err != nil { + return nil, err + } + return &PointBls12381G1{value}, nil +} + +func (p *PointBls12381G1) CurveName() string { + return "BLS12381G1" +} + +func (p *PointBls12381G1) SumOfProducts(points []Point, scalars []Scalar) Point { + nPoints := make([]*bls12381.G1, len(points)) + nScalars := make([]*native.Field, len(scalars)) + for i, pt := range points { + pp, ok := pt.(*PointBls12381G1) + if !ok { + return nil + } + nPoints[i] = pp.Value + } + for i, sc := range scalars { + s, ok := sc.(*ScalarBls12381) + if !ok { + return nil + } + nScalars[i] = s.Value + } + value, err := new(bls12381.G1).SumOfProducts(nPoints, nScalars) + if err != nil { + return nil + } + return &PointBls12381G1{value} +} + +func (p *PointBls12381G1) OtherGroup() PairingPoint { + return new(PointBls12381G2).Identity().(PairingPoint) +} + +func (p *PointBls12381G1) Pairing(rhs PairingPoint) Scalar { + pt, ok := rhs.(*PointBls12381G2) + if !ok { + return nil + } + e := new(bls12381.Engine) + e.AddPair(p.Value, pt.Value) + + value := e.Result() + + return &ScalarBls12381Gt{value} +} + +func (p *PointBls12381G1) MultiPairing(points ...PairingPoint) Scalar { + return multiPairing(points...) +} + +func (p *PointBls12381G1) X() *big.Int { + return p.Value.GetX().BigInt() +} + +func (p *PointBls12381G1) Y() *big.Int { + return p.Value.GetY().BigInt() +} + +func (p *PointBls12381G1) Modulus() *big.Int { + return bls12381modulus +} + +func (p *PointBls12381G1) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *PointBls12381G1) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointBls12381G1) + if !ok { + return fmt.Errorf("invalid point") + } + p.Value = ppt.Value + return nil +} + +func (p *PointBls12381G1) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *PointBls12381G1) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointBls12381G1) + if !ok { + return fmt.Errorf("invalid point") + } + p.Value = ppt.Value + return nil +} + +func (p *PointBls12381G1) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *PointBls12381G1) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*PointBls12381G1) + if !ok { + return fmt.Errorf("invalid type") + } + p.Value = P.Value + return nil +} + +func (p *PointBls12381G2) Random(reader io.Reader) Point { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *PointBls12381G2) Hash(bytes []byte) Point { + domain := []byte("BLS12381G2_XMD:SHA-256_SSWU_RO_") + pt := new(bls12381.G2).Hash(native.EllipticPointHasherSha256(), bytes, domain) + return &PointBls12381G2{Value: pt} +} + +func (p *PointBls12381G2) Identity() Point { + return &PointBls12381G2{ + Value: new(bls12381.G2).Identity(), + } +} + +func (p *PointBls12381G2) Generator() Point { + return &PointBls12381G2{ + Value: new(bls12381.G2).Generator(), + } +} + +func (p *PointBls12381G2) IsIdentity() bool { + return p.Value.IsIdentity() == 1 +} + +func (p *PointBls12381G2) IsNegative() bool { + // According to https://github.com/zcash/librustzcash/blob/6e0364cd42a2b3d2b958a54771ef51a8db79dd29/pairing/src/bls12_381/README.md#serialization + // This bit represents the sign of the `y` coordinate which is what we want + return (p.Value.ToCompressed()[0]>>5)&1 == 1 +} + +func (p *PointBls12381G2) IsOnCurve() bool { + return p.Value.IsOnCurve() == 1 +} + +func (p *PointBls12381G2) Double() Point { + return &PointBls12381G2{new(bls12381.G2).Double(p.Value)} +} + +func (p *PointBls12381G2) Scalar() Scalar { + return &ScalarBls12381{ + Value: bls12381.Bls12381FqNew(), + point: new(PointBls12381G2), + } +} + +func (p *PointBls12381G2) Neg() Point { + return &PointBls12381G2{new(bls12381.G2).Neg(p.Value)} +} + +func (p *PointBls12381G2) Add(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointBls12381G2) + if ok { + return &PointBls12381G2{new(bls12381.G2).Add(p.Value, r.Value)} + } else { + return nil + } +} + +func (p *PointBls12381G2) Sub(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointBls12381G2) + if ok { + return &PointBls12381G2{new(bls12381.G2).Sub(p.Value, r.Value)} + } else { + return nil + } +} + +func (p *PointBls12381G2) Mul(rhs Scalar) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*ScalarBls12381) + if ok { + return &PointBls12381G2{new(bls12381.G2).Mul(p.Value, r.Value)} + } else { + return nil + } +} + +func (p *PointBls12381G2) Equal(rhs Point) bool { + r, ok := rhs.(*PointBls12381G2) + if ok { + return p.Value.Equal(r.Value) == 1 + } else { + return false + } +} + +func (p *PointBls12381G2) Set(x, y *big.Int) (Point, error) { + value, err := new(bls12381.G2).SetBigInt(x, y) + if err != nil { + return nil, fmt.Errorf("invalid coordinates") + } + return &PointBls12381G2{value}, nil +} + +func (p *PointBls12381G2) ToAffineCompressed() []byte { + out := p.Value.ToCompressed() + return out[:] +} + +func (p *PointBls12381G2) ToAffineUncompressed() []byte { + out := p.Value.ToUncompressed() + return out[:] +} + +func (p *PointBls12381G2) FromAffineCompressed(bytes []byte) (Point, error) { + var b [bls12381.WideFieldBytes]byte + copy(b[:], bytes) + value, err := new(bls12381.G2).FromCompressed(&b) + if err != nil { + return nil, err + } + return &PointBls12381G2{value}, nil +} + +func (p *PointBls12381G2) FromAffineUncompressed(bytes []byte) (Point, error) { + var b [bls12381.DoubleWideFieldBytes]byte + copy(b[:], bytes) + value, err := new(bls12381.G2).FromUncompressed(&b) + if err != nil { + return nil, err + } + return &PointBls12381G2{value}, nil +} + +func (p *PointBls12381G2) CurveName() string { + return "BLS12381G2" +} + +func (p *PointBls12381G2) SumOfProducts(points []Point, scalars []Scalar) Point { + nPoints := make([]*bls12381.G2, len(points)) + nScalars := make([]*native.Field, len(scalars)) + for i, pt := range points { + pp, ok := pt.(*PointBls12381G2) + if !ok { + return nil + } + nPoints[i] = pp.Value + } + for i, sc := range scalars { + s, ok := sc.(*ScalarBls12381) + if !ok { + return nil + } + nScalars[i] = s.Value + } + value, err := new(bls12381.G2).SumOfProducts(nPoints, nScalars) + if err != nil { + return nil + } + return &PointBls12381G2{value} +} + +func (p *PointBls12381G2) OtherGroup() PairingPoint { + return new(PointBls12381G1).Identity().(PairingPoint) +} + +func (p *PointBls12381G2) Pairing(rhs PairingPoint) Scalar { + pt, ok := rhs.(*PointBls12381G1) + if !ok { + return nil + } + e := new(bls12381.Engine) + e.AddPair(pt.Value, p.Value) + + value := e.Result() + + return &ScalarBls12381Gt{value} +} + +func (p *PointBls12381G2) MultiPairing(points ...PairingPoint) Scalar { + return multiPairing(points...) +} + +func (p *PointBls12381G2) X() *big.Int { + x := p.Value.ToUncompressed() + return new(big.Int).SetBytes(x[:bls12381.WideFieldBytes]) +} + +func (p *PointBls12381G2) Y() *big.Int { + y := p.Value.ToUncompressed() + return new(big.Int).SetBytes(y[bls12381.WideFieldBytes:]) +} + +func (p *PointBls12381G2) Modulus() *big.Int { + return bls12381modulus +} + +func (p *PointBls12381G2) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *PointBls12381G2) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointBls12381G2) + if !ok { + return fmt.Errorf("invalid point") + } + p.Value = ppt.Value + return nil +} + +func (p *PointBls12381G2) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *PointBls12381G2) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointBls12381G2) + if !ok { + return fmt.Errorf("invalid point") + } + p.Value = ppt.Value + return nil +} + +func (p *PointBls12381G2) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *PointBls12381G2) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*PointBls12381G2) + if !ok { + return fmt.Errorf("invalid type") + } + p.Value = P.Value + return nil +} + +func multiPairing(points ...PairingPoint) Scalar { + if len(points)%2 != 0 { + return nil + } + valid := true + eng := new(bls12381.Engine) + for i := 0; i < len(points); i += 2 { + pt1, ok := points[i].(*PointBls12381G1) + valid = valid && ok + pt2, ok := points[i+1].(*PointBls12381G2) + valid = valid && ok + if valid { + eng.AddPair(pt1.Value, pt2.Value) + } + } + if !valid { + return nil + } + + value := eng.Result() + return &ScalarBls12381Gt{value} +} + +func (s *ScalarBls12381Gt) Random(reader io.Reader) Scalar { + value, err := new(bls12381.Gt).Random(reader) + if err != nil { + return nil + } + return &ScalarBls12381Gt{value} +} + +func (s *ScalarBls12381Gt) Hash(bytes []byte) Scalar { + reader := sha3.NewShake256() + n, err := reader.Write(bytes) + if err != nil { + return nil + } + if n != len(bytes) { + return nil + } + return s.Random(reader) +} + +func (s *ScalarBls12381Gt) Zero() Scalar { + return &ScalarBls12381Gt{new(bls12381.Gt)} +} + +func (s *ScalarBls12381Gt) One() Scalar { + return &ScalarBls12381Gt{new(bls12381.Gt).SetOne()} +} + +func (s *ScalarBls12381Gt) IsZero() bool { + return s.Value.IsZero() == 1 +} + +func (s *ScalarBls12381Gt) IsOne() bool { + return s.Value.IsOne() == 1 +} + +func (s *ScalarBls12381Gt) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *ScalarBls12381Gt) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarBls12381Gt) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.Value = ss.Value + return nil +} + +func (s *ScalarBls12381Gt) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *ScalarBls12381Gt) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarBls12381Gt) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.Value = ss.Value + return nil +} + +func (s *ScalarBls12381Gt) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *ScalarBls12381Gt) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*ScalarBls12381Gt) + if !ok { + return fmt.Errorf("invalid type") + } + s.Value = S.Value + return nil +} + +func (s *ScalarBls12381Gt) IsOdd() bool { + data := s.Value.Bytes() + return data[0]&1 == 1 +} + +func (s *ScalarBls12381Gt) IsEven() bool { + data := s.Value.Bytes() + return data[0]&1 == 0 +} + +func (s *ScalarBls12381Gt) New(input int) Scalar { + var data [bls12381.GtFieldBytes]byte + data[3] = byte(input >> 24 & 0xFF) + data[2] = byte(input >> 16 & 0xFF) + data[1] = byte(input >> 8 & 0xFF) + data[0] = byte(input & 0xFF) + + value, isCanonical := new(bls12381.Gt).SetBytes(&data) + if isCanonical != 1 { + return nil + } + return &ScalarBls12381Gt{value} +} + +func (s *ScalarBls12381Gt) Cmp(rhs Scalar) int { + r, ok := rhs.(*ScalarBls12381Gt) + if ok && s.Value.Equal(r.Value) == 1 { + return 0 + } else { + return -2 + } +} + +func (s *ScalarBls12381Gt) Square() Scalar { + return &ScalarBls12381Gt{ + new(bls12381.Gt).Square(s.Value), + } +} + +func (s *ScalarBls12381Gt) Double() Scalar { + return &ScalarBls12381Gt{ + new(bls12381.Gt).Double(s.Value), + } +} + +func (s *ScalarBls12381Gt) Invert() (Scalar, error) { + value, wasInverted := new(bls12381.Gt).Invert(s.Value) + if wasInverted != 1 { + return nil, fmt.Errorf("not invertible") + } + return &ScalarBls12381Gt{ + value, + }, nil +} + +func (s *ScalarBls12381Gt) Sqrt() (Scalar, error) { + // Not implemented + return nil, nil +} + +func (s *ScalarBls12381Gt) Cube() Scalar { + value := new(bls12381.Gt).Square(s.Value) + value.Add(value, s.Value) + return &ScalarBls12381Gt{ + value, + } +} + +func (s *ScalarBls12381Gt) Add(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12381Gt) + if ok { + return &ScalarBls12381Gt{ + new(bls12381.Gt).Add(s.Value, r.Value), + } + } else { + return nil + } +} + +func (s *ScalarBls12381Gt) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12381Gt) + if ok { + return &ScalarBls12381Gt{ + new(bls12381.Gt).Sub(s.Value, r.Value), + } + } else { + return nil + } +} + +func (s *ScalarBls12381Gt) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12381Gt) + if ok { + return &ScalarBls12381Gt{ + new(bls12381.Gt).Add(s.Value, r.Value), + } + } else { + return nil + } +} + +func (s *ScalarBls12381Gt) MulAdd(y, z Scalar) Scalar { + return s.Mul(y).Add(z) +} + +func (s *ScalarBls12381Gt) Div(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarBls12381Gt) + if ok { + return &ScalarBls12381Gt{ + new(bls12381.Gt).Sub(s.Value, r.Value), + } + } else { + return nil + } +} + +func (s *ScalarBls12381Gt) Neg() Scalar { + return &ScalarBls12381Gt{ + new(bls12381.Gt).Neg(s.Value), + } +} + +func (s *ScalarBls12381Gt) SetBigInt(v *big.Int) (Scalar, error) { + var bytes [bls12381.GtFieldBytes]byte + v.FillBytes(bytes[:]) + return s.SetBytes(bytes[:]) +} + +func (s *ScalarBls12381Gt) BigInt() *big.Int { + bytes := s.Value.Bytes() + return new(big.Int).SetBytes(bytes[:]) +} + +func (s *ScalarBls12381Gt) Point() Point { + return &PointBls12381G1{Value: new(bls12381.G1).Identity()} +} + +func (s *ScalarBls12381Gt) Bytes() []byte { + bytes := s.Value.Bytes() + return bytes[:] +} + +func (s *ScalarBls12381Gt) SetBytes(bytes []byte) (Scalar, error) { + var b [bls12381.GtFieldBytes]byte + copy(b[:], bytes) + ss, isCanonical := new(bls12381.Gt).SetBytes(&b) + if isCanonical == 0 { + return nil, fmt.Errorf("invalid bytes") + } + return &ScalarBls12381Gt{ss}, nil +} + +func (s *ScalarBls12381Gt) SetBytesWide(bytes []byte) (Scalar, error) { + l := len(bytes) + if l != bls12381.GtFieldBytes*2 { + return nil, fmt.Errorf("invalid byte sequence") + } + var b [bls12381.GtFieldBytes]byte + copy(b[:], bytes[:bls12381.GtFieldBytes]) + + value, isCanonical := new(bls12381.Gt).SetBytes(&b) + if isCanonical == 0 { + return nil, fmt.Errorf("invalid byte sequence") + } + copy(b[:], bytes[bls12381.GtFieldBytes:]) + value2, isCanonical := new(bls12381.Gt).SetBytes(&b) + if isCanonical == 0 { + return nil, fmt.Errorf("invalid byte sequence") + } + value.Add(value, value2) + return &ScalarBls12381Gt{value}, nil +} + +func (s *ScalarBls12381Gt) Clone() Scalar { + return &ScalarBls12381Gt{ + Value: new(bls12381.Gt).Set(s.Value), + } +} diff --git a/pkg/crypto/core/curves/curve.go b/pkg/crypto/core/curves/curve.go new file mode 100755 index 000000000..55e2f1956 --- /dev/null +++ b/pkg/crypto/core/curves/curve.go @@ -0,0 +1,863 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/elliptic" + "encoding/hex" + "encoding/json" + "fmt" + "hash" + "io" + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" +) + +var ( + k256Initonce sync.Once + k256 Curve + + bls12381g1Initonce sync.Once + bls12381g1 Curve + + bls12381g2Initonce sync.Once + bls12381g2 Curve + + bls12377g1Initonce sync.Once + bls12377g1 Curve + + bls12377g2Initonce sync.Once + bls12377g2 Curve + + p256Initonce sync.Once + p256 Curve + + ed25519Initonce sync.Once + ed25519 Curve + + pallasInitonce sync.Once + pallas Curve +) + +const ( + K256Name = "secp256k1" + BLS12381G1Name = "BLS12381G1" + BLS12381G2Name = "BLS12381G2" + BLS12831Name = "BLS12831" + P256Name = "P-256" + ED25519Name = "ed25519" + PallasName = "pallas" + BLS12377G1Name = "BLS12377G1" + BLS12377G2Name = "BLS12377G2" + BLS12377Name = "BLS12377" +) + +const scalarBytes = 32 + +// Scalar represents an element of the scalar field \mathbb{F}_q +// of the elliptic curve construction. +type Scalar interface { + // Random returns a random scalar using the provided reader + // to retrieve bytes + Random(reader io.Reader) Scalar + // Hash the specific bytes in a manner to yield a + // uniformly distributed scalar + Hash(bytes []byte) Scalar + // Zero returns the additive identity element + Zero() Scalar + // One returns the multiplicative identity element + One() Scalar + // IsZero returns true if this element is the additive identity element + IsZero() bool + // IsOne returns true if this element is the multiplicative identity element + IsOne() bool + // IsOdd returns true if this element is odd + IsOdd() bool + // IsEven returns true if this element is even + IsEven() bool + // New returns an element with the value equal to `value` + New(value int) Scalar + // Cmp returns + // -2 if this element is in a different field than rhs + // -1 if this element is less than rhs + // 0 if this element is equal to rhs + // 1 if this element is greater than rhs + Cmp(rhs Scalar) int + // Square returns element*element + Square() Scalar + // Double returns element+element + Double() Scalar + // Invert returns element^-1 mod p + Invert() (Scalar, error) + // Sqrt computes the square root of this element if it exists. + Sqrt() (Scalar, error) + // Cube returns element*element*element + Cube() Scalar + // Add returns element+rhs + Add(rhs Scalar) Scalar + // Sub returns element-rhs + Sub(rhs Scalar) Scalar + // Mul returns element*rhs + Mul(rhs Scalar) Scalar + // MulAdd returns element * y + z mod p + MulAdd(y, z Scalar) Scalar + // Div returns element*rhs^-1 mod p + Div(rhs Scalar) Scalar + // Neg returns -element mod p + Neg() Scalar + // SetBigInt returns this element set to the value of v + SetBigInt(v *big.Int) (Scalar, error) + // BigInt returns this element as a big integer + BigInt() *big.Int + // Point returns the associated point for this scalar + Point() Point + // Bytes returns the canonical byte representation of this scalar + Bytes() []byte + // SetBytes creates a scalar from the canonical representation expecting the exact number of bytes needed to represent the scalar + SetBytes(bytes []byte) (Scalar, error) + // SetBytesWide creates a scalar expecting double the exact number of bytes needed to represent the scalar which is reduced by the modulus + SetBytesWide(bytes []byte) (Scalar, error) + // Clone returns a cloned Scalar of this value + Clone() Scalar +} + +type PairingScalar interface { + Scalar + SetPoint(p Point) PairingScalar +} + +func unmarshalScalar(input []byte) (*Curve, []byte, error) { + sep := byte(':') + i := 0 + for ; i < len(input); i++ { + if input[i] == sep { + break + } + } + name := string(input[:i]) + curve := GetCurveByName(name) + if curve == nil { + return nil, nil, fmt.Errorf("unrecognized curve") + } + return curve, input[i+1:], nil +} + +func scalarMarshalBinary(scalar Scalar) ([]byte, error) { + // All scalars are 32 bytes long + // The last 32 bytes are the actual value + // The first remaining bytes are the curve name + // separated by a colon + name := []byte(scalar.Point().CurveName()) + output := make([]byte, len(name)+1+scalarBytes) + copy(output[:len(name)], name) + output[len(name)] = byte(':') + copy(output[len(name)+1:], scalar.Bytes()) + return output, nil +} + +func scalarUnmarshalBinary(input []byte) (Scalar, error) { + // All scalars are 32 bytes long + // The first 32 bytes are the actual value + // The remaining bytes are the curve name + if len(input) < scalarBytes+1+len(P256Name) { + return nil, fmt.Errorf("invalid byte sequence") + } + sc, data, err := unmarshalScalar(input) + if err != nil { + return nil, err + } + return sc.Scalar.SetBytes(data) +} + +func scalarMarshalText(scalar Scalar) ([]byte, error) { + // All scalars are 32 bytes long + // For text encoding we put the curve name first for readability + // separated by a colon, then the hex encoding of the scalar + // which avoids the base64 weakness with strict mode or not + name := []byte(scalar.Point().CurveName()) + output := make([]byte, len(name)+1+scalarBytes*2) + copy(output[:len(name)], name) + output[len(name)] = byte(':') + _ = hex.Encode(output[len(name)+1:], scalar.Bytes()) + return output, nil +} + +func scalarUnmarshalText(input []byte) (Scalar, error) { + if len(input) < scalarBytes*2+len(P256Name)+1 { + return nil, fmt.Errorf("invalid byte sequence") + } + curve, data, err := unmarshalScalar(input) + if err != nil { + return nil, err + } + var t [scalarBytes]byte + _, err = hex.Decode(t[:], data) + if err != nil { + return nil, err + } + return curve.Scalar.SetBytes(t[:]) +} + +func scalarMarshalJson(scalar Scalar) ([]byte, error) { + m := make(map[string]string, 2) + m["type"] = scalar.Point().CurveName() + m["value"] = hex.EncodeToString(scalar.Bytes()) + return json.Marshal(m) +} + +func scalarUnmarshalJson(input []byte) (Scalar, error) { + var m map[string]string + + err := json.Unmarshal(input, &m) + if err != nil { + return nil, err + } + curve := GetCurveByName(m["type"]) + if curve == nil { + return nil, fmt.Errorf("invalid type") + } + s, err := hex.DecodeString(m["value"]) + if err != nil { + return nil, err + } + S, err := curve.Scalar.SetBytes(s) + if err != nil { + return nil, err + } + return S, nil +} + +// Point represents an elliptic curve point +type Point interface { + Random(reader io.Reader) Point + Hash(bytes []byte) Point + Identity() Point + Generator() Point + IsIdentity() bool + IsNegative() bool + IsOnCurve() bool + Double() Point + Scalar() Scalar + Neg() Point + Add(rhs Point) Point + Sub(rhs Point) Point + Mul(rhs Scalar) Point + Equal(rhs Point) bool + Set(x, y *big.Int) (Point, error) + ToAffineCompressed() []byte + ToAffineUncompressed() []byte + FromAffineCompressed(bytes []byte) (Point, error) + FromAffineUncompressed(bytes []byte) (Point, error) + CurveName() string + SumOfProducts(points []Point, scalars []Scalar) Point +} + +type PairingPoint interface { + Point + OtherGroup() PairingPoint + Pairing(rhs PairingPoint) Scalar + MultiPairing(...PairingPoint) Scalar +} + +func pointMarshalBinary(point Point) ([]byte, error) { + // Always stores points in compressed form + // The first bytes are the curve name + // separated by a colon followed by the compressed point + // bytes + t := point.ToAffineCompressed() + name := []byte(point.CurveName()) + output := make([]byte, len(name)+1+len(t)) + copy(output[:len(name)], name) + output[len(name)] = byte(':') + copy(output[len(output)-len(t):], t) + return output, nil +} + +func pointUnmarshalBinary(input []byte) (Point, error) { + if len(input) < scalarBytes+1+len(P256Name) { + return nil, fmt.Errorf("invalid byte sequence") + } + sep := byte(':') + i := 0 + for ; i < len(input); i++ { + if input[i] == sep { + break + } + } + name := string(input[:i]) + curve := GetCurveByName(name) + if curve == nil { + return nil, fmt.Errorf("unrecognized curve") + } + return curve.Point.FromAffineCompressed(input[i+1:]) +} + +func pointMarshalText(point Point) ([]byte, error) { + // Always stores points in compressed form + // The first bytes are the curve name + // separated by a colon followed by the compressed point + // bytes + t := point.ToAffineCompressed() + name := []byte(point.CurveName()) + output := make([]byte, len(name)+1+len(t)*2) + copy(output[:len(name)], name) + output[len(name)] = byte(':') + hex.Encode(output[len(output)-len(t)*2:], t) + return output, nil +} + +func pointUnmarshalText(input []byte) (Point, error) { + if len(input) < scalarBytes*2+1+len(P256Name) { + return nil, fmt.Errorf("invalid byte sequence") + } + sep := byte(':') + i := 0 + for ; i < len(input); i++ { + if input[i] == sep { + break + } + } + name := string(input[:i]) + curve := GetCurveByName(name) + if curve == nil { + return nil, fmt.Errorf("unrecognized curve") + } + buffer := make([]byte, (len(input)-i)/2) + _, err := hex.Decode(buffer, input[i+1:]) + if err != nil { + return nil, err + } + return curve.Point.FromAffineCompressed(buffer) +} + +func pointMarshalJson(point Point) ([]byte, error) { + m := make(map[string]string, 2) + m["type"] = point.CurveName() + m["value"] = hex.EncodeToString(point.ToAffineCompressed()) + return json.Marshal(m) +} + +func pointUnmarshalJson(input []byte) (Point, error) { + var m map[string]string + + err := json.Unmarshal(input, &m) + if err != nil { + return nil, err + } + curve := GetCurveByName(m["type"]) + if curve == nil { + return nil, fmt.Errorf("invalid type") + } + p, err := hex.DecodeString(m["value"]) + if err != nil { + return nil, err + } + P, err := curve.Point.FromAffineCompressed(p) + if err != nil { + return nil, err + } + return P, nil +} + +// Curve represents a named elliptic curve with a scalar field and point group +type Curve struct { + Scalar Scalar + Point Point + Name string +} + +func (c Curve) ScalarBaseMult(sc Scalar) Point { + return c.Point.Generator().Mul(sc) +} + +func (c Curve) NewGeneratorPoint() Point { + return c.Point.Generator() +} + +func (c Curve) NewIdentityPoint() Point { + return c.Point.Identity() +} + +func (c Curve) NewScalar() Scalar { + return c.Scalar.Zero() +} + +// ToEllipticCurve returns the equivalent of this curve as the go interface `elliptic.Curve` +func (c Curve) ToEllipticCurve() (elliptic.Curve, error) { + err := fmt.Errorf("can't convert %s", c.Name) + switch c.Name { + case K256Name: + return K256Curve(), nil + case BLS12381G1Name: + return nil, err + case BLS12381G2Name: + return nil, err + case BLS12831Name: + return nil, err + case P256Name: + return NistP256Curve(), nil + case ED25519Name: + return nil, err + case PallasName: + return nil, err + case BLS12377G1Name: + return nil, err + case BLS12377G2Name: + return nil, err + case BLS12377Name: + return nil, err + default: + return nil, err + } +} + +// PairingCurve represents a named elliptic curve +// that supports pairings +type PairingCurve struct { + Scalar PairingScalar + PointG1 PairingPoint + PointG2 PairingPoint + GT Scalar + Name string +} + +func (c PairingCurve) ScalarG1BaseMult(sc Scalar) PairingPoint { + return c.PointG1.Generator().Mul(sc).(PairingPoint) +} + +func (c PairingCurve) ScalarG2BaseMult(sc Scalar) PairingPoint { + return c.PointG2.Generator().Mul(sc).(PairingPoint) +} + +func (c PairingCurve) NewG1GeneratorPoint() PairingPoint { + return c.PointG1.Generator().(PairingPoint) +} + +func (c PairingCurve) NewG2GeneratorPoint() PairingPoint { + return c.PointG2.Generator().(PairingPoint) +} + +func (c PairingCurve) NewG1IdentityPoint() PairingPoint { + return c.PointG1.Identity().(PairingPoint) +} + +func (c PairingCurve) NewG2IdentityPoint() PairingPoint { + return c.PointG2.Identity().(PairingPoint) +} + +func (c PairingCurve) NewScalar() PairingScalar { + return c.Scalar.Zero().(PairingScalar) +} + +// GetCurveByName returns the correct `Curve` given the name +func GetCurveByName(name string) *Curve { + switch name { + case K256Name: + return K256() + case BLS12381G1Name: + return BLS12381G1() + case BLS12381G2Name: + return BLS12381G2() + case BLS12831Name: + return BLS12381G1() + case P256Name: + return P256() + case ED25519Name: + return ED25519() + case PallasName: + return PALLAS() + case BLS12377G1Name: + return BLS12377G1() + case BLS12377G2Name: + return BLS12377G2() + case BLS12377Name: + return BLS12377G1() + default: + return nil + } +} + +func GetPairingCurveByName(name string) *PairingCurve { + switch name { + case BLS12381G1Name: + return BLS12381(BLS12381G1().NewIdentityPoint()) + case BLS12381G2Name: + return BLS12381(BLS12381G2().NewIdentityPoint()) + case BLS12831Name: + return BLS12381(BLS12381G1().NewIdentityPoint()) + default: + return nil + } +} + +// BLS12381G1 returns the BLS12-381 curve with points in G1 +func BLS12381G1() *Curve { + bls12381g1Initonce.Do(bls12381g1Init) + return &bls12381g1 +} + +func bls12381g1Init() { + bls12381g1 = Curve{ + Scalar: &ScalarBls12381{ + Value: bls12381.Bls12381FqNew(), + point: new(PointBls12381G1), + }, + Point: new(PointBls12381G1).Identity(), + Name: BLS12381G1Name, + } +} + +// BLS12381G2 returns the BLS12-381 curve with points in G2 +func BLS12381G2() *Curve { + bls12381g2Initonce.Do(bls12381g2Init) + return &bls12381g2 +} + +func bls12381g2Init() { + bls12381g2 = Curve{ + Scalar: &ScalarBls12381{ + Value: bls12381.Bls12381FqNew(), + point: new(PointBls12381G2), + }, + Point: new(PointBls12381G2).Identity(), + Name: BLS12381G2Name, + } +} + +func BLS12381(preferredPoint Point) *PairingCurve { + return &PairingCurve{ + Scalar: &ScalarBls12381{ + Value: bls12381.Bls12381FqNew(), + point: preferredPoint, + }, + PointG1: &PointBls12381G1{ + Value: new(bls12381.G1).Identity(), + }, + PointG2: &PointBls12381G2{ + Value: new(bls12381.G2).Identity(), + }, + GT: &ScalarBls12381Gt{ + Value: new(bls12381.Gt).SetOne(), + }, + Name: BLS12831Name, + } +} + +// BLS12377G1 returns the BLS12-377 curve with points in G1 +func BLS12377G1() *Curve { + bls12377g1Initonce.Do(bls12377g1Init) + return &bls12377g1 +} + +func bls12377g1Init() { + bls12377g1 = Curve{ + Scalar: &ScalarBls12377{ + value: new(big.Int), + point: new(PointBls12377G1), + }, + Point: new(PointBls12377G1).Identity(), + Name: BLS12377G1Name, + } +} + +// BLS12377G2 returns the BLS12-377 curve with points in G2 +func BLS12377G2() *Curve { + bls12377g2Initonce.Do(bls12377g2Init) + return &bls12377g2 +} + +func bls12377g2Init() { + bls12377g2 = Curve{ + Scalar: &ScalarBls12377{ + value: new(big.Int), + point: new(PointBls12377G2), + }, + Point: new(PointBls12377G2).Identity(), + Name: BLS12377G2Name, + } +} + +// K256 returns the secp256k1 curve +func K256() *Curve { + k256Initonce.Do(k256Init) + return &k256 +} + +func k256Init() { + k256 = Curve{ + Scalar: new(ScalarK256).Zero(), + Point: new(PointK256).Identity(), + Name: K256Name, + } +} + +func P256() *Curve { + p256Initonce.Do(p256Init) + return &p256 +} + +func p256Init() { + p256 = Curve{ + Scalar: new(ScalarP256).Zero(), + Point: new(PointP256).Identity(), + Name: P256Name, + } +} + +func ED25519() *Curve { + ed25519Initonce.Do(ed25519Init) + return &ed25519 +} + +func ed25519Init() { + ed25519 = Curve{ + Scalar: new(ScalarEd25519).Zero(), + Point: new(PointEd25519).Identity(), + Name: ED25519Name, + } +} + +func PALLAS() *Curve { + pallasInitonce.Do(pallasInit) + return &pallas +} + +func pallasInit() { + pallas = Curve{ + Scalar: new(ScalarPallas).Zero(), + Point: new(PointPallas).Identity(), + Name: PallasName, + } +} + +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-11#appendix-G.2.1 +func osswu3mod4(u *big.Int, p *sswuParams) (x, y *big.Int) { + params := p.Params + field := NewField(p.Params.P) + + tv1 := field.NewElement(u) + tv1 = tv1.Mul(tv1) // tv1 = u^2 + tv3 := field.NewElement(p.Z).Mul(tv1) // tv3 = Z * tv1 + tv2 := tv3.Mul(tv3) // tv2 = tv3^2 + xd := tv2.Add(tv3) // xd = tv2 + tv3 + x1n := xd.Add(field.One()) // x1n = (xd + 1) + x1n = x1n.Mul(field.NewElement(p.B)) // x1n * B + aNeg := field.NewElement(p.A).Neg() + xd = xd.Mul(aNeg) // xd = -A * xd + + if xd.Value.Cmp(big.NewInt(0)) == 0 { + xd = field.NewElement(p.Z).Mul(field.NewElement(p.A)) // xd = Z * A + } + + tv2 = xd.Mul(xd) // tv2 = xd^2 + gxd := tv2.Mul(xd) // gxd = tv2 * xd + tv2 = tv2.Mul(field.NewElement(p.A)) // tv2 = A * tv2 + + gx1 := x1n.Mul(x1n) // gx1 = x1n^2 + gx1 = gx1.Add(tv2) // gx1 = gx1 + tv2 + gx1 = gx1.Mul(x1n) // gx1 = gx1 * x1n + tv2 = gxd.Mul(field.NewElement(p.B)) // tv2 = B * gxd + gx1 = gx1.Add(tv2) // gx1 = gx1 + tv2 + + tv4 := gxd.Mul(gxd) // tv4 = gxd^2 + tv2 = gx1.Mul(gxd) // tv2 = gx1 * gxd + tv4 = tv4.Mul(tv2) // tv4 = tv4 * tv2 + + y1 := tv4.Pow(field.NewElement(p.C1)) + y1 = y1.Mul(tv2) // y1 = y1 * tv2 + x2n := tv3.Mul(x1n) // x2n = tv3 * x1n + + y2 := y1.Mul(field.NewElement(p.C2)) // y2 = y1 * c2 + y2 = y2.Mul(tv1) // y2 = y2 * tv1 + y2 = y2.Mul(field.NewElement(u)) // y2 = y2 * u + + tv2 = y1.Mul(y1) // tv2 = y1^2 + + tv2 = tv2.Mul(gxd) // tv2 = tv2 * gxd + + e2 := tv2.Value.Cmp(gx1.Value) == 0 + + // If e2, x = x1, else x = x2 + if e2 { + x = x1n.Value + } else { + x = x2n.Value + } + // xn / xd + x.Mul(x, new(big.Int).ModInverse(xd.Value, params.P)) + x.Mod(x, params.P) + + // If e2, y = y1, else y = y2 + if e2 { + y = y1.Value + } else { + y = y2.Value + } + + uBytes := u.Bytes() + yBytes := y.Bytes() + + usign := uBytes[len(uBytes)-1] & 1 + ysign := yBytes[len(yBytes)-1] & 1 + + // Fix sign of y + if usign != ysign { + y.Neg(y) + y.Mod(y, params.P) + } + + return +} + +func expandMsgXmd(h hash.Hash, msg, domain []byte, outLen int) ([]byte, error) { + domainLen := uint8(len(domain)) + if domainLen > 255 { + return nil, fmt.Errorf("invalid domain length") + } + // DST_prime = DST || I2OSP(len(DST), 1) + // b_0 = H(Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime) + _, _ = h.Write(make([]byte, h.BlockSize())) + _, _ = h.Write(msg) + _, _ = h.Write([]byte{uint8(outLen >> 8), uint8(outLen)}) + _, _ = h.Write([]byte{0}) + _, _ = h.Write(domain) + _, _ = h.Write([]byte{domainLen}) + b0 := h.Sum(nil) + + // b_1 = H(b_0 || I2OSP(1, 1) || DST_prime) + h.Reset() + _, _ = h.Write(b0) + _, _ = h.Write([]byte{1}) + _, _ = h.Write(domain) + _, _ = h.Write([]byte{domainLen}) + b1 := h.Sum(nil) + + // b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime) + ell := (outLen + h.Size() - 1) / h.Size() + bi := b1 + out := make([]byte, outLen) + for i := 1; i < ell; i++ { + h.Reset() + // b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime) + tmp := make([]byte, h.Size()) + for j := 0; j < h.Size(); j++ { + tmp[j] = b0[j] ^ bi[j] + } + _, _ = h.Write(tmp) + _, _ = h.Write([]byte{1 + uint8(i)}) + _, _ = h.Write(domain) + _, _ = h.Write([]byte{domainLen}) + + // b_1 || ... || b_(ell - 1) + copy(out[(i-1)*h.Size():i*h.Size()], bi[:]) + bi = h.Sum(nil) + } + // b_ell + copy(out[(ell-1)*h.Size():], bi[:]) + return out[:outLen], nil +} + +func bhex(s string) *big.Int { + r, _ := new(big.Int).SetString(s, 16) + return r +} + +type sswuParams struct { + Params *elliptic.CurveParams + C1, C2, A, B, Z *big.Int +} + +// sumOfProductsPippenger implements a version of Pippenger's algorithm. +// +// The algorithm works as follows: +// +// Let `n` be a number of point-scalar pairs. +// Let `w` be a window of bits (6..8, chosen based on `n`, see cost factor). +// +// 1. Prepare `2^(w-1) - 1` buckets with indices `[1..2^(w-1))` initialized with identity points. +// Bucket 0 is not needed as it would contain points multiplied by 0. +// 2. Convert scalars to a radix-`2^w` representation with signed digits in `[-2^w/2, 2^w/2]`. +// Note: only the last digit may equal `2^w/2`. +// 3. Starting with the last window, for each point `i=[0..n)` add it to a a bucket indexed by +// the point's scalar's value in the window. +// 4. Once all points in a window are sorted into buckets, add buckets by multiplying each +// by their index. Efficient way of doing it is to start with the last bucket and compute two sums: +// intermediate sum from the last to the first, and the full sum made of all intermediate sums. +// 5. Shift the resulting sum of buckets by `w` bits by using `w` doublings. +// 6. Add to the return value. +// 7. Repeat the loop. +// +// Approximate cost w/o wNAF optimizations (A = addition, D = doubling): +// +// ```ascii +// cost = (n*A + 2*(2^w/2)*A + w*D + A)*256/w +// +// | | | | | +// | | | | looping over 256/w windows +// | | | adding to the result +// sorting points | shifting the sum by w bits (to the next window, starting from last window) +// one by one | +// into buckets adding/subtracting all buckets +// multiplied by their indexes +// using a sum of intermediate sums +// +// ``` +// +// For large `n`, dominant factor is (n*256/w) additions. +// However, if `w` is too big and `n` is not too big, then `(2^w/2)*A` could dominate. +// Therefore, the optimal choice of `w` grows slowly as `n` grows. +// +// # For constant time we use a fixed window of 6 +// +// This algorithm is adapted from section 4 of . +// and https://cacr.uwaterloo.ca/techreports/2010/cacr2010-26.pdf +func sumOfProductsPippenger(points []Point, scalars []*big.Int) Point { + if len(points) != len(scalars) { + return nil + } + + const w = 6 + + bucketSize := (1 << w) - 1 + windows := make([]Point, 255/w+1) + for i := range windows { + windows[i] = points[0].Identity() + } + bucket := make([]Point, bucketSize) + + for j := 0; j < len(windows); j++ { + for i := 0; i < bucketSize; i++ { + bucket[i] = points[0].Identity() + } + + for i := 0; i < len(scalars); i++ { + index := bucketSize & int(new(big.Int).Rsh(scalars[i], uint(w*j)).Int64()) + if index != 0 { + bucket[index-1] = bucket[index-1].Add(points[i]) + } + } + + acc, sum := windows[j].Identity(), windows[j].Identity() + + for i := bucketSize - 1; i >= 0; i-- { + sum = sum.Add(bucket[i]) + acc = acc.Add(sum) + } + windows[j] = acc + } + + acc := windows[0].Identity() + for i := len(windows) - 1; i >= 0; i-- { + for j := 0; j < w; j++ { + acc = acc.Double() + } + acc = acc.Add(windows[i]) + } + return acc +} diff --git a/pkg/crypto/core/curves/ec_point.go b/pkg/crypto/core/curves/ec_point.go new file mode 100755 index 000000000..12ec61e1c --- /dev/null +++ b/pkg/crypto/core/curves/ec_point.go @@ -0,0 +1,251 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/elliptic" + "encoding/json" + "fmt" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/core" + + "github.com/dustinxie/ecc" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var curveNameToID = map[string]byte{ + "secp256k1": 0, + "P-224": 1, + "P-256": 2, + "P-384": 3, + "P-521": 4, +} + +var curveIDToName = map[byte]func() elliptic.Curve{ + 0: ecc.P256k1, + 1: elliptic.P224, + 2: elliptic.P256, + 3: elliptic.P384, + 4: elliptic.P521, +} + +var curveMapper = map[string]func() elliptic.Curve{ + "secp256k1": ecc.P256k1, + "P-224": elliptic.P224, + "P-256": elliptic.P256, + "P-384": elliptic.P384, + "P-521": elliptic.P521, +} + +// EcPoint represents an elliptic curve Point +type EcPoint struct { + Curve elliptic.Curve + X, Y *big.Int +} + +// EcPointJSON encapsulates the data that is serialized to JSON +// used internally and not for external use. Public so other pieces +// can use for serialization +type EcPointJSON struct { + X *big.Int `json:"x"` + Y *big.Int `json:"y"` + CurveName string `json:"curve_name"` +} + +// MarshalJSON serializes EcPoint to JSON +func (a EcPoint) MarshalJSON() ([]byte, error) { + return json.Marshal(EcPointJSON{ + CurveName: a.Curve.Params().Name, + X: a.X, + Y: a.Y, + }) +} + +// UnmarshalJSON deserializes JSON to EcPoint +func (a *EcPoint) UnmarshalJSON(bytes []byte) error { + data := new(EcPointJSON) + err := json.Unmarshal(bytes, data) + if err != nil { + return err + } + if mapper, ok := curveMapper[data.CurveName]; ok { + a.Curve = mapper() + a.X = data.X + a.Y = data.Y + return nil + } + return fmt.Errorf("unknown curve deserialized") +} + +// MarshalBinary serializes EcPoint to binary +func (a *EcPoint) MarshalBinary() ([]byte, error) { + result := [65]byte{} + if code, ok := curveNameToID[a.Curve.Params().Name]; ok { + result[0] = code + a.X.FillBytes(result[1:33]) + a.Y.FillBytes(result[33:65]) + return result[:], nil + } + return nil, fmt.Errorf("unknown curve serialized") +} + +// UnmarshalBinary deserializes binary to EcPoint +func (a *EcPoint) UnmarshalBinary(data []byte) error { + if mapper, ok := curveIDToName[data[0]]; ok { + a.Curve = mapper() + a.X = new(big.Int).SetBytes(data[1:33]) + a.Y = new(big.Int).SetBytes(data[33:65]) + return nil + } + return fmt.Errorf("unknown curve deserialized") +} + +// IsValid checks if the point is valid +func (a EcPoint) IsValid() bool { + return a.IsOnCurve() || a.IsIdentity() +} + +// IsOnCurve checks if the point is on the curve +func (a EcPoint) IsOnCurve() bool { + return a.Curve.IsOnCurve(a.X, a.Y) +} + +// IsIdentity returns true if this Point is the Point at infinity +func (a EcPoint) IsIdentity() bool { + x := core.ConstantTimeEqByte(a.X, core.Zero) + y := core.ConstantTimeEqByte(a.Y, core.Zero) + return (x & y) == 1 +} + +// Equals return true if a and b have the same x,y coordinates +func (a EcPoint) Equals(b *EcPoint) bool { + if !sameCurve(&a, b) { + return false + } + x := core.ConstantTimeEqByte(a.X, b.X) + y := core.ConstantTimeEqByte(a.Y, b.Y) + return (x & y) == 1 +} + +// IsBasePoint returns true if this Point is curve's base Point +func (a EcPoint) IsBasePoint() bool { + p := a.Curve.Params() + x := core.ConstantTimeEqByte(a.X, p.Gx) + y := core.ConstantTimeEqByte(a.Y, p.Gy) + return (x & y) == 1 +} + +// reduceModN normalizes the Scalar to a positive element smaller than the base Point order. +func reduceModN(curve elliptic.Curve, k *big.Int) *big.Int { + return new(big.Int).Mod(k, curve.Params().N) +} + +// Add performs elliptic curve addition on two points +func (a *EcPoint) Add(b *EcPoint) (*EcPoint, error) { + if a == nil || b == nil { + return nil, internal.ErrNilArguments + } + if !sameCurve(a, b) { + return nil, internal.ErrPointsDistinctCurves + } + p := &EcPoint{Curve: a.Curve} + p.X, p.Y = a.Curve.Add(a.X, a.Y, b.X, b.Y) + if !p.IsValid() { + return nil, internal.ErrNotOnCurve + } + return p, nil +} + +// Neg returns the negation of a Weierstrass Point. +func (a *EcPoint) Neg() (*EcPoint, error) { + if a == nil { + return nil, internal.ErrNilArguments + } + p := &EcPoint{Curve: a.Curve, X: a.X, Y: new(big.Int).Sub(a.Curve.Params().P, a.Y)} + if !p.IsValid() { + return nil, internal.ErrNotOnCurve + } + return p, nil +} + +// ScalarMult multiplies this Point by a Scalar +func (a *EcPoint) ScalarMult(k *big.Int) (*EcPoint, error) { + if a == nil || k == nil { + return nil, fmt.Errorf("cannot multiply nil Point or element") + } + n := reduceModN(a.Curve, k) + p := new(EcPoint) + p.Curve = a.Curve + p.X, p.Y = a.Curve.ScalarMult(a.X, a.Y, n.Bytes()) + if !p.IsValid() { + return nil, fmt.Errorf("result not on the curve") + } + return p, nil +} + +// NewScalarBaseMult creates a Point from the base Point multiplied by a field element +func NewScalarBaseMult(curve elliptic.Curve, k *big.Int) (*EcPoint, error) { + if curve == nil || k == nil { + return nil, fmt.Errorf("nil parameters are not supported") + } + n := reduceModN(curve, k) + p := new(EcPoint) + p.Curve = curve + p.X, p.Y = curve.ScalarBaseMult(n.Bytes()) + if !p.IsValid() { + return nil, fmt.Errorf("result not on the curve") + } + return p, nil +} + +// Bytes returns the bytes represented by this Point with x || y +func (a EcPoint) Bytes() []byte { + fieldSize := internal.CalcFieldSize(a.Curve) + out := make([]byte, fieldSize*2) + + a.X.FillBytes(out[0:fieldSize]) + a.Y.FillBytes(out[fieldSize : fieldSize*2]) + return out +} + +// PointFromBytesUncompressed outputs uncompressed X || Y similar to +// https://www.secg.org/sec1-v1.99.dif.pdf section 2.2 and 2.3 +func PointFromBytesUncompressed(curve elliptic.Curve, b []byte) (*EcPoint, error) { + fieldSize := internal.CalcFieldSize(curve) + if len(b) != fieldSize*2 { + return nil, fmt.Errorf("invalid number of bytes") + } + p := &EcPoint{ + Curve: curve, + X: new(big.Int).SetBytes(b[:fieldSize]), + Y: new(big.Int).SetBytes(b[fieldSize:]), + } + if !p.IsValid() { + return nil, fmt.Errorf("invalid Point") + } + return p, nil +} + +// sameCurve determines if points a,b appear to be from the same curve +func sameCurve(a, b *EcPoint) bool { + if a == b { + return true + } + if a == nil || b == nil { + return false + } + aParams := a.Curve.Params() + bParams := b.Curve.Params() + return aParams.P.Cmp(bParams.P) == 0 && + aParams.N.Cmp(bParams.N) == 0 && + aParams.B.Cmp(bParams.B) == 0 && + aParams.BitSize == bParams.BitSize && + aParams.Gx.Cmp(bParams.Gx) == 0 && + aParams.Gy.Cmp(bParams.Gy) == 0 && + aParams.Name == bParams.Name +} diff --git a/pkg/crypto/core/curves/ec_point_test.go b/pkg/crypto/core/curves/ec_point_test.go new file mode 100755 index 000000000..c19b138ce --- /dev/null +++ b/pkg/crypto/core/curves/ec_point_test.go @@ -0,0 +1,369 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "bytes" + "crypto/elliptic" + "math/big" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core" + tt "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func TestIsIdentity(t *testing.T) { + // Should be Point at infinity + identity := &EcPoint{btcec.S256(), core.Zero, core.Zero} + require.True(t, identity.IsIdentity()) +} + +func TestNewScalarBaseMultZero(t *testing.T) { + // Should be Point at infinity + curve := btcec.S256() + num := big.NewInt(0) + p, err := NewScalarBaseMult(curve, num) + if err != nil { + t.Errorf("NewScalarBaseMult failed: %v", err) + } + if p == nil { + t.Errorf("NewScalarBaseMult failed when it should've succeeded.") + } +} + +func TestNewScalarBaseMultOne(t *testing.T) { + // Should be base Point + curve := btcec.S256() + num := big.NewInt(1) + p, err := NewScalarBaseMult(curve, num) + if err != nil { + t.Errorf("NewScalarBaseMult failed: %v", err) + } + if p == nil { + t.Errorf("NewScalarBaseMult failed when it should've succeeded.") + t.FailNow() + } + if !bytes.Equal(p.Bytes(), append(curve.Gx.Bytes(), curve.Gy.Bytes()...)) { + t.Errorf("NewScalarBaseMult should've returned the base Point.") + } +} + +func TestNewScalarBaseMultNeg(t *testing.T) { + curve := btcec.S256() + num := big.NewInt(-1) + p, err := NewScalarBaseMult(curve, num) + if err != nil { + t.Errorf("NewScalarBaseMult failed: %v", err) + } + if p == nil { + t.Errorf("NewScalarBaseMult failed when it should've succeeded.") + t.FailNow() + } + num.Mod(num, curve.N) + + e, err := NewScalarBaseMult(curve, num) + if err != nil { + t.Errorf("NewScalarBaseMult failed: %v", err) + } + if e == nil { + t.Errorf("NewScalarBaseMult failed when it should've succeeded.") + t.FailNow() + } + + if !bytes.Equal(p.Bytes(), e.Bytes()) { + t.Errorf("NewScalarBaseMult should've returned the %v, found: %v", e, p) + } +} + +func TestScalarMultZero(t *testing.T) { + // Should be Point at infinity + curve := btcec.S256() + p := &EcPoint{ + Curve: curve, + X: curve.Gx, + Y: curve.Gy, + } + num := big.NewInt(0) + q, err := p.ScalarMult(num) + if err != nil { + t.Errorf("ScalarMult failed: %v", err) + } + if q == nil { + t.Errorf("ScalarMult failed when it should've succeeded.") + t.FailNow() + } + if !q.IsIdentity() { + t.Errorf("ScalarMult should've returned the identity Point.") + } +} + +func TestScalarMultOne(t *testing.T) { + // Should be base Point + curve := btcec.S256() + p := &EcPoint{ + Curve: curve, + X: curve.Gx, + Y: curve.Gy, + } + num := big.NewInt(1) + q, err := p.ScalarMult(num) + if err != nil { + t.Errorf("ScalarMult failed: %v", err) + } + if q == nil { + t.Errorf("ScalarMult failed when it should've succeeded.") + t.FailNow() + } + if !bytes.Equal(q.Bytes(), append(curve.Gx.Bytes(), curve.Gy.Bytes()...)) { + t.Errorf("ScalarMult should've returned the base Point.") + } +} + +func TestScalarMultNeg(t *testing.T) { + curve := btcec.S256() + p := &EcPoint{ + Curve: curve, + X: curve.Gx, + Y: curve.Gy, + } + num := big.NewInt(-1) + q, err := p.ScalarMult(num) + if err != nil { + t.Errorf("ScalarMult failed: %v", err) + } + if q == nil { + t.Errorf("ScalarMult failed when it should've succeeded.") + } + num.Mod(num, curve.N) + + e, err := p.ScalarMult(num) + if err != nil { + t.Errorf("ScalarMult failed: %v", err) + } + if e == nil { + t.Errorf("ScalarMult failed when it should've succeeded.") + t.FailNow() + } + + if !bytes.Equal(q.Bytes(), e.Bytes()) { + t.Errorf("ScalarMult should've returned the %v, found: %v", e, p) + } +} + +func TestEcPointAddSimple(t *testing.T) { + curve := btcec.S256() + num := big.NewInt(1) + p1, _ := NewScalarBaseMult(curve, num) + + p2, _ := NewScalarBaseMult(curve, num) + p3, err := p1.Add(p2) + if err != nil { + t.Errorf("EcPoint.Add failed: %v", err) + } + num = big.NewInt(2) + + ep, _ := NewScalarBaseMult(curve, num) + + if !bytes.Equal(ep.Bytes(), p3.Bytes()) { + t.Errorf("EcPoint.Add failed: should equal %v, found: %v", ep, p3) + } +} + +func TestEcPointAddCommunicative(t *testing.T) { + curve := btcec.S256() + a, _ := core.Rand(curve.Params().N) + b, _ := core.Rand(curve.Params().N) + + p1, _ := NewScalarBaseMult(curve, a) + p2, _ := NewScalarBaseMult(curve, b) + p3, err := p1.Add(p2) + if err != nil { + t.Errorf("EcPoint.Add failed: %v", err) + } + p4, err := p2.Add(p1) + if err != nil { + t.Errorf("EcPoint.Add failed: %v", err) + } + if !bytes.Equal(p3.Bytes(), p4.Bytes()) { + t.Errorf("EcPoint.Add Communicative not valid") + } +} + +func TestEcPointAddNeg(t *testing.T) { + curve := btcec.S256() + num := big.NewInt(-1) + + p1, _ := NewScalarBaseMult(curve, num) + num.Abs(num) + + p2, _ := NewScalarBaseMult(curve, num) + + p3, err := p1.Add(p2) + if err != nil { + t.Errorf("EcPoint.Add failed: %v", err) + } + zero := make([]byte, 64) + if !bytes.Equal(zero, p3.Bytes()) { + t.Errorf("Expected value to be zero, found: %v", p3) + } +} + +func TestEcPointBytes(t *testing.T) { + curve := btcec.S256() + + point, err := NewScalarBaseMult(curve, big.NewInt(2)) + require.NoError(t, err) + data := point.Bytes() + point2, err := PointFromBytesUncompressed(curve, data) + require.NoError(t, err) + if point.X.Cmp(point2.X) != 0 && point.Y.Cmp(point2.Y) != 0 { + t.Errorf("Points are not equal. Expected %v, found %v", point, point2) + } + + curve2 := elliptic.P224() + p2, err := NewScalarBaseMult(curve2, big.NewInt(2)) + require.NoError(t, err) + dta := p2.Bytes() + point3, err := PointFromBytesUncompressed(curve2, dta) + require.NoError(t, err) + if p2.X.Cmp(point3.X) != 0 && p2.Y.Cmp(point3.Y) != 0 { + t.Errorf("Points are not equal. Expected %v, found %v", p2, point3) + } + + curve3 := elliptic.P521() + p3, err := NewScalarBaseMult(curve3, big.NewInt(2)) + require.NoError(t, err) + data = p3.Bytes() + point4, err := PointFromBytesUncompressed(curve3, data) + require.NoError(t, err) + if p3.X.Cmp(point4.X) != 0 && p3.Y.Cmp(point4.Y) != 0 { + t.Errorf("Points are not equal. Expected %v, found %v", p3, point4) + } +} + +func TestEcPointBytesDifferentCurves(t *testing.T) { + k256 := btcec.S256() + p224 := elliptic.P224() + p256 := elliptic.P256() + + kp, err := NewScalarBaseMult(k256, big.NewInt(1)) + require.NoError(t, err) + data := kp.Bytes() + _, err = PointFromBytesUncompressed(p224, data) + require.Error(t, err) + _, err = PointFromBytesUncompressed(p256, data) + require.Error(t, err) +} + +func TestEcPointBytesInvalidNumberBytes(t *testing.T) { + curve := btcec.S256() + + for i := 1; i < 64; i++ { + data := make([]byte, i) + _, err := PointFromBytesUncompressed(curve, data) + require.Error(t, err) + } + for i := 65; i < 128; i++ { + data := make([]byte, i) + _, err := PointFromBytesUncompressed(curve, data) + require.Error(t, err) + } +} + +func TestEcPointMultRandom(t *testing.T) { + curve := btcec.S256() + r, err := core.Rand(curve.N) + require.NoError(t, err) + pt, err := NewScalarBaseMult(curve, r) + require.NoError(t, err) + require.NotNil(t, pt) + data := pt.Bytes() + pt2, err := PointFromBytesUncompressed(curve, data) + require.NoError(t, err) + if pt.X.Cmp(pt2.X) != 0 || pt.Y.Cmp(pt2.Y) != 0 { + t.Errorf("Points are not equal. Expected: %v, found: %v", pt, pt2) + } +} + +func TestIsBasePoint(t *testing.T) { + k256 := btcec.S256() + p224 := elliptic.P224() + p256 := elliptic.P256() + + notG_p224, err := NewScalarBaseMult(p224, tt.B10("9876453120")) + require.NoError(t, err) + + tests := []struct { + name string + curve elliptic.Curve + x, y *big.Int + expected bool + }{ + {"k256-positive", k256, k256.Gx, k256.Gy, true}, + {"p224-positive", p224, p224.Params().Gx, p224.Params().Gy, true}, + {"p256-positive", p256, p256.Params().Gx, p256.Params().Gy, true}, + + {"p224-negative", p224, notG_p224.X, notG_p224.Y, false}, + {"p256-negative-wrong-curve", p256, notG_p224.X, notG_p224.Y, false}, + {"k256-negative-doubleGx", k256, k256.Gx, k256.Gx, false}, + {"k256-negative-doubleGy", k256, k256.Gy, k256.Gy, false}, + {"k256-negative-xy-swap", k256, k256.Gy, k256.Gx, false}, + {"k256-negative-oh-oh", k256, core.Zero, core.Zero, false}, + } + // Run all the tests! + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + actual := EcPoint{test.curve, test.x, test.y}.IsBasePoint() + require.Equal(t, test.expected, actual) + }) + } +} + +func TestEquals(t *testing.T) { + k256 := btcec.S256() + p224 := elliptic.P224() + p256 := elliptic.P256() + P_p224, _ := NewScalarBaseMult(p224, tt.B10("9876453120")) + P1_p224, _ := NewScalarBaseMult(p224, tt.B10("9876453120")) + + P_k256 := &EcPoint{k256, P_p224.X, P_p224.Y} + + id_p224 := &EcPoint{p224, core.Zero, core.Zero} + id_k256 := &EcPoint{k256, core.Zero, core.Zero} + id_p256 := &EcPoint{p256, core.Zero, core.Zero} + + tests := []struct { + name string + x, y *EcPoint + expected bool + }{ + {"p224 same pointer", P_p224, P_p224, true}, + {"p224 same Point", P_p224, P1_p224, true}, + {"p224 identity", id_p224, id_p224, true}, + {"p256 identity", id_p256, id_p256, true}, + {"k256 identity", id_k256, id_k256, true}, + + {"negative-same x different y", P_p224, &EcPoint{p224, P_p224.X, core.One}, false}, + {"negative-same y different x", P_p224, &EcPoint{p224, core.Two, P_k256.Y}, false}, + + {"negative-wrong curve", P_p224, P_k256, false}, + {"negative-wrong curve reversed", P_k256, P_p224, false}, + {"Point is not the identity", P_p224, id_p224, false}, + {"negative nil", P1_p224, nil, false}, + {"identities on wrong curve", id_p256, id_k256, false}, + } + // Run all the tests! + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + actual := test.x.Equals(test.y) + require.Equal(t, test.expected, actual) + }) + } +} diff --git a/pkg/crypto/core/curves/ec_scalar.go b/pkg/crypto/core/curves/ec_scalar.go new file mode 100755 index 000000000..3f7889722 --- /dev/null +++ b/pkg/crypto/core/curves/ec_scalar.go @@ -0,0 +1,351 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/elliptic" + crand "crypto/rand" + "crypto/sha512" + "fmt" + "io" + "math/big" + + "filippo.io/edwards25519" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/bwesterb/go-ristretto" + + "github.com/onsonr/sonr/pkg/crypto/core" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +type EcScalar interface { + Add(x, y *big.Int) *big.Int + Sub(x, y *big.Int) *big.Int + Neg(x *big.Int) *big.Int + Mul(x, y *big.Int) *big.Int + Hash(input []byte) *big.Int + Div(x, y *big.Int) *big.Int + Random() (*big.Int, error) + IsValid(x *big.Int) bool + Bytes(x *big.Int) []byte // fixed-length byte array +} + +type K256Scalar struct{} + +// Static interface assertion +var _ EcScalar = (*K256Scalar)(nil) + +// warning: the Euclidean alg which Mod uses is not constant-time. + +func NewK256Scalar() *K256Scalar { + return &K256Scalar{} +} + +func (k K256Scalar) Add(x, y *big.Int) *big.Int { + v := new(big.Int).Add(x, y) + v.Mod(v, btcec.S256().N) + return v +} + +func (k K256Scalar) Sub(x, y *big.Int) *big.Int { + v := new(big.Int).Sub(x, y) + v.Mod(v, btcec.S256().N) + return v +} + +func (k K256Scalar) Neg(x *big.Int) *big.Int { + v := new(big.Int).Sub(btcec.S256().N, x) + v.Mod(v, btcec.S256().N) + return v +} + +func (k K256Scalar) Mul(x, y *big.Int) *big.Int { + v := new(big.Int).Mul(x, y) + v.Mod(v, btcec.S256().N) + return v +} + +func (k K256Scalar) Div(x, y *big.Int) *big.Int { + t := new(big.Int).ModInverse(y, btcec.S256().N) + return k.Mul(x, t) +} + +func (k K256Scalar) Hash(input []byte) *big.Int { + return new(ScalarK256).Hash(input).BigInt() +} + +func (k K256Scalar) Random() (*big.Int, error) { + b := make([]byte, 48) + n, err := crand.Read(b) + if err != nil { + return nil, err + } + if n != 48 { + return nil, fmt.Errorf("insufficient bytes read") + } + v := new(big.Int).SetBytes(b) + v.Mod(v, btcec.S256().N) + return v, nil +} + +func (k K256Scalar) IsValid(x *big.Int) bool { + return core.In(x, btcec.S256().N) == nil +} + +func (k K256Scalar) Bytes(x *big.Int) []byte { + bytes := make([]byte, 32) + x.FillBytes(bytes) // big-endian; will left-pad. + return bytes +} + +type P256Scalar struct{} + +// Static interface assertion +var _ EcScalar = (*P256Scalar)(nil) + +func NewP256Scalar() *P256Scalar { + return &P256Scalar{} +} + +func (k P256Scalar) Add(x, y *big.Int) *big.Int { + v := new(big.Int).Add(x, y) + v.Mod(v, elliptic.P256().Params().N) + return v +} + +func (k P256Scalar) Sub(x, y *big.Int) *big.Int { + v := new(big.Int).Sub(x, y) + v.Mod(v, elliptic.P256().Params().N) + return v +} + +func (k P256Scalar) Neg(x *big.Int) *big.Int { + v := new(big.Int).Sub(elliptic.P256().Params().N, x) + v.Mod(v, elliptic.P256().Params().N) + return v +} + +func (k P256Scalar) Mul(x, y *big.Int) *big.Int { + v := new(big.Int).Mul(x, y) + v.Mod(v, elliptic.P256().Params().N) + return v +} + +func (k P256Scalar) Div(x, y *big.Int) *big.Int { + t := new(big.Int).ModInverse(y, elliptic.P256().Params().N) + return k.Mul(x, t) +} + +func (k P256Scalar) Hash(input []byte) *big.Int { + return new(ScalarP256).Hash(input).BigInt() +} + +func (k P256Scalar) Random() (*big.Int, error) { + b := make([]byte, 48) + n, err := crand.Read(b) + if err != nil { + return nil, err + } + if n != 48 { + return nil, fmt.Errorf("insufficient bytes read") + } + v := new(big.Int).SetBytes(b) + v.Mod(v, elliptic.P256().Params().N) + return v, nil +} + +func (k P256Scalar) IsValid(x *big.Int) bool { + return core.In(x, elliptic.P256().Params().N) == nil +} + +func (k P256Scalar) Bytes(x *big.Int) []byte { + bytes := make([]byte, 32) + x.FillBytes(bytes) // big-endian; will left-pad. + return bytes +} + +type Bls12381Scalar struct{} + +// Static interface assertion +var _ EcScalar = (*Bls12381Scalar)(nil) + +func NewBls12381Scalar() *Bls12381Scalar { + return &Bls12381Scalar{} +} + +func (k Bls12381Scalar) Add(x, y *big.Int) *big.Int { + a := bls12381.Bls12381FqNew().SetBigInt(x) + b := bls12381.Bls12381FqNew().SetBigInt(y) + return a.Add(a, b).BigInt() +} + +func (k Bls12381Scalar) Sub(x, y *big.Int) *big.Int { + a := bls12381.Bls12381FqNew().SetBigInt(x) + b := bls12381.Bls12381FqNew().SetBigInt(y) + return a.Sub(a, b).BigInt() +} + +func (k Bls12381Scalar) Neg(x *big.Int) *big.Int { + a := bls12381.Bls12381FqNew().SetBigInt(x) + return a.Neg(a).BigInt() +} + +func (k Bls12381Scalar) Mul(x, y *big.Int) *big.Int { + a := bls12381.Bls12381FqNew().SetBigInt(x) + b := bls12381.Bls12381FqNew().SetBigInt(y) + return a.Mul(a, b).BigInt() +} + +func (k Bls12381Scalar) Div(x, y *big.Int) *big.Int { + c := bls12381.Bls12381FqNew() + a := bls12381.Bls12381FqNew().SetBigInt(x) + b := bls12381.Bls12381FqNew().SetBigInt(y) + _, wasInverted := c.Invert(b) + c.Mul(a, c) + tt := map[bool]int{false: 0, true: 1} + return a.CMove(a, c, tt[wasInverted]).BigInt() +} + +func (k Bls12381Scalar) Hash(input []byte) *big.Int { + return new(ScalarBls12381).Hash(input).BigInt() +} + +func (k Bls12381Scalar) Random() (*big.Int, error) { + a := BLS12381G1().NewScalar().Random(crand.Reader) + if a == nil { + return nil, fmt.Errorf("invalid random value") + } + return a.BigInt(), nil +} + +func (k Bls12381Scalar) Bytes(x *big.Int) []byte { + bytes := make([]byte, 32) + x.FillBytes(bytes) // big-endian; will left-pad. + return bytes +} + +func (k Bls12381Scalar) IsValid(x *big.Int) bool { + a := bls12381.Bls12381FqNew().SetBigInt(x) + return a.BigInt().Cmp(x) == 0 +} + +// taken from https://datatracker.ietf.org/doc/html/rfc8032 +var ed25519N, _ = new(big.Int).SetString("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", 16) + +type Ed25519Scalar struct{} + +// Static interface assertion +var _ EcScalar = (*Ed25519Scalar)(nil) + +func NewEd25519Scalar() *Ed25519Scalar { + return &Ed25519Scalar{} +} + +func (k Ed25519Scalar) Add(x, y *big.Int) *big.Int { + a, err := internal.BigInt2Ed25519Scalar(x) + if err != nil { + panic(err) + } + b, err := internal.BigInt2Ed25519Scalar(y) + if err != nil { + panic(err) + } + a.Add(a, b) + return new(big.Int).SetBytes(internal.ReverseScalarBytes(a.Bytes())) +} + +func (k Ed25519Scalar) Sub(x, y *big.Int) *big.Int { + a, err := internal.BigInt2Ed25519Scalar(x) + if err != nil { + panic(err) + } + b, err := internal.BigInt2Ed25519Scalar(y) + if err != nil { + panic(err) + } + a.Subtract(a, b) + return new(big.Int).SetBytes(internal.ReverseScalarBytes(a.Bytes())) +} + +func (k Ed25519Scalar) Neg(x *big.Int) *big.Int { + a, err := internal.BigInt2Ed25519Scalar(x) + if err != nil { + panic(err) + } + a.Negate(a) + return new(big.Int).SetBytes(internal.ReverseScalarBytes(a.Bytes())) +} + +func (k Ed25519Scalar) Mul(x, y *big.Int) *big.Int { + a, err := internal.BigInt2Ed25519Scalar(x) + if err != nil { + panic(err) + } + b, err := internal.BigInt2Ed25519Scalar(y) + if err != nil { + panic(err) + } + a.Multiply(a, b) + return new(big.Int).SetBytes(internal.ReverseScalarBytes(a.Bytes())) +} + +func (k Ed25519Scalar) Div(x, y *big.Int) *big.Int { + b, err := internal.BigInt2Ed25519Scalar(y) + if err != nil { + panic(err) + } + b.Invert(b) + a, err := internal.BigInt2Ed25519Scalar(x) + if err != nil { + panic(err) + } + a.Multiply(a, b) + return new(big.Int).SetBytes(internal.ReverseScalarBytes(a.Bytes())) +} + +func (k Ed25519Scalar) Hash(input []byte) *big.Int { + v := new(ristretto.Scalar).Derive(input) + var data [32]byte + v.BytesInto(&data) + return new(big.Int).SetBytes(internal.ReverseScalarBytes(data[:])) +} + +func (k Ed25519Scalar) Bytes(x *big.Int) []byte { + a, err := internal.BigInt2Ed25519Scalar(x) + if err != nil { + panic(err) + } + return internal.ReverseScalarBytes(a.Bytes()) +} + +func (k Ed25519Scalar) Random() (*big.Int, error) { + return k.RandomWithReader(crand.Reader) +} + +func (k Ed25519Scalar) RandomWithReader(r io.Reader) (*big.Int, error) { + b := make([]byte, 64) + n, err := r.Read(b) + if err != nil { + return nil, err + } + if n != 64 { + return nil, fmt.Errorf("insufficient bytes read") + } + digest := sha512.Sum512(b) + var hBytes [32]byte + copy(hBytes[:], digest[:]) + s, err := edwards25519.NewScalar().SetBytesWithClamping(hBytes[:]) + if err != nil { + return nil, err + } + return new(big.Int).SetBytes(internal.ReverseScalarBytes(s.Bytes())), nil +} + +func (k Ed25519Scalar) IsValid(x *big.Int) bool { + return x.Cmp(ed25519N) == -1 +} diff --git a/pkg/crypto/core/curves/ecdsa.go b/pkg/crypto/core/curves/ecdsa.go new file mode 100755 index 000000000..41e8759e1 --- /dev/null +++ b/pkg/crypto/core/curves/ecdsa.go @@ -0,0 +1,39 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/ecdsa" + "math/big" +) + +// EcdsaVerify runs a curve- or algorithm-specific ECDSA verification function on input +// an ECDSA public (verification) key, a message digest, and an ECDSA signature. +// It must return true if all the parameters are sane and the ECDSA signature is valid, +// and false otherwise +type EcdsaVerify func(pubKey *EcPoint, hash []byte, signature *EcdsaSignature) bool + +// EcdsaSignature represents a (composite) digital signature +type EcdsaSignature struct { + R *big.Int + S *big.Int + V int +} + +// Static type assertion +var _ EcdsaVerify = VerifyEcdsa + +// Verifies ECDSA signature using core types. +func VerifyEcdsa(pk *EcPoint, hash []byte, sig *EcdsaSignature) bool { + return ecdsa.Verify( + &ecdsa.PublicKey{ + Curve: pk.Curve, + X: pk.X, + Y: pk.Y, + }, + hash, sig.R, sig.S) +} diff --git a/pkg/crypto/core/curves/ed25519_curve.go b/pkg/crypto/core/curves/ed25519_curve.go new file mode 100755 index 000000000..942c62cbc --- /dev/null +++ b/pkg/crypto/core/curves/ed25519_curve.go @@ -0,0 +1,788 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "bytes" + "crypto/sha512" + "crypto/subtle" + "fmt" + "io" + "math/big" + + "filippo.io/edwards25519" + "filippo.io/edwards25519/field" + "github.com/bwesterb/go-ristretto" + ed "github.com/bwesterb/go-ristretto/edwards25519" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +type ScalarEd25519 struct { + value *edwards25519.Scalar +} + +type PointEd25519 struct { + value *edwards25519.Point +} + +var scOne, _ = edwards25519.NewScalar().SetCanonicalBytes([]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) + +func (s *ScalarEd25519) Random(reader io.Reader) Scalar { + if reader == nil { + return nil + } + var seed [64]byte + _, _ = reader.Read(seed[:]) + return s.Hash(seed[:]) +} + +func (s *ScalarEd25519) Hash(bytes []byte) Scalar { + v := new(ristretto.Scalar).Derive(bytes) + var data [32]byte + v.BytesInto(&data) + value, err := edwards25519.NewScalar().SetCanonicalBytes(data[:]) + if err != nil { + return nil + } + return &ScalarEd25519{value} +} + +func (s *ScalarEd25519) Zero() Scalar { + return &ScalarEd25519{ + value: edwards25519.NewScalar(), + } +} + +func (s *ScalarEd25519) One() Scalar { + return &ScalarEd25519{ + value: edwards25519.NewScalar().Set(scOne), + } +} + +func (s *ScalarEd25519) IsZero() bool { + i := byte(0) + for _, b := range s.value.Bytes() { + i |= b + } + return i == 0 +} + +func (s *ScalarEd25519) IsOne() bool { + data := s.value.Bytes() + i := byte(0) + for j := 1; j < len(data); j++ { + i |= data[j] + } + return i == 0 && data[0] == 1 +} + +func (s *ScalarEd25519) IsOdd() bool { + return s.value.Bytes()[0]&1 == 1 +} + +func (s *ScalarEd25519) IsEven() bool { + return s.value.Bytes()[0]&1 == 0 +} + +func (s *ScalarEd25519) New(input int) Scalar { + var data [64]byte + i := input + if input < 0 { + i = -input + } + data[0] = byte(i) + data[1] = byte(i >> 8) + data[2] = byte(i >> 16) + data[3] = byte(i >> 24) + value, err := edwards25519.NewScalar().SetUniformBytes(data[:]) + if err != nil { + return nil + } + if input < 0 { + value.Negate(value) + } + + return &ScalarEd25519{ + value, + } +} + +func (s *ScalarEd25519) Cmp(rhs Scalar) int { + r := s.Sub(rhs) + if r != nil && r.IsZero() { + return 0 + } else { + return -2 + } +} + +func (s *ScalarEd25519) Square() Scalar { + value := edwards25519.NewScalar().Multiply(s.value, s.value) + return &ScalarEd25519{value} +} + +func (s *ScalarEd25519) Double() Scalar { + return &ScalarEd25519{ + value: edwards25519.NewScalar().Add(s.value, s.value), + } +} + +func (s *ScalarEd25519) Invert() (Scalar, error) { + return &ScalarEd25519{ + value: edwards25519.NewScalar().Invert(s.value), + }, nil +} + +func (s *ScalarEd25519) Sqrt() (Scalar, error) { + bi25519, _ := new(big.Int).SetString("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", 16) + x := s.BigInt() + x.ModSqrt(x, bi25519) + return s.SetBigInt(x) +} + +func (s *ScalarEd25519) Cube() Scalar { + value := edwards25519.NewScalar().Multiply(s.value, s.value) + value.Multiply(value, s.value) + return &ScalarEd25519{value} +} + +func (s *ScalarEd25519) Add(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarEd25519) + if ok { + return &ScalarEd25519{ + value: edwards25519.NewScalar().Add(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarEd25519) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarEd25519) + if ok { + return &ScalarEd25519{ + value: edwards25519.NewScalar().Subtract(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarEd25519) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarEd25519) + if ok { + return &ScalarEd25519{ + value: edwards25519.NewScalar().Multiply(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarEd25519) MulAdd(y, z Scalar) Scalar { + yy, ok := y.(*ScalarEd25519) + if !ok { + return nil + } + zz, ok := z.(*ScalarEd25519) + if !ok { + return nil + } + return &ScalarEd25519{value: edwards25519.NewScalar().MultiplyAdd(s.value, yy.value, zz.value)} +} + +func (s *ScalarEd25519) Div(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarEd25519) + if ok { + value := edwards25519.NewScalar().Invert(r.value) + value.Multiply(value, s.value) + return &ScalarEd25519{value} + } else { + return nil + } +} + +func (s *ScalarEd25519) Neg() Scalar { + return &ScalarEd25519{ + value: edwards25519.NewScalar().Negate(s.value), + } +} + +func (s *ScalarEd25519) SetBigInt(x *big.Int) (Scalar, error) { + if x == nil { + return nil, fmt.Errorf("invalid value") + } + + bi25519, _ := new(big.Int).SetString("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", 16) + var v big.Int + buf := v.Mod(x, bi25519).Bytes() + var rBuf [32]byte + for i := 0; i < len(buf) && i < 32; i++ { + rBuf[i] = buf[len(buf)-i-1] + } + value, err := edwards25519.NewScalar().SetCanonicalBytes(rBuf[:]) + if err != nil { + return nil, err + } + return &ScalarEd25519{value}, nil +} + +func (s *ScalarEd25519) BigInt() *big.Int { + var ret big.Int + buf := internal.ReverseScalarBytes(s.value.Bytes()) + return ret.SetBytes(buf) +} + +func (s *ScalarEd25519) Bytes() []byte { + return s.value.Bytes() +} + +// SetBytes takes input a 32-byte long array and returns a ed25519 scalar. +// The input must be 32-byte long and must be a reduced bytes. +func (s *ScalarEd25519) SetBytes(input []byte) (Scalar, error) { + if len(input) != 32 { + return nil, fmt.Errorf("invalid byte sequence") + } + value, err := edwards25519.NewScalar().SetCanonicalBytes(input) + if err != nil { + return nil, err + } + return &ScalarEd25519{value}, nil +} + +// SetBytesWide takes input a 64-byte long byte array, reduce it and return an ed25519 scalar. +// It uses SetUniformBytes of fillipo.io/edwards25519 - https://github.com/FiloSottile/edwards25519/blob/v1.0.0-rc.1/scalar.go#L85 +// If bytes is not of the right length, it returns nil and an error +func (s *ScalarEd25519) SetBytesWide(bytes []byte) (Scalar, error) { + value, err := edwards25519.NewScalar().SetUniformBytes(bytes) + if err != nil { + return nil, err + } + return &ScalarEd25519{value}, nil +} + +// SetBytesClamping uses SetBytesWithClamping of fillipo.io/edwards25519- https://github.com/FiloSottile/edwards25519/blob/v1.0.0-rc.1/scalar.go#L135 +// which applies the buffer pruning described in RFC 8032, Section 5.1.5 (also known as clamping) +// and sets bytes to the result. The input must be 32-byte long, and it is not modified. +// If bytes is not of the right length, SetBytesWithClamping returns nil and an error, and the receiver is unchanged. +func (s *ScalarEd25519) SetBytesClamping(bytes []byte) (Scalar, error) { + value, err := edwards25519.NewScalar().SetBytesWithClamping(bytes) + if err != nil { + return nil, err + } + return &ScalarEd25519{value}, nil +} + +// SetBytesCanonical uses SetCanonicalBytes of fillipo.io/edwards25519. +// https://github.com/FiloSottile/edwards25519/blob/v1.0.0-rc.1/scalar.go#L98 +// This function takes an input x and sets s = x, where x is a 32-byte little-endian +// encoding of s, then it returns the corresponding ed25519 scalar. If the input is +// not a canonical encoding of s, it returns nil and an error. +func (s *ScalarEd25519) SetBytesCanonical(bytes []byte) (Scalar, error) { + return s.SetBytes(bytes) +} + +func (s *ScalarEd25519) Point() Point { + return new(PointEd25519).Identity() +} + +func (s *ScalarEd25519) Clone() Scalar { + return &ScalarEd25519{ + value: edwards25519.NewScalar().Set(s.value), + } +} + +func (s *ScalarEd25519) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *ScalarEd25519) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarEd25519) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarEd25519) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *ScalarEd25519) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarEd25519) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarEd25519) GetEdwardsScalar() *edwards25519.Scalar { + return edwards25519.NewScalar().Set(s.value) +} + +func (s *ScalarEd25519) SetEdwardsScalar(sc *edwards25519.Scalar) *ScalarEd25519 { + return &ScalarEd25519{value: edwards25519.NewScalar().Set(sc)} +} + +func (s *ScalarEd25519) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *ScalarEd25519) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*ScalarEd25519) + if !ok { + return fmt.Errorf("invalid type") + } + s.value = S.value + return nil +} + +func (p *PointEd25519) Random(reader io.Reader) Point { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *PointEd25519) Hash(bytes []byte) Point { + /// Perform hashing to the group using the Elligator2 map + /// + /// See https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-11#section-6.7.1 + h := sha512.Sum512(bytes) + var res [32]byte + copy(res[:], h[:32]) + signBit := (res[31] & 0x80) >> 7 + + fe := new(ed.FieldElement).SetBytes(&res).BytesInto(&res) + m1 := elligatorEncode(fe) + + return toEdwards(m1, signBit) +} + +func (p *PointEd25519) Identity() Point { + return &PointEd25519{ + value: edwards25519.NewIdentityPoint(), + } +} + +func (p *PointEd25519) Generator() Point { + return &PointEd25519{ + value: edwards25519.NewGeneratorPoint(), + } +} + +func (p *PointEd25519) IsIdentity() bool { + return p.Equal(p.Identity()) +} + +func (p *PointEd25519) IsNegative() bool { + // Negative points don't really exist in ed25519 + return false +} + +func (p *PointEd25519) IsOnCurve() bool { + _, err := edwards25519.NewIdentityPoint().SetBytes(p.ToAffineCompressed()) + return err == nil +} + +func (p *PointEd25519) Double() Point { + return &PointEd25519{value: edwards25519.NewIdentityPoint().Add(p.value, p.value)} +} + +func (p *PointEd25519) Scalar() Scalar { + return new(ScalarEd25519).Zero() +} + +func (p *PointEd25519) Neg() Point { + return &PointEd25519{value: edwards25519.NewIdentityPoint().Negate(p.value)} +} + +func (p *PointEd25519) Add(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointEd25519) + if ok { + return &PointEd25519{value: edwards25519.NewIdentityPoint().Add(p.value, r.value)} + } else { + return nil + } +} + +func (p *PointEd25519) Sub(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointEd25519) + if ok { + rTmp := edwards25519.NewIdentityPoint().Negate(r.value) + return &PointEd25519{value: edwards25519.NewIdentityPoint().Add(p.value, rTmp)} + } else { + return nil + } +} + +func (p *PointEd25519) Mul(rhs Scalar) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*ScalarEd25519) + if ok { + value := edwards25519.NewIdentityPoint().ScalarMult(r.value, p.value) + return &PointEd25519{value} + } else { + return nil + } +} + +// MangleScalarBitsAndMulByBasepointToProducePublicKey +// is a function for mangling the bits of a (formerly +// mathematically well-defined) "scalar" and multiplying it to produce a +// public key. +func (p *PointEd25519) MangleScalarBitsAndMulByBasepointToProducePublicKey(rhs *ScalarEd25519) *PointEd25519 { + data := rhs.value.Bytes() + s, err := edwards25519.NewScalar().SetBytesWithClamping(data[:]) + if err != nil { + return nil + } + value := edwards25519.NewIdentityPoint().ScalarBaseMult(s) + return &PointEd25519{value} +} + +func (p *PointEd25519) Equal(rhs Point) bool { + r, ok := rhs.(*PointEd25519) + if ok { + // We would like to check that the point (X/Z, Y/Z) is equal to + // the point (X'/Z', Y'/Z') without converting into affine + // coordinates (x, y) and (x', y'), which requires two inversions. + // We have that X = xZ and X' = x'Z'. Thus, x = x' is equivalent to + // (xZ)Z' = (x'Z')Z, and similarly for the y-coordinate. + return p.value.Equal(r.value) == 1 + //lhs1 := new(ed.FieldElement).Mul(&p.value.X, &r.value.Z) + //rhs1 := new(ed.FieldElement).Mul(&r.value.X, &p.value.Z) + //lhs2 := new(ed.FieldElement).Mul(&p.value.Y, &r.value.Z) + //rhs2 := new(ed.FieldElement).Mul(&r.value.Y, &p.value.Z) + // + //return lhs1.Equals(rhs1) && lhs2.Equals(rhs2) + } else { + return false + } +} + +func (p *PointEd25519) Set(x, y *big.Int) (Point, error) { + // check is identity + xx := subtle.ConstantTimeCompare(x.Bytes(), []byte{}) + yy := subtle.ConstantTimeCompare(y.Bytes(), []byte{}) + if (xx | yy) == 1 { + return p.Identity(), nil + } + xElem := new(ed.FieldElement).SetBigInt(x) + yElem := new(ed.FieldElement).SetBigInt(y) + + var data [32]byte + var affine [64]byte + xElem.BytesInto(&data) + copy(affine[:32], data[:]) + yElem.BytesInto(&data) + copy(affine[32:], data[:]) + return p.FromAffineUncompressed(affine[:]) +} + +// sqrtRatio sets r to the non-negative square root of the ratio of u and v. +// +// If u/v is square, sqrtRatio returns r and 1. If u/v is not square, SqrtRatio +// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00, +// and returns r and 0. +func sqrtRatio(u, v *ed.FieldElement) (r *ed.FieldElement, wasSquare bool) { + sqrtM1 := ed.FieldElement{ + 533094393274173, 2016890930128738, 18285341111199, + 134597186663265, 1486323764102114, + } + a := new(ed.FieldElement) + b := new(ed.FieldElement) + r = new(ed.FieldElement) + + // r = (u * v3) * (u * v7)^((p-5)/8) + v2 := a.Square(v) + uv3 := b.Mul(u, b.Mul(v2, v)) + uv7 := a.Mul(uv3, a.Square(v2)) + r.Mul(uv3, r.Exp22523(uv7)) + + check := a.Mul(v, a.Square(r)) // check = v * r^2 + + uNeg := b.Neg(u) + correctSignSqrt := check.Equals(u) + flippedSignSqrt := check.Equals(uNeg) + flippedSignSqrtI := check.Equals(uNeg.Mul(uNeg, &sqrtM1)) + + rPrime := b.Mul(r, &sqrtM1) // r_prime = SQRT_M1 * r + // r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r) + cselect(r, rPrime, r, flippedSignSqrt || flippedSignSqrtI) + + r.Abs(r) // Choose the nonnegative square root. + return r, correctSignSqrt || flippedSignSqrt +} + +// cselect sets v to a if cond == 1, and to b if cond == 0. +func cselect(v, a, b *ed.FieldElement, cond bool) *ed.FieldElement { + const mask64Bits uint64 = (1 << 64) - 1 + + m := uint64(0) + if cond { + m = mask64Bits + } + + v[0] = (m & a[0]) | (^m & b[0]) + v[1] = (m & a[1]) | (^m & b[1]) + v[2] = (m & a[2]) | (^m & b[2]) + v[3] = (m & a[3]) | (^m & b[3]) + v[4] = (m & a[4]) | (^m & b[4]) + return v +} + +func (p *PointEd25519) ToAffineCompressed() []byte { + return p.value.Bytes() +} + +func (p *PointEd25519) ToAffineUncompressed() []byte { + x, y, z, _ := p.value.ExtendedCoordinates() + recip := new(field.Element).Invert(z) + x.Multiply(x, recip) + y.Multiply(y, recip) + var out [64]byte + copy(out[:32], x.Bytes()) + copy(out[32:], y.Bytes()) + return out[:] +} + +func (p *PointEd25519) FromAffineCompressed(inBytes []byte) (Point, error) { + pt, err := edwards25519.NewIdentityPoint().SetBytes(inBytes) + if err != nil { + return nil, err + } + return &PointEd25519{value: pt}, nil +} + +func (p *PointEd25519) FromAffineUncompressed(inBytes []byte) (Point, error) { + if len(inBytes) != 64 { + return nil, fmt.Errorf("invalid byte sequence") + } + if bytes.Equal(inBytes, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) { + return &PointEd25519{value: edwards25519.NewIdentityPoint()}, nil + } + x, err := new(field.Element).SetBytes(inBytes[:32]) + if err != nil { + return nil, err + } + y, err := new(field.Element).SetBytes(inBytes[32:]) + if err != nil { + return nil, err + } + z := new(field.Element).One() + t := new(field.Element).Multiply(x, y) + value, err := edwards25519.NewIdentityPoint().SetExtendedCoordinates(x, y, z, t) + if err != nil { + return nil, err + } + return &PointEd25519{value}, nil +} + +func (p *PointEd25519) CurveName() string { + return ED25519Name +} + +func (p *PointEd25519) SumOfProducts(points []Point, scalars []Scalar) Point { + nScalars := make([]*edwards25519.Scalar, len(scalars)) + nPoints := make([]*edwards25519.Point, len(points)) + for i, sc := range scalars { + s, err := edwards25519.NewScalar().SetCanonicalBytes(sc.Bytes()) + if err != nil { + return nil + } + nScalars[i] = s + } + for i, pt := range points { + pp, ok := pt.(*PointEd25519) + if !ok { + return nil + } + nPoints[i] = pp.value + } + pt := edwards25519.NewIdentityPoint().MultiScalarMult(nScalars, nPoints) + return &PointEd25519{value: pt} +} + +func (p *PointEd25519) VarTimeDoubleScalarBaseMult(a Scalar, A Point, b Scalar) Point { + AA, ok := A.(*PointEd25519) + if !ok { + return nil + } + aa, ok := a.(*ScalarEd25519) + if !ok { + return nil + } + bb, ok := b.(*ScalarEd25519) + if !ok { + return nil + } + value := edwards25519.NewIdentityPoint().VarTimeDoubleScalarBaseMult(aa.value, AA.value, bb.value) + return &PointEd25519{value} +} + +func (p *PointEd25519) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *PointEd25519) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointEd25519) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointEd25519) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *PointEd25519) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointEd25519) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointEd25519) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *PointEd25519) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*PointEd25519) + if !ok { + return fmt.Errorf("invalid type") + } + p.value = P.value + return nil +} + +func (p *PointEd25519) GetEdwardsPoint() *edwards25519.Point { + return edwards25519.NewIdentityPoint().Set(p.value) +} + +func (p *PointEd25519) SetEdwardsPoint(pt *edwards25519.Point) *PointEd25519 { + return &PointEd25519{value: edwards25519.NewIdentityPoint().Set(pt)} +} + +// Attempt to convert to an `EdwardsPoint`, using the supplied +// choice of sign for the `EdwardsPoint`. +// - `sign`: a `u8` donating the desired sign of the resulting +// `EdwardsPoint`. `0` denotes positive and `1` negative. +func toEdwards(u *ed.FieldElement, sign byte) *PointEd25519 { + one := new(ed.FieldElement).SetOne() + // To decompress the Montgomery u coordinate to an + // `EdwardsPoint`, we apply the birational map to obtain the + // Edwards y coordinate, then do Edwards decompression. + // + // The birational map is y = (u-1)/(u+1). + // + // The exceptional points are the zeros of the denominator, + // i.e., u = -1. + // + // But when u = -1, v^2 = u*(u^2+486662*u+1) = 486660. + // + // Since this is nonsquare mod p, u = -1 corresponds to a point + // on the twist, not the curve, so we can reject it early. + if u.Equals(new(ed.FieldElement).Neg(one)) { + return nil + } + + // y = (u-1)/(u+1) + yLhs := new(ed.FieldElement).Sub(u, one) + yRhs := new(ed.FieldElement).Add(u, one) + yInv := new(ed.FieldElement).Inverse(yRhs) + y := new(ed.FieldElement).Mul(yLhs, yInv) + yBytes := y.Bytes() + yBytes[31] ^= sign << 7 + + pt, err := edwards25519.NewIdentityPoint().SetBytes(yBytes[:]) + if err != nil { + return nil + } + pt.MultByCofactor(pt) + return &PointEd25519{value: pt} +} + +// Perform the Elligator2 mapping to a Montgomery point encoded as a 32 byte value +// +// See +func elligatorEncode(r0 *ed.FieldElement) *ed.FieldElement { + montgomeryA := &ed.FieldElement{ + 486662, 0, 0, 0, 0, + } + // montgomeryANeg is equal to -486662. + montgomeryANeg := &ed.FieldElement{ + 2251799813198567, + 2251799813685247, + 2251799813685247, + 2251799813685247, + 2251799813685247, + } + t := new(ed.FieldElement) + one := new(ed.FieldElement).SetOne() + // 2r^2 + d1 := new(ed.FieldElement).Add(one, t.DoubledSquare(r0)) + // A/(1+2r^2) + d := new(ed.FieldElement).Mul(montgomeryANeg, t.Inverse(d1)) + dsq := new(ed.FieldElement).Square(d) + au := new(ed.FieldElement).Mul(montgomeryA, d) + + inner := new(ed.FieldElement).Add(dsq, au) + inner.Add(inner, one) + + // d^3 + Ad^2 + d + eps := new(ed.FieldElement).Mul(d, inner) + _, wasSquare := sqrtRatio(eps, one) + + zero := new(ed.FieldElement).SetZero() + aTemp := new(ed.FieldElement).SetZero() + // 0 or A if non-square + cselect(aTemp, zero, montgomeryA, wasSquare) + // d, or d+A if non-square + u := new(ed.FieldElement).Add(d, aTemp) + // d or -d-A if non-square + cselect(u, u, new(ed.FieldElement).Neg(u), wasSquare) + return u +} diff --git a/pkg/crypto/core/curves/ed25519_curve_test.go b/pkg/crypto/core/curves/ed25519_curve_test.go new file mode 100755 index 000000000..4c60befc1 --- /dev/null +++ b/pkg/crypto/core/curves/ed25519_curve_test.go @@ -0,0 +1,403 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + crand "crypto/rand" + "encoding/hex" + "math/big" + "testing" + + ed "filippo.io/edwards25519" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func TestScalarEd25519Random(t *testing.T) { + ed25519 := ED25519() + sc := ed25519.Scalar.Random(testRng()) + s, ok := sc.(*ScalarEd25519) + require.True(t, ok) + expected := toRSc("feaa6a9d6dda758da6145f7d411a3af9f8a120698e0093faa97085b384c3f00e") + require.Equal(t, s.value.Equal(expected), 1) + // Try 10 random values + for i := 0; i < 10; i++ { + sc := ed25519.Scalar.Random(crand.Reader) + _, ok := sc.(*ScalarEd25519) + require.True(t, ok) + require.True(t, !sc.IsZero()) + } +} + +func TestScalarEd25519Hash(t *testing.T) { + var b [32]byte + ed25519 := ED25519() + sc := ed25519.Scalar.Hash(b[:]) + s, ok := sc.(*ScalarEd25519) + require.True(t, ok) + expected := toRSc("9d574494a02d72f5ff311cf0fb844d0fdd6103b17255274e029bdeed7207d409") + require.Equal(t, s.value.Equal(expected), 1) +} + +func TestScalarEd25519Zero(t *testing.T) { + ed25519 := ED25519() + sc := ed25519.Scalar.Zero() + require.True(t, sc.IsZero()) + require.True(t, sc.IsEven()) +} + +func TestScalarEd25519One(t *testing.T) { + ed25519 := ED25519() + sc := ed25519.Scalar.One() + require.True(t, sc.IsOne()) + require.True(t, sc.IsOdd()) +} + +func TestScalarEd25519New(t *testing.T) { + ed25519 := ED25519() + three := ed25519.Scalar.New(3) + require.True(t, three.IsOdd()) + four := ed25519.Scalar.New(4) + require.True(t, four.IsEven()) + neg1 := ed25519.Scalar.New(-1) + require.True(t, neg1.IsEven()) + neg2 := ed25519.Scalar.New(-2) + require.True(t, neg2.IsOdd()) +} + +func TestScalarEd25519Square(t *testing.T) { + ed25519 := ED25519() + three := ed25519.Scalar.New(3) + nine := ed25519.Scalar.New(9) + require.Equal(t, three.Square().Cmp(nine), 0) +} + +func TestScalarEd25519Cube(t *testing.T) { + ed25519 := ED25519() + three := ed25519.Scalar.New(3) + twentySeven := ed25519.Scalar.New(27) + require.Equal(t, three.Cube().Cmp(twentySeven), 0) +} + +func TestScalarEd25519Double(t *testing.T) { + ed25519 := ED25519() + three := ed25519.Scalar.New(3) + six := ed25519.Scalar.New(6) + require.Equal(t, three.Double().Cmp(six), 0) +} + +func TestScalarEd25519Neg(t *testing.T) { + ed25519 := ED25519() + one := ed25519.Scalar.One() + neg1 := ed25519.Scalar.New(-1) + require.Equal(t, one.Neg().Cmp(neg1), 0) + lotsOfThrees := ed25519.Scalar.New(333333) + expected := ed25519.Scalar.New(-333333) + require.Equal(t, lotsOfThrees.Neg().Cmp(expected), 0) +} + +func TestScalarEd25519Invert(t *testing.T) { + ed25519 := ED25519() + nine := ed25519.Scalar.New(9) + actual, _ := nine.Invert() + sa, _ := actual.(*ScalarEd25519) + expected := toRSc("c3d9c4db0516043013b1e1ce8637dc92e3388ee3388ee3388ee3388ee3388e03") + require.Equal(t, sa.value.Equal(expected), 1) +} + +func TestScalarEd25519Sqrt(t *testing.T) { + ed25519 := ED25519() + nine := ed25519.Scalar.New(9) + actual, err := nine.Sqrt() + sa, _ := actual.(*ScalarEd25519) + expected := toRSc("03") + require.NoError(t, err) + require.Equal(t, sa.value.Equal(expected), 1) +} + +func TestScalarEd25519Add(t *testing.T) { + ed25519 := ED25519() + nine := ed25519.Scalar.New(9) + six := ed25519.Scalar.New(6) + fifteen := nine.Add(six) + require.NotNil(t, fifteen) + expected := ed25519.Scalar.New(15) + require.Equal(t, expected.Cmp(fifteen), 0) + + upper := ed25519.Scalar.New(-3) + actual := upper.Add(nine) + require.NotNil(t, actual) + require.Equal(t, actual.Cmp(six), 0) +} + +func TestScalarEd25519Sub(t *testing.T) { + ed25519 := ED25519() + nine := ed25519.Scalar.New(9) + six := ed25519.Scalar.New(6) + expected := ed25519.Scalar.New(-3) + + actual := six.Sub(nine) + require.Equal(t, expected.Cmp(actual), 0) + + actual = nine.Sub(six) + require.Equal(t, actual.Cmp(ed25519.Scalar.New(3)), 0) +} + +func TestScalarEd25519Mul(t *testing.T) { + ed25519 := ED25519() + nine := ed25519.Scalar.New(9) + six := ed25519.Scalar.New(6) + actual := nine.Mul(six) + require.Equal(t, actual.Cmp(ed25519.Scalar.New(54)), 0) + + upper := ed25519.Scalar.New(-1) + require.Equal(t, upper.Mul(upper).Cmp(ed25519.Scalar.New(1)), 0) +} + +func TestScalarEd25519Div(t *testing.T) { + ed25519 := ED25519() + nine := ed25519.Scalar.New(9) + actual := nine.Div(nine) + require.Equal(t, actual.Cmp(ed25519.Scalar.New(1)), 0) + require.Equal(t, ed25519.Scalar.New(54).Div(nine).Cmp(ed25519.Scalar.New(6)), 0) +} + +func TestScalarEd25519Serialize(t *testing.T) { + ed25519 := ED25519() + sc := ed25519.Scalar.New(255) + sequence := sc.Bytes() + require.Equal(t, len(sequence), 32) + require.Equal(t, sequence, []byte{0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}) + ret, err := ed25519.Scalar.SetBytes(sequence) + require.NoError(t, err) + require.Equal(t, ret.Cmp(sc), 0) + + // Try 10 random values + for i := 0; i < 10; i++ { + sc = ed25519.Scalar.Random(crand.Reader) + sequence = sc.Bytes() + require.Equal(t, len(sequence), 32) + ret, err = ed25519.Scalar.SetBytes(sequence) + require.NoError(t, err) + require.Equal(t, ret.Cmp(sc), 0) + } +} + +func TestScalarEd25519Nil(t *testing.T) { + ed25519 := ED25519() + one := ed25519.Scalar.New(1) + require.Nil(t, one.Add(nil)) + require.Nil(t, one.Sub(nil)) + require.Nil(t, one.Mul(nil)) + require.Nil(t, one.Div(nil)) + require.Nil(t, ed25519.Scalar.Random(nil)) + require.Equal(t, one.Cmp(nil), -2) + _, err := ed25519.Scalar.SetBigInt(nil) + require.Error(t, err) +} + +func TestPointEd25519Random(t *testing.T) { + ed25519 := ED25519() + sc := ed25519.Point.Random(testRng()) + s, ok := sc.(*PointEd25519) + require.True(t, ok) + expected := toRPt("6011540c6231421a70ced5f577432531f198d318facfaad6e52cc42fba6e6fc5") + require.True(t, s.Equal(&PointEd25519{expected})) + // Try 25 random values + for i := 0; i < 25; i++ { + sc := ed25519.Point.Random(crand.Reader) + _, ok := sc.(*PointEd25519) + require.True(t, ok) + require.True(t, !sc.IsIdentity()) + pBytes := sc.ToAffineCompressed() + _, err := ed.NewIdentityPoint().SetBytes(pBytes) + require.NoError(t, err) + } +} + +func TestPointEd25519Hash(t *testing.T) { + var b [32]byte + ed25519 := ED25519() + sc := ed25519.Point.Hash(b[:]) + s, ok := sc.(*PointEd25519) + require.True(t, ok) + expected := toRPt("b4d75c3bb03ca644ab6c6d2a955c911003d8cfa719415de93a6b85eeb0c8dd97") + require.True(t, s.Equal(&PointEd25519{expected})) + + // Fuzz test + for i := 0; i < 25; i++ { + _, _ = crand.Read(b[:]) + sc = ed25519.Point.Hash(b[:]) + require.NotNil(t, sc) + } +} + +func TestPointEd25519Identity(t *testing.T) { + ed25519 := ED25519() + sc := ed25519.Point.Identity() + require.True(t, sc.IsIdentity()) + require.Equal(t, sc.ToAffineCompressed(), []byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) +} + +func TestPointEd25519Generator(t *testing.T) { + ed25519 := ED25519() + sc := ed25519.Point.Generator() + s, ok := sc.(*PointEd25519) + require.True(t, ok) + require.Equal(t, s.ToAffineCompressed(), []byte{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}) +} + +func TestPointEd25519Set(t *testing.T) { + ed25519 := ED25519() + iden, err := ed25519.Point.Set(big.NewInt(0), big.NewInt(0)) + require.NoError(t, err) + require.True(t, iden.IsIdentity()) + xBytes, _ := hex.DecodeString("1ad5258f602d56c9b2a7259560c72c695cdcd6fd31e2a4c0fe536ecdd3366921") + yBytes, _ := hex.DecodeString("5866666666666666666666666666666666666666666666666666666666666666") + x := new(big.Int).SetBytes(internal.ReverseScalarBytes(xBytes)) + y := new(big.Int).SetBytes(internal.ReverseScalarBytes(yBytes)) + newPoint, err := ed25519.Point.Set(x, y) + require.NoError(t, err) + require.NotEqualf(t, iden, newPoint, "after setting valid x and y, the point should NOT be identity point") + + emptyX := new(big.Int).SetBytes(internal.ReverseScalarBytes([]byte{})) + identityPoint, err := ed25519.Point.Set(emptyX, y) + require.NoError(t, err) + require.Equalf(t, iden, identityPoint, "When x is empty, the point will be identity") +} + +func TestPointEd25519Double(t *testing.T) { + ed25519 := ED25519() + g := ed25519.Point.Generator() + g2 := g.Double() + require.True(t, g2.Equal(g.Mul(ed25519.Scalar.New(2)))) + i := ed25519.Point.Identity() + require.True(t, i.Double().Equal(i)) +} + +func TestPointEd25519Neg(t *testing.T) { + ed25519 := ED25519() + g := ed25519.Point.Generator().Neg() + require.True(t, g.Neg().Equal(ed25519.Point.Generator())) + require.True(t, ed25519.Point.Identity().Neg().Equal(ed25519.Point.Identity())) +} + +func TestPointEd25519Add(t *testing.T) { + ed25519 := ED25519() + pt := ed25519.Point.Generator() + require.True(t, pt.Add(pt).Equal(pt.Double())) + require.True(t, pt.Mul(ed25519.Scalar.New(3)).Equal(pt.Add(pt).Add(pt))) +} + +func TestPointEd25519Sub(t *testing.T) { + ed25519 := ED25519() + g := ed25519.Point.Generator() + pt := ed25519.Point.Generator().Mul(ed25519.Scalar.New(4)) + require.True(t, pt.Sub(g).Sub(g).Sub(g).Equal(g)) + require.True(t, pt.Sub(g).Sub(g).Sub(g).Sub(g).IsIdentity()) +} + +func TestPointEd25519Mul(t *testing.T) { + ed25519 := ED25519() + g := ed25519.Point.Generator() + pt := ed25519.Point.Generator().Mul(ed25519.Scalar.New(4)) + require.True(t, g.Double().Double().Equal(pt)) +} + +func TestPointEd25519Serialize(t *testing.T) { + ed25519 := ED25519() + ss := ed25519.Scalar.Random(testRng()) + g := ed25519.Point.Generator() + + ppt := g.Mul(ss) + expectedC := []byte{0x7f, 0x5b, 0xa, 0xd9, 0xb8, 0xce, 0xb7, 0x7, 0x4c, 0x10, 0xc8, 0xb4, 0x27, 0xe8, 0xd2, 0x28, 0x50, 0x42, 0x6c, 0x0, 0x8a, 0x3, 0x72, 0x2b, 0x7c, 0x3c, 0x37, 0x6f, 0xf8, 0x8f, 0x42, 0x5d} + expectedU := []byte{0x70, 0xad, 0x4, 0xa1, 0x6, 0x8, 0x9f, 0x47, 0xe1, 0xe8, 0x9b, 0x9c, 0x81, 0x5a, 0xfb, 0xb9, 0x85, 0x6a, 0x2c, 0xa, 0xbc, 0xff, 0xe, 0xc6, 0xa0, 0xb0, 0xac, 0x75, 0xc, 0xd8, 0x59, 0x53, 0x7f, 0x5b, 0xa, 0xd9, 0xb8, 0xce, 0xb7, 0x7, 0x4c, 0x10, 0xc8, 0xb4, 0x27, 0xe8, 0xd2, 0x28, 0x50, 0x42, 0x6c, 0x0, 0x8a, 0x3, 0x72, 0x2b, 0x7c, 0x3c, 0x37, 0x6f, 0xf8, 0x8f, 0x42, 0x5d} + require.Equal(t, ppt.ToAffineCompressed(), expectedC) + require.Equal(t, ppt.ToAffineUncompressed(), expectedU) + retP, err := ppt.FromAffineCompressed(ppt.ToAffineCompressed()) + require.NoError(t, err) + require.True(t, ppt.Equal(retP)) + retP, err = ppt.FromAffineUncompressed(ppt.ToAffineUncompressed()) + require.NoError(t, err) + require.True(t, ppt.Equal(retP)) + + // smoke test + for i := 0; i < 25; i++ { + s := ed25519.Scalar.Random(crand.Reader) + pt := g.Mul(s) + cmprs := pt.ToAffineCompressed() + require.Equal(t, len(cmprs), 32) + retC, err := pt.FromAffineCompressed(cmprs) + require.NoError(t, err) + require.True(t, pt.Equal(retC)) + + un := pt.ToAffineUncompressed() + require.Equal(t, len(un), 64) + retU, err := pt.FromAffineUncompressed(un) + require.NoError(t, err) + require.True(t, pt.Equal(retU)) + } +} + +func TestPointEd25519Nil(t *testing.T) { + ed25519 := ED25519() + one := ed25519.Point.Generator() + require.Nil(t, one.Add(nil)) + require.Nil(t, one.Sub(nil)) + require.Nil(t, one.Mul(nil)) + require.Nil(t, ed25519.Scalar.Random(nil)) + require.False(t, one.Equal(nil)) + _, err := ed25519.Scalar.SetBigInt(nil) + require.Error(t, err) +} + +func TestPointEd25519SumOfProducts(t *testing.T) { + lhs := new(PointEd25519).Generator().Mul(new(ScalarEd25519).New(50)) + points := make([]Point, 5) + for i := range points { + points[i] = new(PointEd25519).Generator() + } + scalars := []Scalar{ + new(ScalarEd25519).New(8), + new(ScalarEd25519).New(9), + new(ScalarEd25519).New(10), + new(ScalarEd25519).New(11), + new(ScalarEd25519).New(12), + } + rhs := lhs.SumOfProducts(points, scalars) + require.NotNil(t, rhs) + require.True(t, lhs.Equal(rhs)) +} + +func TestPointEd25519VarTimeDoubleScalarBaseMult(t *testing.T) { + curve := ED25519() + h := curve.Point.Hash([]byte("TestPointEd25519VarTimeDoubleScalarBaseMult")) + a := curve.Scalar.New(23) + b := curve.Scalar.New(77) + H, ok := h.(*PointEd25519) + require.True(t, ok) + rhs := H.VarTimeDoubleScalarBaseMult(a, H, b) + lhs := h.Mul(a).Add(curve.Point.Generator().Mul(b)) + require.True(t, lhs.Equal(rhs)) +} + +func toRSc(hx string) *ed.Scalar { + e, _ := hex.DecodeString(hx) + var data [32]byte + copy(data[:], e) + value, _ := new(ed.Scalar).SetCanonicalBytes(data[:]) + return value +} + +func toRPt(hx string) *ed.Point { + e, _ := hex.DecodeString(hx) + var data [32]byte + copy(data[:], e) + pt, _ := new(PointEd25519).FromAffineCompressed(data[:]) + return pt.(*PointEd25519).value +} diff --git a/pkg/crypto/core/curves/field.go b/pkg/crypto/core/curves/field.go new file mode 100755 index 000000000..946aac872 --- /dev/null +++ b/pkg/crypto/core/curves/field.go @@ -0,0 +1,280 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package curves: Field implementation IS NOT constant time as it leverages math/big for big number operations. +package curves + +import ( + "crypto/rand" + "encoding/json" + "fmt" + "io" + "math/big" + "sync" +) + +var ed25519SubGroupOrderOnce sync.Once +var ed25519SubGroupOrder *big.Int + +// Field is a finite field. +type Field struct { + *big.Int +} + +// Element is a group element within a finite field. +type Element struct { + Modulus *Field `json:"modulus"` + Value *big.Int `json:"value"` +} + +// ElementJSON is used in JSON<>Element conversions. +// For years, big.Int hasn't properly supported JSON unmarshaling +// https://github.com/golang/go/issues/28154 +type ElementJSON struct { + Modulus string `json:"modulus"` + Value string `json:"value"` +} + +// Marshal Element to JSON +func (x *Element) MarshalJSON() ([]byte, error) { + return json.Marshal(ElementJSON{ + Modulus: x.Modulus.String(), + Value: x.Value.String(), + }) +} + +func (x *Element) UnmarshalJSON(bytes []byte) error { + var e ElementJSON + err := json.Unmarshal(bytes, &e) + if err != nil { + return err + } + // Convert the strings to big.Ints + modulus, ok := new(big.Int).SetString(e.Modulus, 10) + if !ok { + return fmt.Errorf("failed to unmarshal modulus string '%v' to big.Int", e.Modulus) + } + x.Modulus = &Field{modulus} + x.Value, ok = new(big.Int).SetString(e.Value, 10) + if !ok { + return fmt.Errorf("failed to unmarshal value string '%v' to big.Int", e.Value) + } + return nil +} + +// The probability of returning true for a randomly chosen +// non-prime is at most ¼ⁿ. 64 is a widely used standard +// that is more than sufficient. +const millerRabinRounds = 64 + +// New is a constructor for a Field. +func NewField(modulus *big.Int) *Field { + // For our purposes we never expect to be dealing with a non-prime field. This provides some protection against + // accidentally doing that. + if !modulus.ProbablyPrime(millerRabinRounds) { + panic(fmt.Sprintf("modulus: %x is not a prime", modulus)) + } + + return &Field{modulus} +} + +func newElement(field *Field, value *big.Int) *Element { + if !field.IsValid(value) { + panic(fmt.Sprintf("value: %x is not within field: %x", value, field)) + } + + return &Element{field, value} +} + +// IsValid returns whether or not the value is within [0, modulus) +func (f Field) IsValid(value *big.Int) bool { + // value < modulus && value >= 0 + return value.Cmp(f.Int) < 0 && value.Sign() >= 0 +} + +func (f Field) NewElement(value *big.Int) *Element { + return newElement(&f, value) +} + +func (f Field) Zero() *Element { + return newElement(&f, big.NewInt(0)) +} + +func (f Field) One() *Element { + return newElement(&f, big.NewInt(1)) +} + +func (f Field) RandomElement(r io.Reader) (*Element, error) { + if r == nil { + r = rand.Reader + } + var randInt *big.Int + var err error + // Ed25519 needs to do special handling + // in case the value is used in + // Scalar multiplications with points + if f.Int.Cmp(Ed25519Order()) == 0 { + scalar := NewEd25519Scalar() + randInt, err = scalar.RandomWithReader(r) + } else { + // Read a random integer within the field. This is defined as [0, max) so we don't need to + // explicitly check it is within the field. If it is not, NewElement will panic anyways. + randInt, err = rand.Int(r, f.Int) + } + if err != nil { + return nil, err + } + return newElement(&f, randInt), nil +} + +// ElementFromBytes initializes a new field element from big-endian bytes +func (f Field) ElementFromBytes(bytes []byte) *Element { + return newElement(&f, new(big.Int).SetBytes(bytes)) +} + +// ReducedElementFromBytes initializes a new field element from big-endian bytes and reduces it by +// the modulus of the field. +// +// WARNING: If this is used with cryptographic constructions which rely on a uniform distribution of +// values, this may introduce a bias to the value of the returned field element. This happens when +// the integer range of the provided bytes is not an integer multiple of the field order. +// +// Assume we are working in field which a modulus of 3 and the range of the uniform random bytes we +// provide as input is 5. Thus, the set of field elements is {0, 1, 2} and the set of integer values +// for the input bytes is: {0, 1, 2, 3, 4}. What is the distribution of the output values produced +// by this function? +// +// ReducedElementFromBytes(0) => 0 +// ReducedElementFromBytes(1) => 1 +// ReducedElementFromBytes(2) => 2 +// ReducedElementFromBytes(3) => 0 +// ReducedElementFromBytes(4) => 1 +// +// For a value space V and random value v, a uniform distribution is defined as P[V = v] = 1/|V| +// where |V| is to the order of the field. Using the results from above, we see that P[v = 0] = 2/5, +// P[v = 1] = 2/5, and P[v = 2] = 1/5. For a uniform distribution we would expect these to each be +// equal to 1/3. As they do not, this does not return uniform output for that example. +// +// To see why this is okay if the range is a multiple of the field order, change the input range to +// 6 and notice that now each output has a probability of 2/6 = 1/3, and the output is uniform. +func (f Field) ReducedElementFromBytes(bytes []byte) *Element { + value := new(big.Int).SetBytes(bytes) + value.Mod(value, f.Int) + return newElement(&f, value) +} + +func (x Element) Field() *Field { + return x.Modulus +} + +// Add returns the sum x+y +func (x Element) Add(y *Element) *Element { + x.validateFields(y) + + sum := new(big.Int).Add(x.Value, y.Value) + sum.Mod(sum, x.Modulus.Int) + return newElement(x.Modulus, sum) +} + +// Sub returns the difference x-y +func (x Element) Sub(y *Element) *Element { + x.validateFields(y) + + difference := new(big.Int).Sub(x.Value, y.Value) + difference.Mod(difference, x.Modulus.Int) + return newElement(x.Modulus, difference) +} + +// Neg returns the field negation +func (x Element) Neg() *Element { + z := new(big.Int).Neg(x.Value) + z.Mod(z, x.Modulus.Int) + return newElement(x.Modulus, z) +} + +// Mul returns the product x*y +func (x Element) Mul(y *Element) *Element { + x.validateFields(y) + + product := new(big.Int).Mul(x.Value, y.Value) + product.Mod(product, x.Modulus.Int) + return newElement(x.Modulus, product) +} + +// Div returns the quotient x/y +func (x Element) Div(y *Element) *Element { + x.validateFields(y) + + yInv := new(big.Int).ModInverse(y.Value, x.Modulus.Int) + quotient := new(big.Int).Mul(x.Value, yInv) + quotient.Mod(quotient, x.Modulus.Int) + return newElement(x.Modulus, quotient) +} + +// Pow computes x^y reduced by the modulus +func (x Element) Pow(y *Element) *Element { + x.validateFields(y) + + return newElement(x.Modulus, new(big.Int).Exp(x.Value, y.Value, x.Modulus.Int)) +} + +func (x Element) Invert() *Element { + return newElement(x.Modulus, new(big.Int).ModInverse(x.Value, x.Modulus.Int)) +} + +func (x Element) Sqrt() *Element { + return newElement(x.Modulus, new(big.Int).ModSqrt(x.Value, x.Modulus.Int)) +} + +// BigInt returns value as a big.Int +func (x Element) BigInt() *big.Int { + return x.Value +} + +// Bytes returns the value as bytes +func (x Element) Bytes() []byte { + return x.BigInt().Bytes() +} + +// IsEqual returns x == y +func (x Element) IsEqual(y *Element) bool { + if !x.isEqualFields(y) { + return false + } + + return x.Value.Cmp(y.Value) == 0 +} + +// Clone returns a new copy of the element +func (x Element) Clone() *Element { + return x.Modulus.ElementFromBytes(x.Bytes()) +} + +func (x Element) isEqualFields(y *Element) bool { + return x.Modulus.Int.Cmp(y.Modulus.Int) == 0 +} + +func (x Element) validateFields(y *Element) { + if !x.isEqualFields(y) { + panic("fields must match for valid binary operation") + } +} + +// SubgroupOrder returns the order of the Ed25519 base Point. +func Ed25519Order() *big.Int { + ed25519SubGroupOrderOnce.Do(func() { + order, ok := new(big.Int).SetString( + "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + 16, + ) + if !ok { + panic("invalid hex string provided. This should never happen as it is constant.") + } + ed25519SubGroupOrder = order + }) + + return ed25519SubGroupOrder +} diff --git a/pkg/crypto/core/curves/field_test.go b/pkg/crypto/core/curves/field_test.go new file mode 100755 index 000000000..cd260b316 --- /dev/null +++ b/pkg/crypto/core/curves/field_test.go @@ -0,0 +1,301 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "encoding/json" + "errors" + "fmt" + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +var ( + one = big.NewInt(1) + modulus, modulusOk = new(big.Int).SetString( + "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + 16, + ) + oneBelowModulus = zero().Sub(modulus, one) + oneAboveModulus = zero().Add(modulus, one) + field25519 = NewField(modulus) +) + +type buggedReader struct{} + +func (r buggedReader) Read(p []byte) (n int, err error) { + return 0, errors.New("EOF") +} + +func zero() *big.Int { + return new(big.Int) +} + +func assertElementZero(t *testing.T, e *Element) { + require.Equal(t, zero().Bytes(), e.Bytes()) +} + +type binaryOperation func(*Element) *Element + +func assertUnequalFieldsPanic(t *testing.T, b binaryOperation) { + altField := NewField(big.NewInt(23)) + altElement := altField.NewElement(one) + + require.PanicsWithValue( + t, + "fields must match for valid binary operation", + func() { b(altElement) }, + ) +} + +func TestFieldModulus(t *testing.T) { + require.True(t, modulusOk) +} + +func TestNewField(t *testing.T) { + require.PanicsWithValue( + t, + fmt.Sprintf("modulus: %x is not a prime", oneBelowModulus), + func() { NewField(oneBelowModulus) }, + ) + require.NotPanics( + t, + func() { NewField(modulus) }, + ) +} + +func TestNewElement(t *testing.T) { + require.PanicsWithValue( + t, + fmt.Sprintf("value: %x is not within field: %x", modulus, field25519.Int), + func() { newElement(field25519, modulus) }, + ) + require.NotPanics( + t, + func() { newElement(field25519, oneBelowModulus) }, + ) +} + +func TestElementIsValid(t *testing.T) { + require.False(t, field25519.IsValid(zero().Neg(one))) + require.False(t, field25519.IsValid(modulus)) + require.False(t, field25519.IsValid(oneAboveModulus)) + require.True(t, field25519.IsValid(oneBelowModulus)) +} + +func TestFieldNewElement(t *testing.T) { + element := field25519.NewElement(oneBelowModulus) + + require.Equal(t, oneBelowModulus, element.Value) + require.Equal(t, field25519, element.Field()) +} + +func TestZeroElement(t *testing.T) { + require.Equal(t, zero(), field25519.Zero().Value) + require.Equal(t, field25519, field25519.Zero().Field()) +} + +func TestOneElement(t *testing.T) { + require.Equal(t, field25519.One().Value, one) + require.Equal(t, field25519.One().Field(), field25519) +} + +func TestRandomElement(t *testing.T) { + randomElement1, err := field25519.RandomElement(nil) + require.NoError(t, err) + randomElement2, err := field25519.RandomElement(nil) + require.NoError(t, err) + randomElement3, err := field25519.RandomElement(new(buggedReader)) + require.Error(t, err) + + require.Equal(t, field25519, randomElement1.Field()) + require.Equal(t, field25519, randomElement2.Field()) + require.NotEqual(t, randomElement1.Value, randomElement2.Value) + require.Nil(t, randomElement3) +} + +func TestElementFromBytes(t *testing.T) { + element := field25519.ElementFromBytes(oneBelowModulus.Bytes()) + + require.Equal(t, field25519, element.Field()) + require.Equal(t, oneBelowModulus, element.Value) +} + +func TestReducedElementFromBytes(t *testing.T) { + element := field25519.ReducedElementFromBytes(oneBelowModulus.Bytes()) + + require.Equal(t, field25519, element.Field()) + require.Equal(t, oneBelowModulus, element.Value) + + element = field25519.ReducedElementFromBytes(oneAboveModulus.Bytes()) + + require.Equal(t, field25519, element.Field()) + require.Equal(t, one, element.Value) +} + +func TestAddElement(t *testing.T) { + element1 := field25519.NewElement(one) + element2 := field25519.NewElement(big.NewInt(2)) + element3 := field25519.NewElement(oneBelowModulus) + element4 := &Element{field25519, modulus} + + require.Equal(t, element2, element1.Add(element1)) + require.Equal(t, big.NewInt(3), element1.Add(element2).Value) + require.Equal(t, big.NewInt(3), element2.Add(element1).Value) + require.Equal(t, one, element1.Add(element4).Value) + require.Equal(t, one, element3.Add(element2).Value) + assertElementZero(t, element1.Add(element3)) + assertUnequalFieldsPanic(t, element1.Add) +} + +func TestSubElement(t *testing.T) { + element1 := field25519.NewElement(one) + element2 := field25519.NewElement(big.NewInt(2)) + element3 := field25519.NewElement(oneBelowModulus) + element4 := &Element{field25519, modulus} + + assertElementZero(t, element1.Sub(element1)) + require.Equal(t, element3, element1.Sub(element2)) + require.Equal(t, element1, element2.Sub(element1)) + require.Equal(t, element1, element1.Sub(element4)) + require.Equal(t, element3, element4.Sub(element1)) + require.Equal(t, element1, element4.Sub(element3)) + require.Equal(t, element3, element3.Sub(element4)) + assertUnequalFieldsPanic(t, element1.Sub) +} + +func TestMulElement(t *testing.T) { + element1 := field25519.NewElement(one) + element2 := field25519.NewElement(big.NewInt(2)) + element3 := field25519.NewElement(oneBelowModulus) + element4 := field25519.NewElement(zero()) + expectedProduct, ok := new(big.Int).SetString( + "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3eb", + 16, + ) + require.True(t, ok) + + assertElementZero(t, element1.Mul(element4)) + assertElementZero(t, element4.Mul(element1)) + require.Equal(t, element3, element1.Mul(element3)) + require.Equal(t, element3, element3.Mul(element1)) + require.Equal(t, expectedProduct, element3.Mul(element2).Value) + require.Equal(t, expectedProduct, element2.Mul(element3).Value) + assertUnequalFieldsPanic(t, element1.Mul) +} + +func TestDivElement(t *testing.T) { + element1 := field25519.NewElement(one) + element2 := field25519.NewElement(big.NewInt(2)) + element3 := field25519.NewElement(oneBelowModulus) + element4 := field25519.NewElement(zero()) + expectedQuotient1, ok := new(big.Int).SetString( + "80000000000000000000000000000000a6f7cef517bce6b2c09318d2e7ae9f6", + 16, + ) + require.True(t, ok) + expectedQuotient2, ok := new(big.Int).SetString( + "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3eb", + 16, + ) + require.True(t, ok) + + assertElementZero(t, element4.Div(element3)) + require.Equal(t, element3, element3.Div(element1)) + require.Equal(t, expectedQuotient1, element3.Div(element2).Value) + require.Equal(t, expectedQuotient2, element2.Div(element3).Value) + require.Panics(t, func() { element3.Div(element4) }) + assertUnequalFieldsPanic(t, element1.Div) +} + +func TestIsEqualElement(t *testing.T) { + element1 := field25519.NewElement(oneBelowModulus) + element2 := field25519.NewElement(big.NewInt(23)) + element3 := field25519.NewElement(oneBelowModulus) + altField := NewField(big.NewInt(23)) + altElement1 := altField.NewElement(one) + + require.False(t, element1.IsEqual(element2)) + require.True(t, element1.IsEqual(element3)) + require.True(t, element1.IsEqual(element1)) + require.False(t, element1.IsEqual(altElement1)) +} + +func TestBigIntElement(t *testing.T) { + element := field25519.NewElement(oneBelowModulus) + + require.Equal(t, oneBelowModulus, element.BigInt()) +} + +func TestBytesElement(t *testing.T) { + element := field25519.NewElement(oneBelowModulus) + + require.Equal( + t, + []byte{ + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0xde, 0xf9, 0xde, 0xa2, + 0xf7, 0x9c, 0xd6, 0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, + 0xd3, 0xec, + }, + element.Bytes(), + ) +} + +func TestCloneElement(t *testing.T) { + element := field25519.NewElement(oneBelowModulus) + clone := element.Clone() + + require.Equal(t, clone, element) + + clone.Value.Add(one, one) + + require.NotEqual(t, clone, element) +} + +// Tests un/marshaling Element +func TestElementMarshalJsonRoundTrip(t *testing.T) { + reallyBigInt1, ok := new(big.Int).SetString("12365234878725472538962348629568356835892346729834725643857832", 10) + require.True(t, ok) + + reallyBigInt2, ok := new(big.Int).SetString("123652348787DEF9DEA2F79CD65812631A5CF5D3ED46729834725643857832", 16) + require.True(t, ok) + + ins := []*Element{ + newElement(field25519, big.NewInt(300)), + newElement(field25519, big.NewInt(300000)), + newElement(field25519, big.NewInt(12812798)), + newElement(field25519, big.NewInt(17)), + newElement(field25519, big.NewInt(5066680)), + newElement(field25519, big.NewInt(3005)), + newElement(field25519, big.NewInt(317)), + newElement(field25519, big.NewInt(323)), + newElement(field25519, reallyBigInt1), + newElement(field25519, reallyBigInt2), + newElement(field25519, oneBelowModulus), + } + + // Run all the tests! + for _, in := range ins { + bytes, err := json.Marshal(in) + require.NoError(t, err) + require.NotNil(t, bytes) + + // Unmarshal and test + out := &Element{} + err = json.Unmarshal(bytes, &out) + require.NoError(t, err) + require.NotNil(t, out) + require.NotNil(t, out.Modulus) + require.NotNil(t, out.Value) + + require.Equal(t, in.Modulus.Bytes(), out.Modulus.Bytes()) + require.Equal(t, in.Value.Bytes(), out.Value.Bytes()) + } +} diff --git a/pkg/crypto/core/curves/k256_bench_test.go b/pkg/crypto/core/curves/k256_bench_test.go new file mode 100755 index 000000000..9d97910b2 --- /dev/null +++ b/pkg/crypto/core/curves/k256_bench_test.go @@ -0,0 +1,446 @@ +package curves + +import ( + crand "crypto/rand" + "crypto/sha256" + "io" + "math/big" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + + mod "github.com/onsonr/sonr/pkg/crypto/core" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func BenchmarkK256(b *testing.B) { + // 1000 points + b.Run("1000 point add - btcec", func(b *testing.B) { + b.StopTimer() + points := make([]*BenchPoint, 1000) + for i := range points { + points[i] = points[i].Random(crand.Reader).(*BenchPoint) + } + acc := new(BenchPoint).Identity() + b.StartTimer() + for _, pt := range points { + acc = acc.Add(pt) + } + }) + b.Run("1000 point add - ct k256", func(b *testing.B) { + b.StopTimer() + curve := K256() + points := make([]*PointK256, 1000) + for i := range points { + points[i] = curve.NewIdentityPoint().Random(crand.Reader).(*PointK256) + } + acc := curve.NewIdentityPoint() + b.StartTimer() + for _, pt := range points { + acc = acc.Add(pt) + } + }) + b.Run("1000 point double - btcec", func(b *testing.B) { + b.StopTimer() + acc := new(BenchPoint).Generator() + b.StartTimer() + for i := 0; i < 1000; i++ { + acc = acc.Double() + } + }) + b.Run("1000 point double - ct k256", func(b *testing.B) { + b.StopTimer() + acc := new(PointK256).Generator() + b.StartTimer() + for i := 0; i < 1000; i++ { + acc = acc.Double() + } + }) + b.Run("1000 point multiply - btcec", func(b *testing.B) { + b.StopTimer() + scalars := make([]*BenchScalar, 1000) + for i := range scalars { + s := new(BenchScalar).Random(crand.Reader) + scalars[i] = s.(*BenchScalar) + } + acc := new(BenchPoint).Generator().Mul(new(BenchScalar).New(2)) + b.StartTimer() + for _, sc := range scalars { + acc = acc.Mul(sc) + } + }) + b.Run("1000 point multiply - ct k256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*ScalarK256, 1000) + for i := range scalars { + s := new(ScalarK256).Random(crand.Reader) + scalars[i] = s.(*ScalarK256) + } + acc := new(PointK256).Generator() + b.StartTimer() + for _, sc := range scalars { + acc = acc.Mul(sc) + } + }) + b.Run("1000 scalar invert - btcec", func(b *testing.B) { + b.StopTimer() + scalars := make([]*BenchScalar, 1000) + for i := range scalars { + s := new(BenchScalar).Random(crand.Reader) + scalars[i] = s.(*BenchScalar) + } + b.StartTimer() + for _, sc := range scalars { + _, _ = sc.Invert() + } + }) + b.Run("1000 scalar invert - ct k256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*ScalarK256, 1000) + for i := range scalars { + s := new(ScalarK256).Random(crand.Reader) + scalars[i] = s.(*ScalarK256) + } + b.StartTimer() + for _, sc := range scalars { + _, _ = sc.Invert() + } + }) + b.Run("1000 scalar sqrt - btcec", func(b *testing.B) { + b.StopTimer() + scalars := make([]*BenchScalar, 1000) + for i := range scalars { + s := new(BenchScalar).Random(crand.Reader) + scalars[i] = s.(*BenchScalar) + } + b.StartTimer() + for _, sc := range scalars { + _, _ = sc.Sqrt() + } + }) + b.Run("1000 scalar sqrt - ct k256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*ScalarK256, 1000) + for i := range scalars { + s := new(ScalarK256).Random(crand.Reader) + scalars[i] = s.(*ScalarK256) + } + b.StartTimer() + for _, sc := range scalars { + _, _ = sc.Sqrt() + } + }) +} + +type BenchScalar struct { + value *big.Int +} + +func (s *BenchScalar) Random(reader io.Reader) Scalar { + var v [32]byte + _, _ = reader.Read(v[:]) + value := new(big.Int).SetBytes(v[:]) + return &BenchScalar{ + value: value.Mod(value, btcec.S256().N), + } +} + +func (s *BenchScalar) Hash(bytes []byte) Scalar { + h := sha256.Sum256(bytes) + value := new(big.Int).SetBytes(h[:]) + return &BenchScalar{ + value: value.Mod(value, btcec.S256().N), + } +} + +func (s *BenchScalar) Zero() Scalar { + return &BenchScalar{ + value: big.NewInt(0), + } +} + +func (s *BenchScalar) One() Scalar { + return &BenchScalar{ + value: big.NewInt(1), + } +} + +func (s *BenchScalar) IsZero() bool { + return s.value.Cmp(big.NewInt(0)) == 0 +} + +func (s *BenchScalar) IsOne() bool { + return s.value.Cmp(big.NewInt(1)) == 0 +} + +func (s *BenchScalar) IsOdd() bool { + return s.value.Bit(0) == 1 +} + +func (s *BenchScalar) IsEven() bool { + return s.value.Bit(0) == 0 +} + +func (s *BenchScalar) New(value int) Scalar { + v := big.NewInt(int64(value)) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) Cmp(rhs Scalar) int { + r := rhs.(*BenchScalar) + return s.value.Cmp(r.value) +} + +func (s *BenchScalar) Square() Scalar { + v := new(big.Int).Mul(s.value, s.value) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) Double() Scalar { + v := new(big.Int).Add(s.value, s.value) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) Invert() (Scalar, error) { + return &BenchScalar{ + value: new(big.Int).ModInverse(s.value, btcec.S256().N), + }, nil +} + +func (s *BenchScalar) Sqrt() (Scalar, error) { + return &BenchScalar{ + value: new(big.Int).ModSqrt(s.value, btcec.S256().N), + }, nil +} + +func (s *BenchScalar) Cube() Scalar { + v := new(big.Int).Mul(s.value, s.value) + v.Mul(v, s.value) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) Add(rhs Scalar) Scalar { + r := rhs.(*BenchScalar) + v := new(big.Int).Add(s.value, r.value) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) Sub(rhs Scalar) Scalar { + r := rhs.(*BenchScalar) + v := new(big.Int).Sub(s.value, r.value) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) Mul(rhs Scalar) Scalar { + r := rhs.(*BenchScalar) + v := new(big.Int).Mul(s.value, r.value) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) MulAdd(y, z Scalar) Scalar { + yy := y.(*BenchScalar) + zz := z.(*BenchScalar) + v := new(big.Int).Mul(s.value, yy.value) + v.Add(v, zz.value) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) Div(rhs Scalar) Scalar { + r := rhs.(*BenchScalar) + v := new(big.Int).ModInverse(r.value, btcec.S256().N) + v.Mul(v, s.value) + return &BenchScalar{ + value: v.Mod(v, btcec.S256().N), + } +} + +func (s *BenchScalar) Neg() Scalar { + v, _ := mod.Neg(s.value, btcec.S256().N) + return &BenchScalar{ + value: v, + } +} + +func (s *BenchScalar) SetBigInt(v *big.Int) (Scalar, error) { + return &BenchScalar{ + value: new(big.Int).Set(v), + }, nil +} + +func (s *BenchScalar) BigInt() *big.Int { + return new(big.Int).Set(s.value) +} + +func (s *BenchScalar) Point() Point { + return (&BenchPoint{}).Identity() +} + +func (s *BenchScalar) Bytes() []byte { + return internal.ReverseScalarBytes(s.value.Bytes()) +} + +func (s *BenchScalar) SetBytes(bytes []byte) (Scalar, error) { + value := new(big.Int).SetBytes(internal.ReverseScalarBytes(bytes)) + value.Mod(value, btcec.S256().N) + return &BenchScalar{ + value, + }, nil +} + +func (s *BenchScalar) SetBytesWide(bytes []byte) (Scalar, error) { + value := new(big.Int).SetBytes(internal.ReverseScalarBytes(bytes)) + value.Mod(value, btcec.S256().N) + return &BenchScalar{ + value, + }, nil +} + +func (s *BenchScalar) Clone() Scalar { + return &BenchScalar{ + value: new(big.Int).Set(s.value), + } +} + +type BenchPoint struct { + x, y *big.Int +} + +func (p *BenchPoint) Random(reader io.Reader) Point { + var k [32]byte + curve := btcec.S256() + _, _ = reader.Read(k[:]) + x, y := curve.ScalarBaseMult(k[:]) + for !curve.IsOnCurve(x, y) { + _, _ = reader.Read(k[:]) + x, y = curve.ScalarBaseMult(k[:]) + } + return &BenchPoint{x, y} +} + +func (p *BenchPoint) Hash(bytes []byte) Point { + return nil +} + +func (p *BenchPoint) Identity() Point { + return &BenchPoint{x: big.NewInt(0), y: big.NewInt(0)} +} + +func (p *BenchPoint) Generator() Point { + return &BenchPoint{ + x: new(big.Int).Set(btcec.S256().Gx), + y: new(big.Int).Set(btcec.S256().Gy), + } +} + +func (p *BenchPoint) IsIdentity() bool { + return false +} + +func (p *BenchPoint) IsNegative() bool { + return false +} + +func (p *BenchPoint) IsOnCurve() bool { + return btcec.S256().IsOnCurve(p.x, p.y) +} + +func (p *BenchPoint) Double() Point { + x, y := btcec.S256().Double(p.x, p.y) + return &BenchPoint{ + x, y, + } +} + +func (p *BenchPoint) Scalar() Scalar { + return &BenchScalar{value: big.NewInt(0)} +} + +func (p *BenchPoint) Neg() Point { + y, _ := mod.Neg(p.y, btcec.S256().P) + return &BenchPoint{ + x: new(big.Int).Set(p.x), y: y, + } +} + +func (p *BenchPoint) Add(rhs Point) Point { + r := rhs.(*BenchPoint) + x, y := btcec.S256().Add(p.x, p.y, r.x, r.y) + return &BenchPoint{ + x, y, + } +} + +func (p *BenchPoint) Sub(rhs Point) Point { + t := rhs.Neg().(*BenchPoint) + return t.Add(p) +} + +func (p *BenchPoint) Mul(rhs Scalar) Point { + k := rhs.Bytes() + x, y := btcec.S256().ScalarMult(p.x, p.y, k) + return &BenchPoint{ + x, y, + } +} + +func (p *BenchPoint) Equal(rhs Point) bool { + r := rhs.(*BenchPoint) + return p.x.Cmp(r.x) == 0 && p.y.Cmp(r.y) == 0 +} + +func (p *BenchPoint) Set(x, y *big.Int) (Point, error) { + return &BenchPoint{ + x, y, + }, nil +} + +func (p *BenchPoint) ToAffineCompressed() []byte { + return nil +} + +func (p *BenchPoint) ToAffineUncompressed() []byte { + return nil +} + +func (p *BenchPoint) FromAffineCompressed(bytes []byte) (Point, error) { + return nil, nil +} + +func (p *BenchPoint) FromAffineUncompressed(bytes []byte) (Point, error) { + return nil, nil +} + +func (p *BenchPoint) CurveName() string { + return btcec.S256().Name +} + +func (p *BenchPoint) SumOfProducts(points []Point, scalars []Scalar) Point { + biScalars := make([]*big.Int, len(scalars)) + for i := 0; i < len(scalars); i++ { + biScalars[i] = scalars[i].BigInt() + } + return sumOfProductsPippenger(points, biScalars) +} + +//func rhsK256(x *big.Int) *big.Int { +// // y^2 = x^3 + B +// x3, _ := mod.Exp(x, big.NewInt(3), btcec.S256().P) +// x3.Add(x3, btcec.S256().B) +// return x3.ModSqrt(x3, btcec.S256().P) +//} diff --git a/pkg/crypto/core/curves/k256_curve.go b/pkg/crypto/core/curves/k256_curve.go new file mode 100755 index 000000000..3ad28148b --- /dev/null +++ b/pkg/crypto/core/curves/k256_curve.go @@ -0,0 +1,670 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/elliptic" + "fmt" + "io" + "math/big" + "sync" + + "github.com/btcsuite/btcd/btcec/v2" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + secp256k1 "github.com/onsonr/sonr/pkg/crypto/core/curves/native/k256" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/k256/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/k256/fq" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + oldK256Initonce sync.Once + oldK256 Koblitz256 +) + +type Koblitz256 struct { + *elliptic.CurveParams +} + +func oldK256InitAll() { + curve := btcec.S256() + oldK256.CurveParams = new(elliptic.CurveParams) + oldK256.P = curve.P + oldK256.N = curve.N + oldK256.Gx = curve.Gx + oldK256.Gy = curve.Gy + oldK256.B = curve.B + oldK256.BitSize = curve.BitSize + oldK256.Name = K256Name +} + +func K256Curve() *Koblitz256 { + oldK256Initonce.Do(oldK256InitAll) + return &oldK256 +} + +func (curve *Koblitz256) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +func (curve *Koblitz256) IsOnCurve(x, y *big.Int) bool { + _, err := secp256k1.K256PointNew().SetBigInt(x, y) + return err == nil +} + +func (curve *Koblitz256) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + p1, err := secp256k1.K256PointNew().SetBigInt(x1, y1) + if err != nil { + return nil, nil + } + p2, err := secp256k1.K256PointNew().SetBigInt(x2, y2) + if err != nil { + return nil, nil + } + return p1.Add(p1, p2).BigInt() +} + +func (curve *Koblitz256) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + p1, err := secp256k1.K256PointNew().SetBigInt(x1, y1) + if err != nil { + return nil, nil + } + return p1.Double(p1).BigInt() +} + +func (curve *Koblitz256) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + p1, err := secp256k1.K256PointNew().SetBigInt(Bx, By) + if err != nil { + return nil, nil + } + var bytes [32]byte + copy(bytes[:], internal.ReverseScalarBytes(k)) + s, err := fq.K256FqNew().SetBytes(&bytes) + if err != nil { + return nil, nil + } + return p1.Mul(p1, s).BigInt() +} + +func (curve *Koblitz256) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + var bytes [32]byte + copy(bytes[:], internal.ReverseScalarBytes(k)) + s, err := fq.K256FqNew().SetBytes(&bytes) + if err != nil { + return nil, nil + } + p1 := secp256k1.K256PointNew().Generator() + return p1.Mul(p1, s).BigInt() +} + +type ScalarK256 struct { + value *native.Field +} + +type PointK256 struct { + value *native.EllipticPoint +} + +func (s *ScalarK256) Random(reader io.Reader) Scalar { + if reader == nil { + return nil + } + var seed [64]byte + _, _ = reader.Read(seed[:]) + return s.Hash(seed[:]) +} + +func (s *ScalarK256) Hash(bytes []byte) Scalar { + dst := []byte("secp256k1_XMD:SHA-256_SSWU_RO_") + xmd := native.ExpandMsgXmd(native.EllipticPointHasherSha256(), bytes, dst, 48) + var t [64]byte + copy(t[:48], internal.ReverseScalarBytes(xmd)) + + return &ScalarK256{ + value: fq.K256FqNew().SetBytesWide(&t), + } +} + +func (s *ScalarK256) Zero() Scalar { + return &ScalarK256{ + value: fq.K256FqNew().SetZero(), + } +} + +func (s *ScalarK256) One() Scalar { + return &ScalarK256{ + value: fq.K256FqNew().SetOne(), + } +} + +func (s *ScalarK256) IsZero() bool { + return s.value.IsZero() == 1 +} + +func (s *ScalarK256) IsOne() bool { + return s.value.IsOne() == 1 +} + +func (s *ScalarK256) IsOdd() bool { + return s.value.Bytes()[0]&1 == 1 +} + +func (s *ScalarK256) IsEven() bool { + return s.value.Bytes()[0]&1 == 0 +} + +func (s *ScalarK256) New(value int) Scalar { + t := fq.K256FqNew() + v := big.NewInt(int64(value)) + if value < 0 { + v.Mod(v, t.Params.BiModulus) + } + return &ScalarK256{ + value: t.SetBigInt(v), + } +} + +func (s *ScalarK256) Cmp(rhs Scalar) int { + r, ok := rhs.(*ScalarK256) + if ok { + return s.value.Cmp(r.value) + } else { + return -2 + } +} + +func (s *ScalarK256) Square() Scalar { + return &ScalarK256{ + value: fq.K256FqNew().Square(s.value), + } +} + +func (s *ScalarK256) Double() Scalar { + return &ScalarK256{ + value: fq.K256FqNew().Double(s.value), + } +} + +func (s *ScalarK256) Invert() (Scalar, error) { + value, wasInverted := fq.K256FqNew().Invert(s.value) + if !wasInverted { + return nil, fmt.Errorf("inverse doesn't exist") + } + return &ScalarK256{ + value, + }, nil +} + +func (s *ScalarK256) Sqrt() (Scalar, error) { + value, wasSquare := fq.K256FqNew().Sqrt(s.value) + if !wasSquare { + return nil, fmt.Errorf("not a square") + } + return &ScalarK256{ + value, + }, nil +} + +func (s *ScalarK256) Cube() Scalar { + value := fq.K256FqNew().Mul(s.value, s.value) + value.Mul(value, s.value) + return &ScalarK256{ + value, + } +} + +func (s *ScalarK256) Add(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarK256) + if ok { + return &ScalarK256{ + value: fq.K256FqNew().Add(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarK256) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarK256) + if ok { + return &ScalarK256{ + value: fq.K256FqNew().Sub(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarK256) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarK256) + if ok { + return &ScalarK256{ + value: fq.K256FqNew().Mul(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarK256) MulAdd(y, z Scalar) Scalar { + return s.Mul(y).Add(z) +} + +func (s *ScalarK256) Div(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarK256) + if ok { + v, wasInverted := fq.K256FqNew().Invert(r.value) + if !wasInverted { + return nil + } + v.Mul(v, s.value) + return &ScalarK256{value: v} + } else { + return nil + } +} + +func (s *ScalarK256) Neg() Scalar { + return &ScalarK256{ + value: fq.K256FqNew().Neg(s.value), + } +} + +func (s *ScalarK256) SetBigInt(v *big.Int) (Scalar, error) { + if v == nil { + return nil, fmt.Errorf("'v' cannot be nil") + } + value := fq.K256FqNew().SetBigInt(v) + return &ScalarK256{ + value, + }, nil +} + +func (s *ScalarK256) BigInt() *big.Int { + return s.value.BigInt() +} + +func (s *ScalarK256) Bytes() []byte { + t := s.value.Bytes() + return internal.ReverseScalarBytes(t[:]) +} + +func (s *ScalarK256) SetBytes(bytes []byte) (Scalar, error) { + if len(bytes) != 32 { + return nil, fmt.Errorf("invalid length") + } + var seq [32]byte + copy(seq[:], internal.ReverseScalarBytes(bytes)) + value, err := fq.K256FqNew().SetBytes(&seq) + if err != nil { + return nil, err + } + return &ScalarK256{ + value, + }, nil +} + +func (s *ScalarK256) SetBytesWide(bytes []byte) (Scalar, error) { + if len(bytes) != 64 { + return nil, fmt.Errorf("invalid length") + } + var seq [64]byte + copy(seq[:], bytes) + return &ScalarK256{ + value: fq.K256FqNew().SetBytesWide(&seq), + }, nil +} + +func (s *ScalarK256) Point() Point { + return new(PointK256).Identity() +} + +func (s *ScalarK256) Clone() Scalar { + return &ScalarK256{ + value: fq.K256FqNew().Set(s.value), + } +} + +func (s *ScalarK256) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *ScalarK256) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarK256) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarK256) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *ScalarK256) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarK256) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarK256) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *ScalarK256) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*ScalarK256) + if !ok { + return fmt.Errorf("invalid type") + } + s.value = S.value + return nil +} + +func (p *PointK256) Random(reader io.Reader) Point { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *PointK256) Hash(bytes []byte) Point { + value, err := secp256k1.K256PointNew().Hash(bytes, native.EllipticPointHasherSha256()) + // TODO: change hash to return an error also + if err != nil { + return nil + } + + return &PointK256{value} +} + +func (p *PointK256) Identity() Point { + return &PointK256{ + value: secp256k1.K256PointNew().Identity(), + } +} + +func (p *PointK256) Generator() Point { + return &PointK256{ + value: secp256k1.K256PointNew().Generator(), + } +} + +func (p *PointK256) IsIdentity() bool { + return p.value.IsIdentity() +} + +func (p *PointK256) IsNegative() bool { + return p.value.GetY().Value[0]&1 == 1 +} + +func (p *PointK256) IsOnCurve() bool { + return p.value.IsOnCurve() +} + +func (p *PointK256) Double() Point { + value := secp256k1.K256PointNew().Double(p.value) + return &PointK256{value} +} + +func (p *PointK256) Scalar() Scalar { + return new(ScalarK256).Zero() +} + +func (p *PointK256) Neg() Point { + value := secp256k1.K256PointNew().Neg(p.value) + return &PointK256{value} +} + +func (p *PointK256) Add(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointK256) + if ok { + value := secp256k1.K256PointNew().Add(p.value, r.value) + return &PointK256{value} + } else { + return nil + } +} + +func (p *PointK256) Sub(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointK256) + if ok { + value := secp256k1.K256PointNew().Sub(p.value, r.value) + return &PointK256{value} + } else { + return nil + } +} + +func (p *PointK256) Mul(rhs Scalar) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*ScalarK256) + if ok { + value := secp256k1.K256PointNew().Mul(p.value, r.value) + return &PointK256{value} + } else { + return nil + } +} + +func (p *PointK256) Equal(rhs Point) bool { + r, ok := rhs.(*PointK256) + if ok { + return p.value.Equal(r.value) == 1 + } else { + return false + } +} + +func (p *PointK256) Set(x, y *big.Int) (Point, error) { + value, err := secp256k1.K256PointNew().SetBigInt(x, y) + if err != nil { + return nil, err + } + return &PointK256{value}, nil +} + +func (p *PointK256) ToAffineCompressed() []byte { + var x [33]byte + x[0] = byte(2) + + t := secp256k1.K256PointNew().ToAffine(p.value) + + x[0] |= t.Y.Bytes()[0] & 1 + + xBytes := t.X.Bytes() + copy(x[1:], internal.ReverseScalarBytes(xBytes[:])) + return x[:] +} + +func (p *PointK256) ToAffineUncompressed() []byte { + var out [65]byte + out[0] = byte(4) + t := secp256k1.K256PointNew().ToAffine(p.value) + arr := t.X.Bytes() + copy(out[1:33], internal.ReverseScalarBytes(arr[:])) + arr = t.Y.Bytes() + copy(out[33:], internal.ReverseScalarBytes(arr[:])) + return out[:] +} + +func (p *PointK256) FromAffineCompressed(bytes []byte) (Point, error) { + var raw [native.FieldBytes]byte + if len(bytes) != 33 { + return nil, fmt.Errorf("invalid byte sequence") + } + sign := int(bytes[0]) + if sign != 2 && sign != 3 { + return nil, fmt.Errorf("invalid sign byte") + } + sign &= 0x1 + + copy(raw[:], internal.ReverseScalarBytes(bytes[1:])) + x, err := fp.K256FpNew().SetBytes(&raw) + if err != nil { + return nil, err + } + + value := secp256k1.K256PointNew().Identity() + rhs := fp.K256FpNew() + p.value.Arithmetic.RhsEq(rhs, x) + // test that rhs is quadratic residue + // if not, then this Point is at infinity + y, wasQr := fp.K256FpNew().Sqrt(rhs) + if wasQr { + // fix the sign + sigY := int(y.Bytes()[0] & 1) + if sigY != sign { + y.Neg(y) + } + value.X = x + value.Y = y + value.Z.SetOne() + } + return &PointK256{value}, nil +} + +func (p *PointK256) FromAffineUncompressed(bytes []byte) (Point, error) { + var arr [native.FieldBytes]byte + if len(bytes) != 65 { + return nil, fmt.Errorf("invalid byte sequence") + } + if bytes[0] != 4 { + return nil, fmt.Errorf("invalid sign byte") + } + + copy(arr[:], internal.ReverseScalarBytes(bytes[1:33])) + x, err := fp.K256FpNew().SetBytes(&arr) + if err != nil { + return nil, err + } + copy(arr[:], internal.ReverseScalarBytes(bytes[33:])) + y, err := fp.K256FpNew().SetBytes(&arr) + if err != nil { + return nil, err + } + value := secp256k1.K256PointNew() + value.X = x + value.Y = y + value.Z.SetOne() + return &PointK256{value}, nil +} + +func (p *PointK256) CurveName() string { + return p.value.Params.Name +} + +func (p *PointK256) SumOfProducts(points []Point, scalars []Scalar) Point { + nPoints := make([]*native.EllipticPoint, len(points)) + nScalars := make([]*native.Field, len(scalars)) + for i, pt := range points { + ptv, ok := pt.(*PointK256) + if !ok { + return nil + } + nPoints[i] = ptv.value + } + for i, sc := range scalars { + s, ok := sc.(*ScalarK256) + if !ok { + return nil + } + nScalars[i] = s.value + } + value := secp256k1.K256PointNew() + _, err := value.SumOfProducts(nPoints, nScalars) + if err != nil { + return nil + } + return &PointK256{value} +} + +func (p *PointK256) X() *native.Field { + return p.value.GetX() +} + +func (p *PointK256) Y() *native.Field { + return p.value.GetY() +} + +func (p *PointK256) Params() *elliptic.CurveParams { + return K256Curve().Params() +} + +func (p *PointK256) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *PointK256) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointK256) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointK256) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *PointK256) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointK256) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointK256) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *PointK256) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*PointK256) + if !ok { + return fmt.Errorf("invalid type") + } + p.value = P.value + return nil +} diff --git a/pkg/crypto/core/curves/k256_curve_test.go b/pkg/crypto/core/curves/k256_curve_test.go new file mode 100755 index 000000000..bed4e5308 --- /dev/null +++ b/pkg/crypto/core/curves/k256_curve_test.go @@ -0,0 +1,423 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + crand "crypto/rand" + "math/big" + "sync" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" +) + +type mockReader struct { + index int + seed []byte +} + +var ( + mockRngInitonce sync.Once + mockRng mockReader +) + +func newMockReader() { + mockRng.index = 0 + mockRng.seed = make([]byte, 32) + for i := range mockRng.seed { + mockRng.seed[i] = 1 + } +} + +func testRng() *mockReader { + mockRngInitonce.Do(newMockReader) + return &mockRng +} + +func (m *mockReader) Read(p []byte) (n int, err error) { + limit := len(m.seed) + for i := range p { + p[i] = m.seed[m.index] + m.index += 1 + m.index %= limit + } + n = len(p) + err = nil + return +} + +func TestScalarK256Random(t *testing.T) { + curve := K256() + sc := curve.Scalar.Random(testRng()) + s, ok := sc.(*ScalarK256) + require.True(t, ok) + expected, _ := new(big.Int).SetString("2f71aaec5e14d747c72e46cdcaffffe6f542f38b3f0925469ceb24ac1c65885d", 16) + require.Equal(t, s.value.BigInt(), expected) + // Try 10 random values + for i := 0; i < 10; i++ { + sc := curve.Scalar.Random(crand.Reader) + _, ok := sc.(*ScalarK256) + require.True(t, ok) + require.True(t, !sc.IsZero()) + } +} + +func TestScalarK256Hash(t *testing.T) { + var b [32]byte + k256 := K256() + sc := k256.Scalar.Hash(b[:]) + s, ok := sc.(*ScalarK256) + require.True(t, ok) + expected, _ := new(big.Int).SetString("e5cb3500b809a8202de0834a805068bc21bde09bd6367815e7523a37adf8f52e", 16) + require.Equal(t, s.value.BigInt(), expected) +} + +func TestScalarK256Zero(t *testing.T) { + k256 := K256() + sc := k256.Scalar.Zero() + require.True(t, sc.IsZero()) + require.True(t, sc.IsEven()) +} + +func TestScalarK256One(t *testing.T) { + k256 := K256() + sc := k256.Scalar.One() + require.True(t, sc.IsOne()) + require.True(t, sc.IsOdd()) +} + +func TestScalarK256New(t *testing.T) { + k256 := K256() + three := k256.Scalar.New(3) + require.True(t, three.IsOdd()) + four := k256.Scalar.New(4) + require.True(t, four.IsEven()) + neg1 := k256.Scalar.New(-1) + require.True(t, neg1.IsEven()) + neg2 := k256.Scalar.New(-2) + require.True(t, neg2.IsOdd()) +} + +func TestScalarK256Square(t *testing.T) { + k256 := K256() + three := k256.Scalar.New(3) + nine := k256.Scalar.New(9) + require.Equal(t, three.Square().Cmp(nine), 0) +} + +func TestScalarK256Cube(t *testing.T) { + k256 := K256() + three := k256.Scalar.New(3) + twentySeven := k256.Scalar.New(27) + require.Equal(t, three.Cube().Cmp(twentySeven), 0) +} + +func TestScalarK256Double(t *testing.T) { + k256 := K256() + three := k256.Scalar.New(3) + six := k256.Scalar.New(6) + require.Equal(t, three.Double().Cmp(six), 0) +} + +func TestScalarK256Neg(t *testing.T) { + k256 := K256() + one := k256.Scalar.One() + neg1 := k256.Scalar.New(-1) + require.Equal(t, one.Neg().Cmp(neg1), 0) + lotsOfThrees := k256.Scalar.New(333333) + expected := k256.Scalar.New(-333333) + require.Equal(t, lotsOfThrees.Neg().Cmp(expected), 0) +} + +func TestScalarK256Invert(t *testing.T) { + k256 := K256() + nine := k256.Scalar.New(9) + actual, _ := nine.Invert() + sa, _ := actual.(*ScalarK256) + bn, _ := new(big.Int).SetString("8e38e38e38e38e38e38e38e38e38e38d842841d57dd303af6a9150f8e5737996", 16) + expected, err := k256.Scalar.SetBigInt(bn) + require.NoError(t, err) + require.Equal(t, sa.Cmp(expected), 0) +} + +func TestScalarK256Sqrt(t *testing.T) { + k256 := K256() + nine := k256.Scalar.New(9) + actual, err := nine.Sqrt() + sa, _ := actual.(*ScalarK256) + expected := k256.Scalar.New(3) + require.NoError(t, err) + require.Equal(t, sa.Cmp(expected), 0) +} + +func TestScalarK256Add(t *testing.T) { + k256 := K256() + nine := k256.Scalar.New(9) + six := k256.Scalar.New(6) + fifteen := nine.Add(six) + require.NotNil(t, fifteen) + expected := k256.Scalar.New(15) + require.Equal(t, expected.Cmp(fifteen), 0) + n := new(big.Int).Set(btcec.S256().N) + n.Sub(n, big.NewInt(3)) + + upper, err := k256.Scalar.SetBigInt(n) + require.NoError(t, err) + actual := upper.Add(nine) + require.NotNil(t, actual) + require.Equal(t, actual.Cmp(six), 0) +} + +func TestScalarK256Sub(t *testing.T) { + k256 := K256() + nine := k256.Scalar.New(9) + six := k256.Scalar.New(6) + n := new(big.Int).Set(btcec.S256().N) + n.Sub(n, big.NewInt(3)) + + expected, err := k256.Scalar.SetBigInt(n) + require.NoError(t, err) + actual := six.Sub(nine) + require.Equal(t, expected.Cmp(actual), 0) + + actual = nine.Sub(six) + require.Equal(t, actual.Cmp(k256.Scalar.New(3)), 0) +} + +func TestScalarK256Mul(t *testing.T) { + k256 := K256() + nine := k256.Scalar.New(9) + six := k256.Scalar.New(6) + actual := nine.Mul(six) + require.Equal(t, actual.Cmp(k256.Scalar.New(54)), 0) + n := new(big.Int).Set(btcec.S256().N) + n.Sub(n, big.NewInt(1)) + upper, err := k256.Scalar.SetBigInt(n) + require.NoError(t, err) + require.Equal(t, upper.Mul(upper).Cmp(k256.Scalar.New(1)), 0) +} + +func TestScalarK256Div(t *testing.T) { + k256 := K256() + nine := k256.Scalar.New(9) + actual := nine.Div(nine) + require.Equal(t, actual.Cmp(k256.Scalar.New(1)), 0) + require.Equal(t, k256.Scalar.New(54).Div(nine).Cmp(k256.Scalar.New(6)), 0) +} + +func TestScalarK256Serialize(t *testing.T) { + k256 := K256() + sc := k256.Scalar.New(255) + sequence := sc.Bytes() + require.Equal(t, len(sequence), 32) + require.Equal(t, sequence, []byte{0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff}) + ret, err := k256.Scalar.SetBytes(sequence) + require.NoError(t, err) + require.Equal(t, ret.Cmp(sc), 0) + + // Try 10 random values + for i := 0; i < 10; i++ { + sc = k256.Scalar.Random(crand.Reader) + sequence = sc.Bytes() + require.Equal(t, len(sequence), 32) + ret, err = k256.Scalar.SetBytes(sequence) + require.NoError(t, err) + require.Equal(t, ret.Cmp(sc), 0) + } +} + +func TestScalarK256Nil(t *testing.T) { + k256 := K256() + one := k256.Scalar.New(1) + require.Nil(t, one.Add(nil)) + require.Nil(t, one.Sub(nil)) + require.Nil(t, one.Mul(nil)) + require.Nil(t, one.Div(nil)) + require.Nil(t, k256.Scalar.Random(nil)) + require.Equal(t, one.Cmp(nil), -2) + _, err := k256.Scalar.SetBigInt(nil) + require.Error(t, err) +} + +func TestPointK256Random(t *testing.T) { + curve := K256() + sc := curve.Point.Random(testRng()) + s, ok := sc.(*PointK256) + require.True(t, ok) + expectedX, _ := new(big.Int).SetString("c6e18a1d7cf834462675b31581639a18e14fd0f73f8dfd5fe2993f88f6fbe008", 16) + expectedY, _ := new(big.Int).SetString("b65fab3243c5d07cef005d7fb335ebe8019efd954e95e68c86ef9b3bd7bccd36", 16) + require.Equal(t, s.X().BigInt(), expectedX) + require.Equal(t, s.Y().BigInt(), expectedY) + // Try 10 random values + for i := 0; i < 10; i++ { + sc := curve.Point.Random(crand.Reader) + _, ok := sc.(*PointK256) + require.True(t, ok) + require.True(t, !sc.IsIdentity()) + } +} + +func TestPointK256Hash(t *testing.T) { + var b [32]byte + curve := K256() + sc := curve.Point.Hash(b[:]) + s, ok := sc.(*PointK256) + require.True(t, ok) + expectedX, _ := new(big.Int).SetString("95d0ad42f68ddb5a808469dd75fa866890dcc7d039844e0e2d58a6d25bd9a66b", 16) + expectedY, _ := new(big.Int).SetString("f37c564d05168dab4413caacdb8e3426143fc5fb24a470ccd8a51856c11d163c", 16) + require.Equal(t, s.X().BigInt(), expectedX) + require.Equal(t, s.Y().BigInt(), expectedY) +} + +func TestPointK256Identity(t *testing.T) { + k256 := K256() + sc := k256.Point.Identity() + require.True(t, sc.IsIdentity()) + require.Equal(t, sc.ToAffineCompressed(), []byte{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) +} + +func TestPointK256Generator(t *testing.T) { + curve := K256() + sc := curve.Point.Generator() + s, ok := sc.(*PointK256) + require.True(t, ok) + require.Equal(t, s.X().BigInt().Cmp(btcec.S256().Gx), 0) + require.Equal(t, s.Y().BigInt().Cmp(btcec.S256().Gy), 0) +} + +func TestPointK256Set(t *testing.T) { + k256 := K256() + iden, err := k256.Point.Set(big.NewInt(0), big.NewInt(0)) + require.NoError(t, err) + require.True(t, iden.IsIdentity()) + _, err = k256.Point.Set(btcec.S256().Gx, btcec.S256().Gy) + require.NoError(t, err) +} + +func TestPointK256Double(t *testing.T) { + curve := K256() + g := curve.Point.Generator() + g2 := g.Double() + require.True(t, g2.Equal(g.Mul(curve.Scalar.New(2)))) + i := curve.Point.Identity() + require.True(t, i.Double().Equal(i)) + gg := curve.Point.Generator().Add(curve.Point.Generator()) + require.True(t, g2.Equal(gg)) +} + +func TestPointK256Neg(t *testing.T) { + k256 := K256() + g := k256.Point.Generator().Neg() + require.True(t, g.Neg().Equal(k256.Point.Generator())) + require.True(t, k256.Point.Identity().Neg().Equal(k256.Point.Identity())) +} + +func TestPointK256Add(t *testing.T) { + curve := K256() + pt := curve.Point.Generator().(*PointK256) + pt1 := pt.Add(pt).(*PointK256) + pt2 := pt.Double().(*PointK256) + pt3 := pt.Mul(curve.Scalar.New(2)).(*PointK256) + + require.True(t, pt1.Equal(pt2)) + require.True(t, pt1.Equal(pt3)) + require.True(t, pt.Add(pt).Equal(pt.Double())) + require.True(t, pt.Mul(curve.Scalar.New(3)).Equal(pt.Add(pt).Add(pt))) +} + +func TestPointK256Sub(t *testing.T) { + curve := K256() + g := curve.Point.Generator() + pt := curve.Point.Generator().Mul(curve.Scalar.New(4)) + + require.True(t, pt.Sub(g).Sub(g).Sub(g).Equal(g)) + require.True(t, pt.Sub(g).Sub(g).Sub(g).Sub(g).IsIdentity()) +} + +func TestPointK256Mul(t *testing.T) { + curve := K256() + g := curve.Point.Generator() + pt := curve.Point.Generator().Mul(curve.Scalar.New(4)) + require.True(t, g.Double().Double().Equal(pt)) +} + +func TestPointK256Serialize(t *testing.T) { + curve := K256() + ss := curve.Scalar.Random(testRng()) + + g := curve.Point.Generator() + ppt := g.Mul(ss).(*PointK256) + + require.Equal(t, ppt.ToAffineCompressed(), []byte{0x2, 0x1b, 0xa7, 0x7e, 0x98, 0xd6, 0xd8, 0x49, 0x45, 0xa4, 0x75, 0xd8, 0x6, 0xc0, 0x94, 0x5b, 0x8c, 0xf0, 0x5b, 0x8a, 0xb2, 0x76, 0xbb, 0x9f, 0x6e, 0x52, 0x9a, 0x11, 0x9c, 0x79, 0xdd, 0xf6, 0x5a}) + require.Equal(t, ppt.ToAffineUncompressed(), []byte{0x4, 0x1b, 0xa7, 0x7e, 0x98, 0xd6, 0xd8, 0x49, 0x45, 0xa4, 0x75, 0xd8, 0x6, 0xc0, 0x94, 0x5b, 0x8c, 0xf0, 0x5b, 0x8a, 0xb2, 0x76, 0xbb, 0x9f, 0x6e, 0x52, 0x9a, 0x11, 0x9c, 0x79, 0xdd, 0xf6, 0x5a, 0xb2, 0x96, 0x7c, 0x59, 0x4, 0xeb, 0x9a, 0xaa, 0xa9, 0x1d, 0x4d, 0xd0, 0x2d, 0xc6, 0x37, 0xee, 0x4a, 0x95, 0x51, 0x60, 0xab, 0xab, 0xf7, 0xdb, 0x30, 0x7d, 0x7d, 0x0, 0x68, 0x6c, 0xcf, 0xf6}) + retP, err := ppt.FromAffineCompressed(ppt.ToAffineCompressed()) + require.NoError(t, err) + require.True(t, ppt.Equal(retP)) + retP, err = ppt.FromAffineUncompressed(ppt.ToAffineUncompressed()) + require.NoError(t, err) + require.True(t, ppt.Equal(retP)) + + // smoke test + for i := 0; i < 25; i++ { + s := curve.Scalar.Random(crand.Reader) + pt := g.Mul(s) + cmprs := pt.ToAffineCompressed() + require.Equal(t, len(cmprs), 33) + retC, err := pt.FromAffineCompressed(cmprs) + require.NoError(t, err) + require.True(t, pt.Equal(retC)) + + un := pt.ToAffineUncompressed() + require.Equal(t, len(un), 65) + retU, err := pt.FromAffineUncompressed(un) + require.NoError(t, err) + require.True(t, pt.Equal(retU)) + } +} + +func TestPointK256Nil(t *testing.T) { + k256 := K256() + one := k256.Point.Generator() + require.Nil(t, one.Add(nil)) + require.Nil(t, one.Sub(nil)) + require.Nil(t, one.Mul(nil)) + require.Nil(t, k256.Scalar.Random(nil)) + require.False(t, one.Equal(nil)) + _, err := k256.Scalar.SetBigInt(nil) + require.Error(t, err) +} + +func TestPointK256SumOfProducts(t *testing.T) { + lhs := new(PointK256).Generator().Mul(new(ScalarK256).New(50)) + points := make([]Point, 5) + for i := range points { + points[i] = new(PointK256).Generator() + } + scalars := []Scalar{ + new(ScalarK256).New(8), + new(ScalarK256).New(9), + new(ScalarK256).New(10), + new(ScalarK256).New(11), + new(ScalarK256).New(12), + } + rhs := lhs.SumOfProducts(points, scalars) + require.NotNil(t, rhs) + require.True(t, lhs.Equal(rhs)) + + for j := 0; j < 25; j++ { + lhs = lhs.Identity() + for i := range points { + points[i] = new(PointK256).Random(crand.Reader) + scalars[i] = new(ScalarK256).Random(crand.Reader) + lhs = lhs.Add(points[i].Mul(scalars[i])) + } + rhs = lhs.SumOfProducts(points, scalars) + require.NotNil(t, rhs) + require.True(t, lhs.Equal(rhs)) + } +} diff --git a/pkg/crypto/core/curves/native/bls12381/bls12381.go b/pkg/crypto/core/curves/native/bls12381/bls12381.go new file mode 100755 index 000000000..c4d53709e --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/bls12381.go @@ -0,0 +1,48 @@ +package bls12381 + +import ( + "math/bits" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +var fqModulusBytes = [native.FieldBytes]byte{0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0x02, 0xa4, 0xbd, 0x53, 0x05, 0xd8, 0xa1, 0x09, 0x08, 0xd8, 0x39, 0x33, 0x48, 0x7d, 0x9d, 0x29, 0x53, 0xa7, 0xed, 0x73} + +const ( + // The BLS parameter x for BLS12-381 is -0xd201000000010000 + paramX = uint64(0xd201000000010000) + Limbs = 6 + FieldBytes = 48 + WideFieldBytes = 96 + DoubleWideFieldBytes = 192 +) + +// mac Multiply and Accumulate - compute a + (b * c) + d, return the result and new carry +func mac(a, b, c, d uint64) (uint64, uint64) { + hi, lo := bits.Mul64(b, c) + carry2, carry := bits.Add64(a, d, 0) + hi, _ = bits.Add64(hi, 0, carry) + lo, carry = bits.Add64(lo, carry2, 0) + hi, _ = bits.Add64(hi, 0, carry) + + return lo, hi +} + +// adc Add w/Carry +func adc(x, y, carry uint64) (uint64, uint64) { + sum := x + y + carry + // The sum will overflow if both top bits are set (x & y) or if one of them + // is (x | y), and a carry from the lower place happened. If such a carry + // happens, the top bit will be 1 + 0 + 1 = 0 (&^ sum). + carryOut := ((x & y) | ((x | y) &^ sum)) >> 63 + carryOut |= ((x & carry) | ((x | carry) &^ sum)) >> 63 + carryOut |= ((y & carry) | ((y | carry) &^ sum)) >> 63 + return sum, carryOut +} + +// sbb Subtract with borrow +func sbb(x, y, borrow uint64) (uint64, uint64) { + diff := x - (y + borrow) + borrowOut := ((^x & y) | (^(x ^ y) & diff)) >> 63 + return diff, borrowOut +} diff --git a/pkg/crypto/core/curves/native/bls12381/fp.go b/pkg/crypto/core/curves/native/bls12381/fp.go new file mode 100755 index 000000000..3891ef990 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fp.go @@ -0,0 +1,697 @@ +package bls12381 + +import ( + "encoding/binary" + "fmt" + "io" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// fp field element mod p +type fp [Limbs]uint64 + +var ( + modulus = fp{ + 0xb9feffffffffaaab, + 0x1eabfffeb153ffff, + 0x6730d2a0f6b0f624, + 0x64774b84f38512bf, + 0x4b1ba7b6434bacd7, + 0x1a0111ea397fe69a, + } + halfModulus = fp{ + 0xdcff_7fff_ffff_d556, + 0x0f55_ffff_58a9_ffff, + 0xb398_6950_7b58_7b12, + 0xb23b_a5c2_79c2_895f, + 0x258d_d3db_21a5_d66b, + 0x0d00_88f5_1cbf_f34d, + } + // 2^256 mod p + r = fp{ + 0x760900000002fffd, + 0xebf4000bc40c0002, + 0x5f48985753c758ba, + 0x77ce585370525745, + 0x5c071a97a256ec6d, + 0x15f65ec3fa80e493, + } + // 2^512 mod p + r2 = fp{ + 0xf4df1f341c341746, + 0x0a76e6a609d104f1, + 0x8de5476c4c95b6d5, + 0x67eb88a9939d83c0, + 0x9a793e85b519952d, + 0x11988fe592cae3aa, + } + // 2^768 mod p + r3 = fp{ + 0xed48ac6bd94ca1e0, + 0x315f831e03a7adf8, + 0x9a53352a615e29dd, + 0x34c04e5e921e1761, + 0x2512d43565724728, + 0x0aa6346091755d4d, + } + biModulus = new(big.Int).SetBytes([]byte{ + 0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b, 0xac, 0xd7, 0x64, 0x77, 0x4b, 0x84, 0xf3, 0x85, 0x12, 0xbf, 0x67, 0x30, 0xd2, 0xa0, 0xf6, 0xb0, 0xf6, 0x24, 0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xab, + }, + ) +) + +// inv = -(p^{-1} mod 2^64) mod 2^64 +const ( + inv = 0x89f3_fffc_fffc_fffd + hashBytes = 64 +) + +// IsZero returns 1 if fp == 0, 0 otherwise +func (f *fp) IsZero() int { + t := f[0] + t |= f[1] + t |= f[2] + t |= f[3] + t |= f[4] + t |= f[5] + return int(((int64(t) | int64(-t)) >> 63) + 1) +} + +// IsNonZero returns 1 if fp != 0, 0 otherwise +func (f *fp) IsNonZero() int { + t := f[0] + t |= f[1] + t |= f[2] + t |= f[3] + t |= f[4] + t |= f[5] + return int(-((int64(t) | int64(-t)) >> 63)) +} + +// IsOne returns 1 if fp == 1, 0 otherwise +func (f *fp) IsOne() int { + return f.Equal(&r) +} + +// Cmp returns -1 if f < rhs +// 0 if f == rhs +// 1 if f > rhs +func (f *fp) Cmp(rhs *fp) int { + gt := uint64(0) + lt := uint64(0) + for i := 5; i >= 0; i-- { + // convert to two 64-bit numbers where + // the leading bits are zeros and hold no meaning + // so rhs - f actually means gt + // and f - rhs actually means lt. + rhsH := rhs[i] >> 32 + rhsL := rhs[i] & 0xffffffff + lhsH := f[i] >> 32 + lhsL := f[i] & 0xffffffff + + // Check the leading bit + // if negative then f > rhs + // if positive then f < rhs + gt |= (rhsH - lhsH) >> 32 & 1 &^ lt + lt |= (lhsH - rhsH) >> 32 & 1 &^ gt + gt |= (rhsL - lhsL) >> 32 & 1 &^ lt + lt |= (lhsL - rhsL) >> 32 & 1 &^ gt + } + // Make the result -1 for <, 0 for =, 1 for > + return int(gt) - int(lt) +} + +// Equal returns 1 if fp == rhs, 0 otherwise +func (f *fp) Equal(rhs *fp) int { + t := f[0] ^ rhs[0] + t |= f[1] ^ rhs[1] + t |= f[2] ^ rhs[2] + t |= f[3] ^ rhs[3] + t |= f[4] ^ rhs[4] + t |= f[5] ^ rhs[5] + return int(((int64(t) | int64(-t)) >> 63) + 1) +} + +// LexicographicallyLargest returns 1 if +// this element is strictly lexicographically larger than its negation +// 0 otherwise +func (f *fp) LexicographicallyLargest() int { + var ff fp + ff.fromMontgomery(f) + + _, borrow := sbb(ff[0], halfModulus[0], 0) + _, borrow = sbb(ff[1], halfModulus[1], borrow) + _, borrow = sbb(ff[2], halfModulus[2], borrow) + _, borrow = sbb(ff[3], halfModulus[3], borrow) + _, borrow = sbb(ff[4], halfModulus[4], borrow) + _, borrow = sbb(ff[5], halfModulus[5], borrow) + + return (int(borrow) - 1) & 1 +} + +// Sgn0 returns the lowest bit value +func (f *fp) Sgn0() int { + t := new(fp).fromMontgomery(f) + return int(t[0] & 1) +} + +// SetOne fp = r +func (f *fp) SetOne() *fp { + f[0] = r[0] + f[1] = r[1] + f[2] = r[2] + f[3] = r[3] + f[4] = r[4] + f[5] = r[5] + return f +} + +// SetZero fp = 0 +func (f *fp) SetZero() *fp { + f[0] = 0 + f[1] = 0 + f[2] = 0 + f[3] = 0 + f[4] = 0 + f[5] = 0 + return f +} + +// SetUint64 fp = rhs +func (f *fp) SetUint64(rhs uint64) *fp { + f[0] = rhs + f[1] = 0 + f[2] = 0 + f[3] = 0 + f[4] = 0 + f[5] = 0 + return f.toMontgomery(f) +} + +// Random generates a random field element +func (f *fp) Random(reader io.Reader) (*fp, error) { + var t [WideFieldBytes]byte + n, err := reader.Read(t[:]) + if err != nil { + return nil, err + } + if n != WideFieldBytes { + return nil, fmt.Errorf("can only read %d when %d are needed", n, WideFieldBytes) + } + return f.Hash(t[:]), nil +} + +// Hash converts the byte sequence into a field element +func (f *fp) Hash(input []byte) *fp { + dst := []byte("BLS12381_XMD:SHA-256_SSWU_RO_") + xmd := native.ExpandMsgXmd(native.EllipticPointHasherSha256(), input, dst, hashBytes) + var t [WideFieldBytes]byte + copy(t[:hashBytes], internal.ReverseScalarBytes(xmd)) + return f.SetBytesWide(&t) +} + +// toMontgomery converts this field to montgomery form +func (f *fp) toMontgomery(a *fp) *fp { + // arg.R^0 * R^2 / R = arg.R + return f.Mul(a, &r2) +} + +// fromMontgomery converts this field from montgomery form +func (f *fp) fromMontgomery(a *fp) *fp { + // Mul by 1 is division by 2^256 mod q + // out.Mul(arg, &[native.FieldLimbs]uint64{1, 0, 0, 0}) + return f.montReduce(&[Limbs * 2]uint64{a[0], a[1], a[2], a[3], a[4], a[5], 0, 0, 0, 0, 0, 0}) +} + +// Neg performs modular negation +func (f *fp) Neg(a *fp) *fp { + // Subtract `arg` from `modulus`. Ignore final borrow + // since it can't underflow. + var t [Limbs]uint64 + var borrow uint64 + t[0], borrow = sbb(modulus[0], a[0], 0) + t[1], borrow = sbb(modulus[1], a[1], borrow) + t[2], borrow = sbb(modulus[2], a[2], borrow) + t[3], borrow = sbb(modulus[3], a[3], borrow) + t[4], borrow = sbb(modulus[4], a[4], borrow) + t[5], _ = sbb(modulus[5], a[5], borrow) + + // t could be `modulus` if `arg`=0. Set mask=0 if self=0 + // and 0xff..ff if `arg`!=0 + mask := a[0] | a[1] | a[2] | a[3] | a[4] | a[5] + mask = -((mask | -mask) >> 63) + f[0] = t[0] & mask + f[1] = t[1] & mask + f[2] = t[2] & mask + f[3] = t[3] & mask + f[4] = t[4] & mask + f[5] = t[5] & mask + return f +} + +// Square performs modular square +func (f *fp) Square(a *fp) *fp { + var r [2 * Limbs]uint64 + var carry uint64 + + r[1], carry = mac(0, a[0], a[1], 0) + r[2], carry = mac(0, a[0], a[2], carry) + r[3], carry = mac(0, a[0], a[3], carry) + r[4], carry = mac(0, a[0], a[4], carry) + r[5], r[6] = mac(0, a[0], a[5], carry) + + r[3], carry = mac(r[3], a[1], a[2], 0) + r[4], carry = mac(r[4], a[1], a[3], carry) + r[5], carry = mac(r[5], a[1], a[4], carry) + r[6], r[7] = mac(r[6], a[1], a[5], carry) + + r[5], carry = mac(r[5], a[2], a[3], 0) + r[6], carry = mac(r[6], a[2], a[4], carry) + r[7], r[8] = mac(r[7], a[2], a[5], carry) + + r[7], carry = mac(r[7], a[3], a[4], 0) + r[8], r[9] = mac(r[8], a[3], a[5], carry) + + r[9], r[10] = mac(r[9], a[4], a[5], 0) + + r[11] = r[10] >> 63 + r[10] = (r[10] << 1) | r[9]>>63 + r[9] = (r[9] << 1) | r[8]>>63 + r[8] = (r[8] << 1) | r[7]>>63 + r[7] = (r[7] << 1) | r[6]>>63 + r[6] = (r[6] << 1) | r[5]>>63 + r[5] = (r[5] << 1) | r[4]>>63 + r[4] = (r[4] << 1) | r[3]>>63 + r[3] = (r[3] << 1) | r[2]>>63 + r[2] = (r[2] << 1) | r[1]>>63 + r[1] = r[1] << 1 + + r[0], carry = mac(0, a[0], a[0], 0) + r[1], carry = adc(0, r[1], carry) + r[2], carry = mac(r[2], a[1], a[1], carry) + r[3], carry = adc(0, r[3], carry) + r[4], carry = mac(r[4], a[2], a[2], carry) + r[5], carry = adc(0, r[5], carry) + r[6], carry = mac(r[6], a[3], a[3], carry) + r[7], carry = adc(0, r[7], carry) + r[8], carry = mac(r[8], a[4], a[4], carry) + r[9], carry = adc(0, r[9], carry) + r[10], carry = mac(r[10], a[5], a[5], carry) + r[11], _ = adc(0, r[11], carry) + + return f.montReduce(&r) +} + +// Double this element +func (f *fp) Double(a *fp) *fp { + return f.Add(a, a) +} + +// Mul performs modular multiplication +func (f *fp) Mul(arg1, arg2 *fp) *fp { + // Schoolbook multiplication + var r [2 * Limbs]uint64 + var carry uint64 + + r[0], carry = mac(0, arg1[0], arg2[0], 0) + r[1], carry = mac(0, arg1[0], arg2[1], carry) + r[2], carry = mac(0, arg1[0], arg2[2], carry) + r[3], carry = mac(0, arg1[0], arg2[3], carry) + r[4], carry = mac(0, arg1[0], arg2[4], carry) + r[5], r[6] = mac(0, arg1[0], arg2[5], carry) + + r[1], carry = mac(r[1], arg1[1], arg2[0], 0) + r[2], carry = mac(r[2], arg1[1], arg2[1], carry) + r[3], carry = mac(r[3], arg1[1], arg2[2], carry) + r[4], carry = mac(r[4], arg1[1], arg2[3], carry) + r[5], carry = mac(r[5], arg1[1], arg2[4], carry) + r[6], r[7] = mac(r[6], arg1[1], arg2[5], carry) + + r[2], carry = mac(r[2], arg1[2], arg2[0], 0) + r[3], carry = mac(r[3], arg1[2], arg2[1], carry) + r[4], carry = mac(r[4], arg1[2], arg2[2], carry) + r[5], carry = mac(r[5], arg1[2], arg2[3], carry) + r[6], carry = mac(r[6], arg1[2], arg2[4], carry) + r[7], r[8] = mac(r[7], arg1[2], arg2[5], carry) + + r[3], carry = mac(r[3], arg1[3], arg2[0], 0) + r[4], carry = mac(r[4], arg1[3], arg2[1], carry) + r[5], carry = mac(r[5], arg1[3], arg2[2], carry) + r[6], carry = mac(r[6], arg1[3], arg2[3], carry) + r[7], carry = mac(r[7], arg1[3], arg2[4], carry) + r[8], r[9] = mac(r[8], arg1[3], arg2[5], carry) + + r[4], carry = mac(r[4], arg1[4], arg2[0], 0) + r[5], carry = mac(r[5], arg1[4], arg2[1], carry) + r[6], carry = mac(r[6], arg1[4], arg2[2], carry) + r[7], carry = mac(r[7], arg1[4], arg2[3], carry) + r[8], carry = mac(r[8], arg1[4], arg2[4], carry) + r[9], r[10] = mac(r[9], arg1[4], arg2[5], carry) + + r[5], carry = mac(r[5], arg1[5], arg2[0], 0) + r[6], carry = mac(r[6], arg1[5], arg2[1], carry) + r[7], carry = mac(r[7], arg1[5], arg2[2], carry) + r[8], carry = mac(r[8], arg1[5], arg2[3], carry) + r[9], carry = mac(r[9], arg1[5], arg2[4], carry) + r[10], r[11] = mac(r[10], arg1[5], arg2[5], carry) + + return f.montReduce(&r) +} + +// MulBy3b returns arg * 12 or 3 * b +func (f *fp) MulBy3b(arg *fp) *fp { + var a, t fp + a.Double(arg) // 2 + t.Double(&a) // 4 + a.Double(&t) // 8 + a.Add(&a, &t) // 12 + return f.Set(&a) +} + +// Add performs modular addition +func (f *fp) Add(arg1, arg2 *fp) *fp { + var t fp + var carry uint64 + + t[0], carry = adc(arg1[0], arg2[0], 0) + t[1], carry = adc(arg1[1], arg2[1], carry) + t[2], carry = adc(arg1[2], arg2[2], carry) + t[3], carry = adc(arg1[3], arg2[3], carry) + t[4], carry = adc(arg1[4], arg2[4], carry) + t[5], _ = adc(arg1[5], arg2[5], carry) + + // Subtract the modulus to ensure the value + // is smaller. + return f.Sub(&t, &modulus) +} + +// Sub performs modular subtraction +func (f *fp) Sub(arg1, arg2 *fp) *fp { + d0, borrow := sbb(arg1[0], arg2[0], 0) + d1, borrow := sbb(arg1[1], arg2[1], borrow) + d2, borrow := sbb(arg1[2], arg2[2], borrow) + d3, borrow := sbb(arg1[3], arg2[3], borrow) + d4, borrow := sbb(arg1[4], arg2[4], borrow) + d5, borrow := sbb(arg1[5], arg2[5], borrow) + + // If underflow occurred on the final limb, borrow 0xff...ff, otherwise + // borrow = 0x00...00. Conditionally mask to add the modulus + borrow = -borrow + d0, carry := adc(d0, modulus[0]&borrow, 0) + d1, carry = adc(d1, modulus[1]&borrow, carry) + d2, carry = adc(d2, modulus[2]&borrow, carry) + d3, carry = adc(d3, modulus[3]&borrow, carry) + d4, carry = adc(d4, modulus[4]&borrow, carry) + d5, _ = adc(d5, modulus[5]&borrow, carry) + + f[0] = d0 + f[1] = d1 + f[2] = d2 + f[3] = d3 + f[4] = d4 + f[5] = d5 + return f +} + +// Sqrt performs modular square root +func (f *fp) Sqrt(a *fp) (*fp, int) { + // Shank's method, as p = 3 (mod 4). This means + // exponentiate by (p+1)/4. This only works for elements + // that are actually quadratic residue, + // so check the result at the end. + var c, z fp + z.pow(a, &fp{ + 0xee7fbfffffffeaab, + 0x07aaffffac54ffff, + 0xd9cc34a83dac3d89, + 0xd91dd2e13ce144af, + 0x92c6e9ed90d2eb35, + 0x0680447a8e5ff9a6, + }) + + c.Square(&z) + wasSquare := c.Equal(a) + f.CMove(f, &z, wasSquare) + return f, wasSquare +} + +// Invert performs modular inverse +func (f *fp) Invert(a *fp) (*fp, int) { + // Exponentiate by p - 2 + t := &fp{} + t.pow(a, &fp{ + 0xb9feffffffffaaa9, + 0x1eabfffeb153ffff, + 0x6730d2a0f6b0f624, + 0x64774b84f38512bf, + 0x4b1ba7b6434bacd7, + 0x1a0111ea397fe69a, + }) + wasInverted := a.IsNonZero() + f.CMove(a, t, wasInverted) + return f, wasInverted +} + +// SetBytes converts a little endian byte array into a field element +// return 0 if the bytes are not in the field, 1 if they are +func (f *fp) SetBytes(arg *[FieldBytes]byte) (*fp, int) { + var borrow uint64 + t := &fp{} + + t[0] = binary.LittleEndian.Uint64(arg[:8]) + t[1] = binary.LittleEndian.Uint64(arg[8:16]) + t[2] = binary.LittleEndian.Uint64(arg[16:24]) + t[3] = binary.LittleEndian.Uint64(arg[24:32]) + t[4] = binary.LittleEndian.Uint64(arg[32:40]) + t[5] = binary.LittleEndian.Uint64(arg[40:]) + + // Try to subtract the modulus + _, borrow = sbb(t[0], modulus[0], 0) + _, borrow = sbb(t[1], modulus[1], borrow) + _, borrow = sbb(t[2], modulus[2], borrow) + _, borrow = sbb(t[3], modulus[3], borrow) + _, borrow = sbb(t[4], modulus[4], borrow) + _, borrow = sbb(t[5], modulus[5], borrow) + + // If the element is smaller than modulus then the + // subtraction will underflow, producing a borrow value + // of 1. Otherwise, it'll be zero. + mask := int(borrow) + return f.CMove(f, t.toMontgomery(t), mask), mask +} + +// SetBytesWide takes 96 bytes as input and treats them as a 512-bit number. +// Attributed to https://github.com/zcash/pasta_curves/blob/main/src/fields/Fp.rs#L255 +// We reduce an arbitrary 768-bit number by decomposing it into two 384-bit digits +// with the higher bits multiplied by 2^384. Thus, we perform two reductions +// +// 1. the lower bits are multiplied by r^2, as normal +// 2. the upper bits are multiplied by r^2 * 2^384 = r^3 +// +// and computing their sum in the field. It remains to see that arbitrary 384-bit +// numbers can be placed into Montgomery form safely using the reduction. The +// reduction works so long as the product is less than r=2^384 multiplied by +// the modulus. This holds because for any `c` smaller than the modulus, we have +// that (2^384 - 1)*c is an acceptable product for the reduction. Therefore, the +// reduction always works so long as `c` is in the field; in this case it is either the +// constant `r2` or `r3`. +func (f *fp) SetBytesWide(a *[WideFieldBytes]byte) *fp { + d0 := &fp{ + binary.LittleEndian.Uint64(a[:8]), + binary.LittleEndian.Uint64(a[8:16]), + binary.LittleEndian.Uint64(a[16:24]), + binary.LittleEndian.Uint64(a[24:32]), + binary.LittleEndian.Uint64(a[32:40]), + binary.LittleEndian.Uint64(a[40:48]), + } + d1 := &fp{ + binary.LittleEndian.Uint64(a[48:56]), + binary.LittleEndian.Uint64(a[56:64]), + binary.LittleEndian.Uint64(a[64:72]), + binary.LittleEndian.Uint64(a[72:80]), + binary.LittleEndian.Uint64(a[80:88]), + binary.LittleEndian.Uint64(a[88:96]), + } + // d0*r2 + d1*r3 + d0.Mul(d0, &r2) + d1.Mul(d1, &r3) + return f.Add(d0, d1) +} + +// SetBigInt initializes an element from big.Int +// The value is reduced by the modulus +func (f *fp) SetBigInt(bi *big.Int) *fp { + var buffer [FieldBytes]byte + t := new(big.Int).Set(bi) + t.Mod(t, biModulus) + t.FillBytes(buffer[:]) + copy(buffer[:], internal.ReverseScalarBytes(buffer[:])) + _, _ = f.SetBytes(&buffer) + return f +} + +// Set copies a into fp +func (f *fp) Set(a *fp) *fp { + f[0] = a[0] + f[1] = a[1] + f[2] = a[2] + f[3] = a[3] + f[4] = a[4] + f[5] = a[5] + return f +} + +// SetLimbs converts an array into a field element +// by converting to montgomery form +func (f *fp) SetLimbs(a *[Limbs]uint64) *fp { + return f.toMontgomery((*fp)(a)) +} + +// SetRaw converts a raw array into a field element +// Assumes input is already in montgomery form +func (f *fp) SetRaw(a *[Limbs]uint64) *fp { + f[0] = a[0] + f[1] = a[1] + f[2] = a[2] + f[3] = a[3] + f[4] = a[4] + f[5] = a[5] + return f +} + +// Bytes converts a field element to a little endian byte array +func (f *fp) Bytes() [FieldBytes]byte { + var out [FieldBytes]byte + t := new(fp).fromMontgomery(f) + binary.LittleEndian.PutUint64(out[:8], t[0]) + binary.LittleEndian.PutUint64(out[8:16], t[1]) + binary.LittleEndian.PutUint64(out[16:24], t[2]) + binary.LittleEndian.PutUint64(out[24:32], t[3]) + binary.LittleEndian.PutUint64(out[32:40], t[4]) + binary.LittleEndian.PutUint64(out[40:], t[5]) + return out +} + +// BigInt converts this element into the big.Int struct +func (f *fp) BigInt() *big.Int { + buffer := f.Bytes() + return new(big.Int).SetBytes(internal.ReverseScalarBytes(buffer[:])) +} + +// Raw converts this element into the a [FieldLimbs]uint64 +func (f *fp) Raw() [Limbs]uint64 { + t := new(fp).fromMontgomery(f) + return *t +} + +// CMove performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f *fp) CMove(arg1, arg2 *fp, choice int) *fp { + mask := uint64(-choice) + f[0] = arg1[0] ^ ((arg1[0] ^ arg2[0]) & mask) + f[1] = arg1[1] ^ ((arg1[1] ^ arg2[1]) & mask) + f[2] = arg1[2] ^ ((arg1[2] ^ arg2[2]) & mask) + f[3] = arg1[3] ^ ((arg1[3] ^ arg2[3]) & mask) + f[4] = arg1[4] ^ ((arg1[4] ^ arg2[4]) & mask) + f[5] = arg1[5] ^ ((arg1[5] ^ arg2[5]) & mask) + return f +} + +// CNeg conditionally negates a if choice == 1 +func (f *fp) CNeg(a *fp, choice int) *fp { + var t fp + t.Neg(a) + return f.CMove(f, &t, choice) +} + +// Exp raises base^exp. +func (f *fp) Exp(base, exp *fp) *fp { + e := (&fp{}).fromMontgomery(exp) + return f.pow(base, e) +} + +func (f *fp) pow(base, e *fp) *fp { + var tmp, res fp + res.SetOne() + + for i := len(e) - 1; i >= 0; i-- { + for j := 63; j >= 0; j-- { + res.Square(&res) + tmp.Mul(&res, base) + res.CMove(&res, &tmp, int(e[i]>>j)&1) + } + } + f[0] = res[0] + f[1] = res[1] + f[2] = res[2] + f[3] = res[3] + f[4] = res[4] + f[5] = res[5] + return f +} + +// montReduce performs the montgomery reduction +func (f *fp) montReduce(r *[2 * Limbs]uint64) *fp { + // Taken from Algorithm 14.32 in Handbook of Applied Cryptography + var r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, carry, k uint64 + var rr fp + + k = r[0] * inv + _, carry = mac(r[0], k, modulus[0], 0) + r1, carry = mac(r[1], k, modulus[1], carry) + r2, carry = mac(r[2], k, modulus[2], carry) + r3, carry = mac(r[3], k, modulus[3], carry) + r4, carry = mac(r[4], k, modulus[4], carry) + r5, carry = mac(r[5], k, modulus[5], carry) + r6, r7 = adc(r[6], 0, carry) + + k = r1 * inv + _, carry = mac(r1, k, modulus[0], 0) + r2, carry = mac(r2, k, modulus[1], carry) + r3, carry = mac(r3, k, modulus[2], carry) + r4, carry = mac(r4, k, modulus[3], carry) + r5, carry = mac(r5, k, modulus[4], carry) + r6, carry = mac(r6, k, modulus[5], carry) + r7, r8 = adc(r7, r[7], carry) + + k = r2 * inv + _, carry = mac(r2, k, modulus[0], 0) + r3, carry = mac(r3, k, modulus[1], carry) + r4, carry = mac(r4, k, modulus[2], carry) + r5, carry = mac(r5, k, modulus[3], carry) + r6, carry = mac(r6, k, modulus[4], carry) + r7, carry = mac(r7, k, modulus[5], carry) + r8, r9 = adc(r8, r[8], carry) + + k = r3 * inv + _, carry = mac(r3, k, modulus[0], 0) + r4, carry = mac(r4, k, modulus[1], carry) + r5, carry = mac(r5, k, modulus[2], carry) + r6, carry = mac(r6, k, modulus[3], carry) + r7, carry = mac(r7, k, modulus[4], carry) + r8, carry = mac(r8, k, modulus[5], carry) + r9, r10 = adc(r9, r[9], carry) + + k = r4 * inv + _, carry = mac(r4, k, modulus[0], 0) + r5, carry = mac(r5, k, modulus[1], carry) + r6, carry = mac(r6, k, modulus[2], carry) + r7, carry = mac(r7, k, modulus[3], carry) + r8, carry = mac(r8, k, modulus[4], carry) + r9, carry = mac(r9, k, modulus[5], carry) + r10, r11 = adc(r10, r[10], carry) + + k = r5 * inv + _, carry = mac(r5, k, modulus[0], 0) + rr[0], carry = mac(r6, k, modulus[1], carry) + rr[1], carry = mac(r7, k, modulus[2], carry) + rr[2], carry = mac(r8, k, modulus[3], carry) + rr[3], carry = mac(r9, k, modulus[4], carry) + rr[4], carry = mac(r10, k, modulus[5], carry) + rr[5], _ = adc(r11, r[11], carry) + + return f.Sub(&rr, &modulus) +} diff --git a/pkg/crypto/core/curves/native/bls12381/fp12.go b/pkg/crypto/core/curves/native/bls12381/fp12.go new file mode 100755 index 000000000..847930f2f --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fp12.go @@ -0,0 +1,231 @@ +package bls12381 + +import "io" + +// fp12 represents an element a + b w of fp^12 = fp^6 / w^2 - v. +type fp12 struct { + A, B fp6 +} + +// SetFp creates an element from a lower field +func (f *fp12) SetFp(a *fp) *fp12 { + f.A.SetFp(a) + f.B.SetZero() + return f +} + +// SetFp2 creates an element from a lower field +func (f *fp12) SetFp2(a *fp2) *fp12 { + f.A.SetFp2(a) + f.B.SetZero() + return f +} + +// SetFp6 creates an element from a lower field +func (f *fp12) SetFp6(a *fp6) *fp12 { + f.A.Set(a) + f.B.SetZero() + return f +} + +// Set copies the value `a` +func (f *fp12) Set(a *fp12) *fp12 { + f.A.Set(&a.A) + f.B.Set(&a.B) + return f +} + +// SetZero fp6 to zero +func (f *fp12) SetZero() *fp12 { + f.A.SetZero() + f.B.SetZero() + return f +} + +// SetOne fp6 to multiplicative identity element +func (f *fp12) SetOne() *fp12 { + f.A.SetOne() + f.B.SetZero() + return f +} + +// Random generates a random field element +func (f *fp12) Random(reader io.Reader) (*fp12, error) { + a, err := new(fp6).Random(reader) + if err != nil { + return nil, err + } + b, err := new(fp6).Random(reader) + if err != nil { + return nil, err + } + f.A.Set(a) + f.B.Set(b) + return f, nil +} + +// Square computes arg^2 +func (f *fp12) Square(arg *fp12) *fp12 { + var ab, apb, aTick, bTick, t fp6 + + ab.Mul(&arg.A, &arg.B) + apb.Add(&arg.A, &arg.B) + + aTick.MulByNonResidue(&arg.B) + aTick.Add(&aTick, &arg.A) + aTick.Mul(&aTick, &apb) + aTick.Sub(&aTick, &ab) + t.MulByNonResidue(&ab) + aTick.Sub(&aTick, &t) + + bTick.Double(&ab) + + f.A.Set(&aTick) + f.B.Set(&bTick) + return f +} + +// Invert computes this element's field inversion +func (f *fp12) Invert(arg *fp12) (*fp12, int) { + var a, b, t fp6 + a.Square(&arg.A) + b.Square(&arg.B) + b.MulByNonResidue(&b) + a.Sub(&a, &b) + _, wasInverted := t.Invert(&a) + + a.Mul(&arg.A, &t) + t.Neg(&t) + b.Mul(&arg.B, &t) + f.A.CMove(&f.A, &a, wasInverted) + f.B.CMove(&f.B, &b, wasInverted) + return f, wasInverted +} + +// Add computes arg1+arg2 +func (f *fp12) Add(arg1, arg2 *fp12) *fp12 { + f.A.Add(&arg1.A, &arg2.A) + f.B.Add(&arg1.B, &arg2.B) + return f +} + +// Sub computes arg1-arg2 +func (f *fp12) Sub(arg1, arg2 *fp12) *fp12 { + f.A.Sub(&arg1.A, &arg2.A) + f.B.Sub(&arg1.B, &arg2.B) + return f +} + +// Mul computes arg1*arg2 +func (f *fp12) Mul(arg1, arg2 *fp12) *fp12 { + var aa, bb, a2b2, a, b fp6 + + aa.Mul(&arg1.A, &arg2.A) + bb.Mul(&arg1.B, &arg2.B) + a2b2.Add(&arg2.A, &arg2.B) + b.Add(&arg1.A, &arg1.B) + b.Mul(&b, &a2b2) + b.Sub(&b, &aa) + b.Sub(&b, &bb) + a.MulByNonResidue(&bb) + a.Add(&a, &aa) + + f.A.Set(&a) + f.B.Set(&b) + return f +} + +// Neg computes the field negation +func (f *fp12) Neg(arg *fp12) *fp12 { + f.A.Neg(&arg.A) + f.B.Neg(&arg.B) + return f +} + +// MulByABD computes arg * a * b * c +func (f *fp12) MulByABD(arg *fp12, a, b, d *fp2) *fp12 { + var aa, bb, aTick, bTick fp6 + var bd fp2 + + aa.MulByAB(&arg.A, a, b) + bb.MulByB(&arg.B, d) + bd.Add(b, d) + + bTick.Add(&arg.A, &arg.B) + bTick.MulByAB(&bTick, a, &bd) + bTick.Sub(&bTick, &aa) + bTick.Sub(&bTick, &bb) + + aTick.MulByNonResidue(&bb) + aTick.Add(&aTick, &aa) + + f.A.Set(&aTick) + f.B.Set(&bTick) + + return f +} + +// Conjugate computes the field conjugation +func (f *fp12) Conjugate(arg *fp12) *fp12 { + f.A.Set(&arg.A) + f.B.Neg(&arg.B) + return f +} + +// FrobeniusMap raises this element to p. +func (f *fp12) FrobeniusMap(arg *fp12) *fp12 { + var a, b, up1epm1div6 fp6 + + // (u + 1)^((p - 1) / 6) + up1epm1div6.A = fp2{ + A: fp{ + 0x07089552b319d465, + 0xc6695f92b50a8313, + 0x97e83cccd117228f, + 0xa35baecab2dc29ee, + 0x1ce393ea5daace4d, + 0x08f2220fb0fb66eb, + }, + B: fp{ + 0xb2f66aad4ce5d646, + 0x5842a06bfc497cec, + 0xcf4895d42599d394, + 0xc11b9cba40a8e8d0, + 0x2e3813cbe5a0de89, + 0x110eefda88847faf, + }, + } + + a.FrobeniusMap(&arg.A) + b.FrobeniusMap(&arg.B) + + // b' = b' * (u + 1)^((p - 1) / 6) + b.Mul(&b, &up1epm1div6) + + f.A.Set(&a) + f.B.Set(&b) + return f +} + +// Equal returns 1 if fp12 == rhs, 0 otherwise +func (f *fp12) Equal(rhs *fp12) int { + return f.A.Equal(&rhs.A) & f.B.Equal(&rhs.B) +} + +// IsZero returns 1 if fp6 == 0, 0 otherwise +func (f *fp12) IsZero() int { + return f.A.IsZero() & f.B.IsZero() +} + +// IsOne returns 1 if fp12 == 1, 0 otherwise +func (f *fp12) IsOne() int { + return f.A.IsOne() & f.B.IsZero() +} + +// CMove performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f *fp12) CMove(arg1, arg2 *fp12, choice int) *fp12 { + f.A.CMove(&arg1.A, &arg2.A, choice) + f.B.CMove(&arg1.B, &arg2.B, choice) + return f +} diff --git a/pkg/crypto/core/curves/native/bls12381/fp12_test.go b/pkg/crypto/core/curves/native/bls12381/fp12_test.go new file mode 100755 index 000000000..c0ee091a3 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fp12_test.go @@ -0,0 +1,417 @@ +package bls12381 + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFp12Arithmetic(t *testing.T) { + var aa, bb, cc, d, e, f fp12 + a := fp12{ + A: fp6{ + A: fp2{ + A: fp{ + 0x47f9cb98b1b82d58, + 0x5fe911eba3aa1d9d, + 0x96bf1b5f4dd81db3, + 0x8100d27cc9259f5b, + 0xafa20b9674640eab, + 0x09bbcea7d8d9497d, + }, + B: fp{ + 0x0303cb98b1662daa, + 0xd93110aa0a621d5a, + 0xbfa9820c5be4a468, + 0x0ba3643ecb05a348, + 0xdc3534bb1f1c25a6, + 0x06c305bb19c0e1c1, + }, + }, + B: fp2{ + A: fp{ + 0x46f9cb98b162d858, + 0x0be9109cf7aa1d57, + 0xc791bc55fece41d2, + 0xf84c57704e385ec2, + 0xcb49c1d9c010e60f, + 0x0acdb8e158bfe3c8, + }, + B: fp{ + 0x8aefcb98b15f8306, + 0x3ea1108fe4f21d54, + 0xcf79f69fa1b7df3b, + 0xe4f54aa1d16b1a3c, + 0xba5e4ef86105a679, + 0x0ed86c0797bee5cf, + }, + }, + C: fp2{ + A: fp{ + 0xcee5cb98b15c2db4, + 0x71591082d23a1d51, + 0xd76230e944a17ca4, + 0xd19e3dd3549dd5b6, + 0xa972dc1701fa66e3, + 0x12e31f2dd6bde7d6, + }, + B: fp{ + 0xad2acb98b1732d9d, + 0x2cfd10dd06961d64, + 0x07396b86c6ef24e8, + 0xbd76e2fdb1bfc820, + 0x6afea7f6de94d0d5, + 0x10994b0c5744c040, + }, + }, + }, + B: fp6{ + A: fp2{ + A: fp{ + 0x47f9cb98b1b82d58, + 0x5fe911eba3aa1d9d, + 0x96bf1b5f4dd81db3, + 0x8100d27cc9259f5b, + 0xafa20b9674640eab, + 0x09bbcea7d8d9497d, + }, + B: fp{ + 0x0303cb98b1662daa, + 0xd93110aa0a621d5a, + 0xbfa9820c5be4a468, + 0x0ba3643ecb05a348, + 0xdc3534bb1f1c25a6, + 0x06c305bb19c0e1c1, + }, + }, + B: fp2{ + A: fp{ + 0x46f9cb98b162d858, + 0x0be9109cf7aa1d57, + 0xc791bc55fece41d2, + 0xf84c57704e385ec2, + 0xcb49c1d9c010e60f, + 0x0acdb8e158bfe3c8, + }, + B: fp{ + 0x8aefcb98b15f8306, + 0x3ea1108fe4f21d54, + 0xcf79f69fa1b7df3b, + 0xe4f54aa1d16b1a3c, + 0xba5e4ef86105a679, + 0x0ed86c0797bee5cf, + }, + }, + C: fp2{ + A: fp{ + 0xcee5cb98b15c2db4, + 0x71591082d23a1d51, + 0xd76230e944a17ca4, + 0xd19e3dd3549dd5b6, + 0xa972dc1701fa66e3, + 0x12e31f2dd6bde7d6, + }, + B: fp{ + 0xad2acb98b1732d9d, + 0x2cfd10dd06961d64, + 0x07396b86c6ef24e8, + 0xbd76e2fdb1bfc820, + 0x6afea7f6de94d0d5, + 0x10994b0c5744c040, + }, + }, + }, + } + + b := fp12{ + A: fp6{ + A: fp2{ + A: fp{ + 0x47f9_cb98_b1b8_2d58, + 0x5fe9_11eb_a3aa_1d9d, + 0x96bf_1b5f_4dd8_1db3, + 0x8100_d272_c925_9f5b, + 0xafa2_0b96_7464_0eab, + 0x09bb_cea7_d8d9_497d, + }, + B: fp{ + 0x0303_cb98_b166_2daa, + 0xd931_10aa_0a62_1d5a, + 0xbfa9_820c_5be4_a468, + 0x0ba3_643e_cb05_a348, + 0xdc35_34bb_1f1c_25a6, + 0x06c3_05bb_19c0_e1c1, + }, + }, + B: fp2{ + A: fp{ + 0x46f9_cb98_b162_d858, + 0x0be9_109c_f7aa_1d57, + 0xc791_bc55_fece_41d2, + 0xf84c_5770_4e38_5ec2, + 0xcb49_c1d9_c010_e60f, + 0x0acd_b8e1_58bf_e348, + }, + B: fp{ + 0x8aef_cb98_b15f_8306, + 0x3ea1_108f_e4f2_1d54, + 0xcf79_f69f_a1b7_df3b, + 0xe4f5_4aa1_d16b_1a3c, + 0xba5e_4ef8_6105_a679, + 0x0ed8_6c07_97be_e5cf, + }, + }, + C: fp2{ + A: fp{ + 0xcee5_cb98_b15c_2db4, + 0x7159_1082_d23a_1d51, + 0xd762_30e9_44a1_7ca4, + 0xd19e_3dd3_549d_d5b6, + 0xa972_dc17_01fa_66e3, + 0x12e3_1f2d_d6bd_e7d6, + }, + B: fp{ + 0xad2a_cb98_b173_2d9d, + 0x2cfd_10dd_0696_1d64, + 0x0739_6b86_c6ef_24e8, + 0xbd76_e2fd_b1bf_c820, + 0x6afe_a7f6_de94_d0d5, + 0x1099_4b0c_5744_c040, + }, + }, + }, + B: fp6{ + A: fp2{ + A: fp{ + 0x47f9_cb98_b1b8_2d58, + 0x5fe9_11eb_a3aa_1d9d, + 0x96bf_1b5f_4dd2_1db3, + 0x8100_d27c_c925_9f5b, + 0xafa2_0b96_7464_0eab, + 0x09bb_cea7_d8d9_497d, + }, + B: fp{ + 0x0303_cb98_b166_2daa, + 0xd931_10aa_0a62_1d5a, + 0xbfa9_820c_5be4_a468, + 0x0ba3_643e_cb05_a348, + 0xdc35_34bb_1f1c_25a6, + 0x06c3_05bb_19c0_e1c1, + }, + }, + B: fp2{ + A: fp{ + 0x46f9_cb98_b162_d858, + 0x0be9_109c_f7aa_1d57, + 0xc791_bc55_fece_41d2, + 0xf84c_5770_4e38_5ec2, + 0xcb49_c1d9_c010_e60f, + 0x0acd_b8e1_58bf_e3c8, + }, + B: fp{ + 0x8aef_cb98_b15f_8306, + 0x3ea1_108f_e4f2_1d54, + 0xcf79_f69f_a117_df3b, + 0xe4f5_4aa1_d16b_1a3c, + 0xba5e_4ef8_6105_a679, + 0x0ed8_6c07_97be_e5cf, + }, + }, + C: fp2{ + A: fp{ + 0xcee5_cb98_b15c_2db4, + 0x7159_1082_d23a_1d51, + 0xd762_30e9_44a1_7ca4, + 0xd19e_3dd3_549d_d5b6, + 0xa972_dc17_01fa_66e3, + 0x12e3_1f2d_d6bd_e7d6, + }, + B: fp{ + 0xad2a_cb98_b173_2d9d, + 0x2cfd_10dd_0696_1d64, + 0x0739_6b86_c6ef_24e8, + 0xbd76_e2fd_b1bf_c820, + 0x6afe_a7f6_de94_d0d5, + 0x1099_4b0c_5744_c040, + }, + }, + }, + } + + c := fp12{ + A: fp6{ + A: fp2{ + A: fp{ + 0x47f9_cb98_71b8_2d58, + 0x5fe9_11eb_a3aa_1d9d, + 0x96bf_1b5f_4dd8_1db3, + 0x8100_d27c_c925_9f5b, + 0xafa2_0b96_7464_0eab, + 0x09bb_cea7_d8d9_497d, + }, + B: fp{ + 0x0303_cb98_b166_2daa, + 0xd931_10aa_0a62_1d5a, + 0xbfa9_820c_5be4_a468, + 0x0ba3_643e_cb05_a348, + 0xdc35_34bb_1f1c_25a6, + 0x06c3_05bb_19c0_e1c1, + }, + }, + B: fp2{ + A: fp{ + 0x46f9_cb98_b162_d858, + 0x0be9_109c_f7aa_1d57, + 0x7791_bc55_fece_41d2, + 0xf84c_5770_4e38_5ec2, + 0xcb49_c1d9_c010_e60f, + 0x0acd_b8e1_58bf_e3c8, + }, + B: fp{ + 0x8aef_cb98_b15f_8306, + 0x3ea1_108f_e4f2_1d54, + 0xcf79_f69f_a1b7_df3b, + 0xe4f5_4aa1_d16b_133c, + 0xba5e_4ef8_6105_a679, + 0x0ed8_6c07_97be_e5cf, + }, + }, + C: fp2{ + A: fp{ + 0xcee5_cb98_b15c_2db4, + 0x7159_1082_d23a_1d51, + 0xd762_40e9_44a1_7ca4, + 0xd19e_3dd3_549d_d5b6, + 0xa972_dc17_01fa_66e3, + 0x12e3_1f2d_d6bd_e7d6, + }, + B: fp{ + 0xad2a_cb98_b173_2d9d, + 0x2cfd_10dd_0696_1d64, + 0x0739_6b86_c6ef_24e8, + 0xbd76_e2fd_b1bf_c820, + 0x6afe_a7f6_de94_d0d5, + 0x1099_4b0c_1744_c040, + }, + }, + }, + B: fp6{ + A: fp2{ + A: fp{ + 0x47f9_cb98_b1b8_2d58, + 0x5fe9_11eb_a3aa_1d9d, + 0x96bf_1b5f_4dd8_1db3, + 0x8100_d27c_c925_9f5b, + 0xafa2_0b96_7464_0eab, + 0x09bb_cea7_d8d9_497d, + }, + B: fp{ + 0x0303_cb98_b166_2daa, + 0xd931_10aa_0a62_1d5a, + 0xbfa9_820c_5be4_a468, + 0x0ba3_643e_cb05_a348, + 0xdc35_34bb_1f1c_25a6, + 0x06c3_05bb_19c0_e1c1, + }, + }, + B: fp2{ + A: fp{ + 0x46f9_cb98_b162_d858, + 0x0be9_109c_f7aa_1d57, + 0xc791_bc55_fece_41d2, + 0xf84c_5770_4e38_5ec2, + 0xcb49_c1d3_c010_e60f, + 0x0acd_b8e1_58bf_e3c8, + }, + B: fp{ + 0x8aef_cb98_b15f_8306, + 0x3ea1_108f_e4f2_1d54, + 0xcf79_f69f_a1b7_df3b, + 0xe4f5_4aa1_d16b_1a3c, + 0xba5e_4ef8_6105_a679, + 0x0ed8_6c07_97be_e5cf, + }, + }, + C: fp2{ + A: fp{ + 0xcee5_cb98_b15c_2db4, + 0x7159_1082_d23a_1d51, + 0xd762_30e9_44a1_7ca4, + 0xd19e_3dd3_549d_d5b6, + 0xa972_dc17_01fa_66e3, + 0x12e3_1f2d_d6bd_e7d6, + }, + B: fp{ + 0xad2a_cb98_b173_2d9d, + 0x2cfd_10dd_0696_1d64, + 0x0739_6b86_c6ef_24e8, + 0xbd76_e2fd_b1bf_c820, + 0x6afe_a7f6_de94_d0d5, + 0x1099_4b0c_5744_1040, + }, + }, + }, + } + + aa.Square(&a) + aa.Invert(&aa) + aa.Square(&aa) + aa.Add(&aa, &c) + + bb.Square(&b) + bb.Invert(&bb) + bb.Square(&bb) + bb.Add(&bb, &aa) + + cc.Square(&c) + cc.Invert(&cc) + cc.Square(&cc) + cc.Add(&cc, &bb) + + d.Square(&aa) + e.Mul(&aa, &aa) + require.Equal(t, 1, e.Equal(&d)) + + d.Square(&bb) + e.Mul(&bb, &bb) + require.Equal(t, 1, e.Equal(&d)) + + d.Square(&cc) + e.Mul(&cc, &cc) + require.Equal(t, 1, e.Equal(&d)) + + d.Square(&cc) + e.Add(&aa, &bb) + d.Mul(&d, &e) + + e.Mul(&cc, &cc) + e.Mul(&e, &aa) + f.Mul(&cc, &cc) + f.Mul(&f, &bb) + e.Add(&e, &f) + + require.Equal(t, 1, e.Equal(&d)) + + d.Invert(&aa) + e.Invert(&bb) + f.Mul(&aa, &bb) + f.Invert(&f) + require.Equal(t, 1, f.Equal(e.Mul(&e, &d))) + + require.Equal(t, 1, d.Mul(&d, &aa).IsOne()) + + require.Equal(t, 0, aa.Equal(d.FrobeniusMap(&aa))) + d.FrobeniusMap(&aa). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d). + FrobeniusMap(&d) + require.Equal(t, 1, aa.Equal(&d)) +} diff --git a/pkg/crypto/core/curves/native/bls12381/fp2.go b/pkg/crypto/core/curves/native/bls12381/fp2.go new file mode 100755 index 000000000..85cdd10b8 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fp2.go @@ -0,0 +1,344 @@ +package bls12381 + +import ( + "io" +) + +// fp2 is a point in p^2 +type fp2 struct { + A, B fp +} + +// Set copies a into fp2 +func (f *fp2) Set(a *fp2) *fp2 { + f.A.Set(&a.A) + f.B.Set(&a.B) + return f +} + +// SetZero fp2 = 0 +func (f *fp2) SetZero() *fp2 { + f.A.SetZero() + f.B.SetZero() + return f +} + +// SetOne fp2 to the multiplicative identity element +func (f *fp2) SetOne() *fp2 { + f.A.SetOne() + f.B.SetZero() + return f +} + +// SetFp creates an element from a lower field +func (f *fp2) SetFp(a *fp) *fp2 { + f.A.Set(a) + f.B.SetZero() + return f +} + +// Random generates a random field element +func (f *fp2) Random(reader io.Reader) (*fp2, error) { + a, err := new(fp).Random(reader) + if err != nil { + return nil, err + } + b, err := new(fp).Random(reader) + if err != nil { + return nil, err + } + f.A = *a + f.B = *b + return f, nil +} + +// IsZero returns 1 if fp2 == 0, 0 otherwise +func (f *fp2) IsZero() int { + return f.A.IsZero() & f.B.IsZero() +} + +// IsOne returns 1 if fp2 == 1, 0 otherwise +func (f *fp2) IsOne() int { + return f.A.IsOne() & f.B.IsZero() +} + +// Equal returns 1 if f == rhs, 0 otherwise +func (f *fp2) Equal(rhs *fp2) int { + return f.A.Equal(&rhs.A) & f.B.Equal(&rhs.B) +} + +// LexicographicallyLargest returns 1 if +// this element is strictly lexicographically larger than its negation +// 0 otherwise +func (f *fp2) LexicographicallyLargest() int { + // If this element's B coefficient is lexicographically largest + // then it is lexicographically largest. Otherwise, in the event + // the B coefficient is zero and the A coefficient is + // lexicographically largest, then this element is lexicographically + // largest. + + return f.B.LexicographicallyLargest() | + f.B.IsZero()&f.A.LexicographicallyLargest() +} + +// Sgn0 returns the lowest bit value +func (f *fp2) Sgn0() int { + // if A = 0 return B.Sgn0 else A.Sgn0 + a := f.A.IsZero() + t := f.B.Sgn0() & a + a = -a + 1 + t |= f.A.Sgn0() & a + return t +} + +// FrobeniusMap raises this element to p. +func (f *fp2) FrobeniusMap(a *fp2) *fp2 { + // This is always just a conjugation. If you're curious why, here's + // an article about it: https://alicebob.cryptoland.net/the-frobenius-endomorphism-with-finite-fields/ + return f.Conjugate(a) +} + +// Conjugate computes the conjugation of this element +func (f *fp2) Conjugate(a *fp2) *fp2 { + f.A.Set(&a.A) + f.B.Neg(&a.B) + return f +} + +// MulByNonResidue computes the following: +// multiply a + bu by u + 1, getting +// au + a + bu^2 + bu +// and because u^2 = -1, we get +// (a - b) + (a + b)u +func (f *fp2) MulByNonResidue(a *fp2) *fp2 { + var aa, bb fp + aa.Sub(&a.A, &a.B) + bb.Add(&a.A, &a.B) + f.A.Set(&aa) + f.B.Set(&bb) + return f +} + +// Square computes the square of this element +func (f *fp2) Square(arg *fp2) *fp2 { + var a, b, c fp + + // Complex squaring: + // + // v0 = a * b + // a' = (a + b) * (a + \beta*b) - v0 - \beta * v0 + // b' = 2 * v0 + // + // In BLS12-381's F_{p^2}, our \beta is -1, so we + // can modify this formula: + // + // a' = (a + b) * (a - b) + // b' = 2 * a * b + a.Add(&arg.A, &arg.B) + b.Sub(&arg.A, &arg.B) + c.Add(&arg.A, &arg.A) + + f.A.Mul(&a, &b) + f.B.Mul(&c, &arg.B) + return f +} + +// Add performs field addition +func (f *fp2) Add(arg1, arg2 *fp2) *fp2 { + f.A.Add(&arg1.A, &arg2.A) + f.B.Add(&arg1.B, &arg2.B) + return f +} + +// Double doubles specified element +func (f *fp2) Double(a *fp2) *fp2 { + f.A.Double(&a.A) + f.B.Double(&a.B) + return f +} + +// Sub performs field subtraction +func (f *fp2) Sub(arg1, arg2 *fp2) *fp2 { + f.A.Sub(&arg1.A, &arg2.A) + f.B.Sub(&arg1.B, &arg2.B) + return f +} + +// Mul computes Karatsuba multiplication +func (f *fp2) Mul(arg1, arg2 *fp2) *fp2 { + var v0, v1, t, a, b fp + + // Karatsuba multiplication: + // + // v0 = a0 * b0 + // v1 = a1 * b1 + // c0 = v0 + \beta * v1 + // c1 = (a0 + a1) * (b0 + b1) - v0 - v1 + // + // In BLS12-381's F_{p^2}, our \beta is -1, so we + // can modify this formula. (Also, since we always + // subtract v1, we can compute v1 = -a1 * b1.) + // + // v0 = a0 * a1 + // v1 = (-b0) * b1 + // a' = v0 + v1 + // b' = (a0 + b0) * (a1 + b1) - v0 + v1 + v0.Mul(&arg1.A, &arg2.A) + v1.Mul(new(fp).Neg(&arg1.B), &arg2.B) + + a.Add(&v0, &v1) + b.Add(&arg1.A, &arg1.B) + t.Add(&arg2.A, &arg2.B) + b.Mul(&b, &t) + b.Sub(&b, &v0) + b.Add(&b, &v1) + f.A.Set(&a) + f.B.Set(&b) + return f +} + +func (f *fp2) Mul0(arg1 *fp2, arg2 *fp) *fp2 { + f.A.Mul(&arg1.A, arg2) + f.B.Mul(&arg1.B, arg2) + return f +} + +// MulBy3b returns arg * 12 or 3 * b +func (f *fp2) MulBy3b(arg *fp2) *fp2 { + return f.Mul(arg, &curveG23B) +} + +// Neg performs field negation +func (f *fp2) Neg(a *fp2) *fp2 { + f.A.Neg(&a.A) + f.B.Neg(&a.B) + return f +} + +// Sqrt performs field square root +func (f *fp2) Sqrt(a *fp2) (*fp2, int) { + // Algorithm 9, https://eprint.iacr.org/2012/685.pdf + // with constant time modifications. + var a1, alpha, x0, t, res, res2 fp2 + e1 := a.IsZero() + // a1 = self^((p - 3) / 4) + a1.pow(a, &[Limbs]uint64{ + 0xee7fbfffffffeaaa, + 0x07aaffffac54ffff, + 0xd9cc34a83dac3d89, + 0xd91dd2e13ce144af, + 0x92c6e9ed90d2eb35, + 0x0680447a8e5ff9a6, + }) + + // alpha = a1^2 * a = a^((p - 3) / 2 + 1) = a^((p - 1) / 2) + alpha.Square(&a1) + alpha.Mul(&alpha, a) + + // x0 = self^((p + 1) / 4) + x0.Mul(&a1, a) + + // In the event that alpha = -1, the element is order p - 1. So + // we're just trying to get the square of an element of the subfield + // fp. This is given by x0 * u, since u = sqrt(-1). Since the element + // x0 = a + bu has b = 0, the solution is therefore au. + res2.A.Neg(&x0.B) + res2.B.Set(&x0.A) + // alpha == -1 + e2 := alpha.Equal(&fp2{ + A: fp{ + 0x43f5fffffffcaaae, + 0x32b7fff2ed47fffd, + 0x07e83a49a2e99d69, + 0xeca8f3318332bb7a, + 0xef148d1ea0f4c069, + 0x040ab3263eff0206, + }, + B: fp{}, + }) + + // Otherwise, the correct solution is (1 + alpha)^((p - 1) // 2) * x0 + t.SetOne() + t.Add(&t, &alpha) + t.pow(&t, &[Limbs]uint64{ + 0xdcff7fffffffd555, + 0x0f55ffff58a9ffff, + 0xb39869507b587b12, + 0xb23ba5c279c2895f, + 0x258dd3db21a5d66b, + 0x0d0088f51cbff34d, + }) + t.Mul(&t, &x0) + // if a = 0, then its zero + res.CMove(&res2, &res, e1) + // if alpha = -1, its not (1 + alpha)^((p - 1) // 2) * x0 + // but au + res.CMove(&t, &res, e2) + + // is the result^2 = a + t.Square(&res) + e3 := t.Equal(a) + f.CMove(f, &res, e3) + return f, e3 +} + +// Invert computes the multiplicative inverse of this field +// element, returning the original value of fp2 +// in the case that this element is zero. +func (f *fp2) Invert(arg *fp2) (*fp2, int) { + // We wish to find the multiplicative inverse of a nonzero + // element a + bu in fp2. We leverage an identity + // + // (a + bu)(a - bu) = a^2 + b^2 + // + // which holds because u^2 = -1. This can be rewritten as + // + // (a + bu)(a - bu)/(a^2 + b^2) = 1 + // + // because a^2 + b^2 = 0 has no nonzero solutions for (a, b). + // This gives that (a - bu)/(a^2 + b^2) is the inverse + // of (a + bu). Importantly, this can be computing using + // only a single inversion in fp. + var a, b, t fp + a.Square(&arg.A) + b.Square(&arg.B) + a.Add(&a, &b) + _, wasInverted := t.Invert(&a) + // a * t + a.Mul(&arg.A, &t) + // b * -t + b.Neg(&t) + b.Mul(&b, &arg.B) + f.A.CMove(&f.A, &a, wasInverted) + f.B.CMove(&f.B, &b, wasInverted) + return f, wasInverted +} + +// CMove performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f *fp2) CMove(arg1, arg2 *fp2, choice int) *fp2 { + f.A.CMove(&arg1.A, &arg2.A, choice) + f.B.CMove(&arg1.B, &arg2.B, choice) + return f +} + +// CNeg conditionally negates a if choice == 1 +func (f *fp2) CNeg(a *fp2, choice int) *fp2 { + var t fp2 + t.Neg(a) + return f.CMove(f, &t, choice) +} + +func (f *fp2) pow(base *fp2, exp *[Limbs]uint64) *fp2 { + res := (&fp2{}).SetOne() + tmp := (&fp2{}).SetZero() + + for i := len(exp) - 1; i >= 0; i-- { + for j := 63; j >= 0; j-- { + res.Square(res) + tmp.Mul(res, base) + res.CMove(res, tmp, int(exp[i]>>j)&1) + } + } + return f.Set(res) +} diff --git a/pkg/crypto/core/curves/native/bls12381/fp2_test.go b/pkg/crypto/core/curves/native/bls12381/fp2_test.go new file mode 100755 index 000000000..c10aceedf --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fp2_test.go @@ -0,0 +1,424 @@ +package bls12381 + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFp2Square(t *testing.T) { + a := fp2{ + A: fp{ + 0xc9a2183163ee70d4, + 0xbc3770a7196b5c91, + 0xa247f8c1304c5f44, + 0xb01fc2a3726c80b5, + 0xe1d293e5bbd919c9, + 0x04b78e80020ef2ca, + }, + B: fp{ + 0x952ea4460462618f, + 0x238d5eddf025c62f, + 0xf6c94b012ea92e72, + 0x03ce24eac1c93808, + 0x055950f945da483c, + 0x010a768d0df4eabc, + }, + } + b := fp2{ + A: fp{ + 0xa1e09175a4d2c1fe, + 0x8b33acfc204eff12, + 0xe24415a11b456e42, + 0x61d996b1b6ee1936, + 0x1164dbe8667c853c, + 0x0788557acc7d9c79, + }, + B: fp{ + 0xda6a87cc6f48fa36, + 0x0fc7b488277c1903, + 0x9445ac4adc448187, + 0x02616d5bc9099209, + 0xdbed46772db58d48, + 0x11b94d5076c7b7b1, + }, + } + + require.Equal(t, &b, a.Square(&a)) +} + +func TestFp2Mul(t *testing.T) { + a := fp2{ + A: fp{ + 0xc9a2183163ee70d4, + 0xbc3770a7196b5c91, + 0xa247f8c1304c5f44, + 0xb01fc2a3726c80b5, + 0xe1d293e5bbd919c9, + 0x04b78e80020ef2ca, + }, + B: fp{ + 0x952ea4460462618f, + 0x238d5eddf025c62f, + 0xf6c94b012ea92e72, + 0x03ce24eac1c93808, + 0x055950f945da483c, + 0x010a768d0df4eabc, + }, + } + b := fp2{ + A: fp{ + 0xa1e09175a4d2c1fe, + 0x8b33acfc204eff12, + 0xe24415a11b456e42, + 0x61d996b1b6ee1936, + 0x1164dbe8667c853c, + 0x0788557acc7d9c79, + }, + B: fp{ + 0xda6a87cc6f48fa36, + 0x0fc7b488277c1903, + 0x9445ac4adc448187, + 0x02616d5bc9099209, + 0xdbed46772db58d48, + 0x11b94d5076c7b7b1, + }, + } + c := fp2{ + A: fp{ + 0xf597483e27b4e0f7, + 0x610fbadf811dae5f, + 0x8432af917714327a, + 0x6a9a9603cf88f09e, + 0xf05a7bf8bad0eb01, + 0x09549131c003ffae, + }, + B: fp{ + 0x963b02d0f93d37cd, + 0xc95ce1cdb30a73d4, + 0x308725fa3126f9b8, + 0x56da3c167fab0d50, + 0x6b5086b5f4b6d6af, + 0x09c39f062f18e9f2, + }, + } + + require.Equal(t, 1, c.Equal(new(fp2).Mul(&a, &b))) +} + +func TestFp2Add(t *testing.T) { + a := fp2{ + A: fp{ + 0xc9a2183163ee70d4, + 0xbc3770a7196b5c91, + 0xa247f8c1304c5f44, + 0xb01fc2a3726c80b5, + 0xe1d293e5bbd919c9, + 0x04b78e80020ef2ca, + }, + B: fp{ + 0x952ea4460462618f, + 0x238d5eddf025c62f, + 0xf6c94b012ea92e72, + 0x03ce24eac1c93808, + 0x055950f945da483c, + 0x010a768d0df4eabc, + }, + } + b := fp2{ + A: fp{ + 0xa1e09175a4d2c1fe, + 0x8b33acfc204eff12, + 0xe24415a11b456e42, + 0x61d996b1b6ee1936, + 0x1164dbe8667c853c, + 0x0788557acc7d9c79, + }, + B: fp{ + 0xda6a87cc6f48fa36, + 0x0fc7b488277c1903, + 0x9445ac4adc448187, + 0x02616d5bc9099209, + 0xdbed46772db58d48, + 0x11b94d5076c7b7b1, + }, + } + c := fp2{ + A: fp{ + 0x6b82a9a708c132d2, + 0x476b1da339ba5ba4, + 0x848c0e624b91cd87, + 0x11f95955295a99ec, + 0xf3376fce22559f06, + 0x0c3fe3face8c8f43, + }, + B: fp{ + 0x6f992c1273ab5bc5, + 0x3355136617a1df33, + 0x8b0ef74c0aedaff9, + 0x062f92468ad2ca12, + 0xe1469770738fd584, + 0x12c3c3dd84bca26d, + }, + } + + require.Equal(t, 1, c.Equal(new(fp2).Add(&a, &b))) +} + +func TestFp2Sub(t *testing.T) { + a := fp2{ + A: fp{ + 0xc9a2183163ee70d4, + 0xbc3770a7196b5c91, + 0xa247f8c1304c5f44, + 0xb01fc2a3726c80b5, + 0xe1d293e5bbd919c9, + 0x04b78e80020ef2ca, + }, + B: fp{ + 0x952ea4460462618f, + 0x238d5eddf025c62f, + 0xf6c94b012ea92e72, + 0x03ce24eac1c93808, + 0x055950f945da483c, + 0x010a768d0df4eabc, + }, + } + b := fp2{ + A: fp{ + 0xa1e09175a4d2c1fe, + 0x8b33acfc204eff12, + 0xe24415a11b456e42, + 0x61d996b1b6ee1936, + 0x1164dbe8667c853c, + 0x0788557acc7d9c79, + }, + B: fp{ + 0xda6a87cc6f48fa36, + 0x0fc7b488277c1903, + 0x9445ac4adc448187, + 0x02616d5bc9099209, + 0xdbed46772db58d48, + 0x11b94d5076c7b7b1, + }, + } + c := fp2{ + A: fp{ + 0xe1c086bbbf1b5981, + 0x4fafc3a9aa705d7e, + 0x2734b5c10bb7e726, + 0xb2bd7776af037a3e, + 0x1b895fb398a84164, + 0x17304aef6f113cec, + }, + B: fp{ + 0x74c31c7995191204, + 0x3271aa5479fdad2b, + 0xc9b471574915a30f, + 0x65e40313ec44b8be, + 0x7487b2385b7067cb, + 0x09523b26d0ad19a4, + }, + } + + require.Equal(t, 1, c.Equal(new(fp2).Sub(&a, &b))) +} + +func TestFp2Neg(t *testing.T) { + a := fp2{ + A: fp{ + 0xc9a2183163ee70d4, + 0xbc3770a7196b5c91, + 0xa247f8c1304c5f44, + 0xb01fc2a3726c80b5, + 0xe1d293e5bbd919c9, + 0x04b78e80020ef2ca, + }, + B: fp{ + 0x952ea4460462618f, + 0x238d5eddf025c62f, + 0xf6c94b012ea92e72, + 0x03ce24eac1c93808, + 0x055950f945da483c, + 0x010a768d0df4eabc, + }, + } + b := fp2{ + A: fp{ + 0xf05ce7ce9c1139d7, + 0x62748f5797e8a36d, + 0xc4e8d9dfc66496df, + 0xb45788e181189209, + 0x694913d08772930d, + 0x1549836a3770f3cf, + }, + B: fp{ + 0x24d05bb9fb9d491c, + 0xfb1ea120c12e39d0, + 0x7067879fc807c7b1, + 0x60a9269a31bbdab6, + 0x45c256bcfd71649b, + 0x18f69b5d2b8afbde, + }, + } + + require.Equal(t, 1, b.Equal(new(fp2).Neg(&a))) +} + +func TestFp2Sqrt(t *testing.T) { + a := fp2{ + A: fp{ + 0x2beed14627d7f9e9, + 0xb6614e06660e5dce, + 0x06c4cc7c2f91d42c, + 0x996d78474b7a63cc, + 0xebaebc4c820d574e, + 0x18865e12d93fd845, + }, + B: fp{ + 0x7d828664baf4f566, + 0xd17e663996ec7339, + 0x679ead55cb4078d0, + 0xfe3b2260e001ec28, + 0x305993d043d91b68, + 0x0626f03c0489b72d, + }, + } + + asq, wasSquare := (&fp2{}).Sqrt(&a) + require.Equal(t, 1, wasSquare) + require.Equal(t, 1, a.Equal(asq.Square(asq))) + + b := fp2{ + A: fp{ + 0x6631000000105545, + 0x211400400eec000d, + 0x3fa7af30c820e316, + 0xc52a8b8d6387695d, + 0x9fb4e61d1e83eac5, + 0x005cb922afe84dc7, + }, + B: fp{}, + } + bsq, wasSquare := (&fp2{}).Sqrt(&b) + require.Equal(t, 1, wasSquare) + require.Equal(t, 1, b.Equal(bsq.Square(bsq))) + + c := fp2{ + A: fp{ + 0x44f600000051ffae, + 0x86b8014199480043, + 0xd7159952f1f3794a, + 0x755d6e3dfe1ffc12, + 0xd36cd6db5547e905, + 0x02f8c8ecbf1867bb, + }, + B: fp{}, + } + csq, wasSquare := (&fp2{}).Sqrt(&c) + require.Equal(t, 1, wasSquare) + require.Equal(t, 1, c.Equal(csq.Square(csq))) + + d := fp2{ + A: fp{ + 0xc5fa1bc8fd00d7f6, + 0x3830ca454606003b, + 0x2b287f1104b102da, + 0xa7fb30f28230f23e, + 0x339cdb9ee953dbf0, + 0x0d78ec51d989fc57, + }, + B: fp{ + 0x27ec4898cf87f613, + 0x9de1394e1abb05a5, + 0x0947f85dc170fc14, + 0x586fbc696b6114b7, + 0x2b3475a4077d7169, + 0x13e1c895cc4b6c22, + }, + } + _, wasSquare = (&fp2{}).Sqrt(&d) + require.Equal(t, 0, wasSquare) + + _, wasSquare = (&fp2{}).Sqrt(&fp2{}) + require.Equal(t, 1, wasSquare) +} + +func TestFp2Invert(t *testing.T) { + a := fp2{ + A: fp{ + 0x1128ecad67549455, + 0x9e7a1cff3a4ea1a8, + 0xeb208d51e08bcf27, + 0xe98ad40811f5fc2b, + 0x736c3a59232d511d, + 0x10acd42d29cfcbb6, + }, + B: fp{ + 0xd328e37cc2f58d41, + 0x948df0858a605869, + 0x6032f9d56f93a573, + 0x2be483ef3fffdc87, + 0x30ef61f88f483c2a, + 0x1333f55a35725be0, + }, + } + + b := fp2{ + A: fp{ + 0x0581a1333d4f48a6, + 0x58242f6ef0748500, + 0x0292c955349e6da5, + 0xba37721ddd95fcd0, + 0x70d167903aa5dfc5, + 0x11895e118b58a9d5, + }, + B: fp{ + 0x0eda09d2d7a85d17, + 0x8808e137a7d1a2cf, + 0x43ae2625c1ff21db, + 0xf85ac9fdf7a74c64, + 0x8fccdda5b8da9738, + 0x08e84f0cb32cd17d, + }, + } + + ainv, wasInverted := (&fp2{}).Invert(&a) + require.Equal(t, 1, wasInverted) + require.Equal(t, 1, b.Equal(ainv)) + + _, wasInverted = (&fp2{}).Invert(&fp2{}) + require.Equal(t, 0, wasInverted) +} + +func TestFp2LexicographicallyLargest(t *testing.T) { + require.Equal(t, 0, new(fp2).SetZero().LexicographicallyLargest()) + require.Equal(t, 0, new(fp2).SetOne().LexicographicallyLargest()) + + a := fp2{ + A: fp{ + 0x1128_ecad_6754_9455, + 0x9e7a_1cff_3a4e_a1a8, + 0xeb20_8d51_e08b_cf27, + 0xe98a_d408_11f5_fc2b, + 0x736c_3a59_232d_511d, + 0x10ac_d42d_29cf_cbb6, + }, + B: fp{ + 0xd328_e37c_c2f5_8d41, + 0x948d_f085_8a60_5869, + 0x6032_f9d5_6f93_a573, + 0x2be4_83ef_3fff_dc87, + 0x30ef_61f8_8f48_3c2a, + 0x1333_f55a_3572_5be0, + }, + } + + require.Equal(t, 1, a.LexicographicallyLargest()) + aNeg := new(fp2).Neg(&a) + require.Equal(t, 0, aNeg.LexicographicallyLargest()) + a.B.SetZero() + require.Equal(t, 0, a.LexicographicallyLargest()) + aNeg.B.SetZero() + require.Equal(t, 1, aNeg.LexicographicallyLargest()) +} diff --git a/pkg/crypto/core/curves/native/bls12381/fp6.go b/pkg/crypto/core/curves/native/bls12381/fp6.go new file mode 100755 index 000000000..0863fd152 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fp6.go @@ -0,0 +1,340 @@ +package bls12381 + +import "io" + +// fp6 represents an element +// a + b v + c v^2 of fp^6 = fp^2 / v^3 - u - 1. +type fp6 struct { + A, B, C fp2 +} + +// Set fp6 = a +func (f *fp6) Set(a *fp6) *fp6 { + f.A.Set(&a.A) + f.B.Set(&a.B) + f.C.Set(&a.C) + return f +} + +// SetFp creates an element from a lower field +func (f *fp6) SetFp(a *fp) *fp6 { + f.A.SetFp(a) + f.B.SetZero() + f.C.SetZero() + return f +} + +// SetFp2 creates an element from a lower field +func (f *fp6) SetFp2(a *fp2) *fp6 { + f.A.Set(a) + f.B.SetZero() + f.C.SetZero() + return f +} + +// SetZero fp6 to zero +func (f *fp6) SetZero() *fp6 { + f.A.SetZero() + f.B.SetZero() + f.C.SetZero() + return f +} + +// SetOne fp6 to multiplicative identity element +func (f *fp6) SetOne() *fp6 { + f.A.SetOne() + f.B.SetZero() + f.C.SetZero() + return f +} + +// Random generates a random field element +func (f *fp6) Random(reader io.Reader) (*fp6, error) { + a, err := new(fp2).Random(reader) + if err != nil { + return nil, err + } + b, err := new(fp2).Random(reader) + if err != nil { + return nil, err + } + c, err := new(fp2).Random(reader) + if err != nil { + return nil, err + } + f.A.Set(a) + f.B.Set(b) + f.C.Set(c) + return f, nil +} + +// Add computes arg1+arg2 +func (f *fp6) Add(arg1, arg2 *fp6) *fp6 { + f.A.Add(&arg1.A, &arg2.A) + f.B.Add(&arg1.B, &arg2.B) + f.C.Add(&arg1.C, &arg2.C) + return f +} + +// Double computes arg1+arg1 +func (f *fp6) Double(arg *fp6) *fp6 { + return f.Add(arg, arg) +} + +// Sub computes arg1-arg2 +func (f *fp6) Sub(arg1, arg2 *fp6) *fp6 { + f.A.Sub(&arg1.A, &arg2.A) + f.B.Sub(&arg1.B, &arg2.B) + f.C.Sub(&arg1.C, &arg2.C) + return f +} + +// Mul computes arg1*arg2 +func (f *fp6) Mul(arg1, arg2 *fp6) *fp6 { + var aa, bb, cc, s, t1, t2, t3 fp2 + + aa.Mul(&arg1.A, &arg2.A) + bb.Mul(&arg1.B, &arg2.B) + cc.Mul(&arg1.C, &arg2.C) + + t1.Add(&arg2.B, &arg2.C) + s.Add(&arg1.B, &arg1.C) + t1.Mul(&t1, &s) + t1.Sub(&t1, &bb) + t1.Sub(&t1, &cc) + t1.MulByNonResidue(&t1) + t1.Add(&t1, &aa) + + t3.Add(&arg2.A, &arg2.C) + s.Add(&arg1.A, &arg1.C) + t3.Mul(&t3, &s) + t3.Sub(&t3, &aa) + t3.Add(&t3, &bb) + t3.Sub(&t3, &cc) + + t2.Add(&arg2.A, &arg2.B) + s.Add(&arg1.A, &arg1.B) + t2.Mul(&t2, &s) + t2.Sub(&t2, &aa) + t2.Sub(&t2, &bb) + cc.MulByNonResidue(&cc) + t2.Add(&t2, &cc) + + f.A.Set(&t1) + f.B.Set(&t2) + f.C.Set(&t3) + return f +} + +// MulByB scales this field by a scalar in the B coefficient +func (f *fp6) MulByB(arg *fp6, b *fp2) *fp6 { + var bB, t1, t2 fp2 + bB.Mul(&arg.B, b) + // (b + c) * arg2 - bB + t1.Add(&arg.B, &arg.C) + t1.Mul(&t1, b) + t1.Sub(&t1, &bB) + t1.MulByNonResidue(&t1) + + t2.Add(&arg.A, &arg.B) + t2.Mul(&t2, b) + t2.Sub(&t2, &bB) + + f.A.Set(&t1) + f.B.Set(&t2) + f.C.Set(&bB) + return f +} + +// MulByAB scales this field by scalars in the A and B coefficients +func (f *fp6) MulByAB(arg *fp6, a, b *fp2) *fp6 { + var aA, bB, t1, t2, t3 fp2 + + aA.Mul(&arg.A, a) + bB.Mul(&arg.B, b) + + t1.Add(&arg.B, &arg.C) + t1.Mul(&t1, b) + t1.Sub(&t1, &bB) + t1.MulByNonResidue(&t1) + t1.Add(&t1, &aA) + + t2.Add(a, b) + t3.Add(&arg.A, &arg.B) + t2.Mul(&t2, &t3) + t2.Sub(&t2, &aA) + t2.Sub(&t2, &bB) + + t3.Add(&arg.A, &arg.C) + t3.Mul(&t3, a) + t3.Sub(&t3, &aA) + t3.Add(&t3, &bB) + + f.A.Set(&t1) + f.B.Set(&t2) + f.C.Set(&t3) + + return f +} + +// MulByNonResidue multiplies by quadratic nonresidue v. +func (f *fp6) MulByNonResidue(arg *fp6) *fp6 { + // Given a + bv + cv^2, this produces + // av + bv^2 + cv^3 + // but because v^3 = u + 1, we have + // c(u + 1) + av + bv^2 + var a, b, c fp2 + a.MulByNonResidue(&arg.C) + b.Set(&arg.A) + c.Set(&arg.B) + f.A.Set(&a) + f.B.Set(&b) + f.C.Set(&c) + return f +} + +// FrobeniusMap raises this element to p. +func (f *fp6) FrobeniusMap(arg *fp6) *fp6 { + var a, b, c fp2 + pm1Div3 := fp2{ + A: fp{}, + B: fp{ + 0xcd03c9e48671f071, + 0x5dab22461fcda5d2, + 0x587042afd3851b95, + 0x8eb60ebe01bacb9e, + 0x03f97d6e83d050d2, + 0x18f0206554638741, + }, + } + p2m2Div3 := fp2{ + A: fp{ + 0x890dc9e4867545c3, + 0x2af322533285a5d5, + 0x50880866309b7e2c, + 0xa20d1b8c7e881024, + 0x14e4f04fe2db9068, + 0x14e56d3f1564853a, + }, + B: fp{}, + } + a.FrobeniusMap(&arg.A) + b.FrobeniusMap(&arg.B) + c.FrobeniusMap(&arg.C) + + // b = b * (u + 1)^((p - 1) / 3) + b.Mul(&b, &pm1Div3) + + // c = c * (u + 1)^((2p - 2) / 3) + c.Mul(&c, &p2m2Div3) + + f.A.Set(&a) + f.B.Set(&b) + f.C.Set(&c) + return f +} + +// Square computes fp6^2 +func (f *fp6) Square(arg *fp6) *fp6 { + var s0, s1, s2, s3, s4, ab, bc fp2 + + s0.Square(&arg.A) + ab.Mul(&arg.A, &arg.B) + s1.Double(&ab) + s2.Sub(&arg.A, &arg.B) + s2.Add(&s2, &arg.C) + s2.Square(&s2) + bc.Mul(&arg.B, &arg.C) + s3.Double(&bc) + s4.Square(&arg.C) + + f.A.MulByNonResidue(&s3) + f.A.Add(&f.A, &s0) + + f.B.MulByNonResidue(&s4) + f.B.Add(&f.B, &s1) + + // s1 + s2 + s3 - s0 - s4 + f.C.Add(&s1, &s2) + f.C.Add(&f.C, &s3) + f.C.Sub(&f.C, &s0) + f.C.Sub(&f.C, &s4) + + return f +} + +// Invert computes this element's field inversion +func (f *fp6) Invert(arg *fp6) (*fp6, int) { + var a, b, c, s, t fp2 + + // a' = a^2 - (b * c).mul_by_nonresidue() + a.Mul(&arg.B, &arg.C) + a.MulByNonResidue(&a) + t.Square(&arg.A) + a.Sub(&t, &a) + + // b' = (c^2).mul_by_nonresidue() - (a * b) + b.Square(&arg.C) + b.MulByNonResidue(&b) + t.Mul(&arg.A, &arg.B) + b.Sub(&b, &t) + + // c' = b^2 - (a * c) + c.Square(&arg.B) + t.Mul(&arg.A, &arg.C) + c.Sub(&c, &t) + + // t = ((b * c') + (c * b')).mul_by_nonresidue() + (a * a') + s.Mul(&arg.B, &c) + t.Mul(&arg.C, &b) + s.Add(&s, &t) + s.MulByNonResidue(&s) + + t.Mul(&arg.A, &a) + s.Add(&s, &t) + + _, wasInverted := t.Invert(&s) + + // newA = a' * t^-1 + s.Mul(&a, &t) + f.A.CMove(&f.A, &s, wasInverted) + // newB = b' * t^-1 + s.Mul(&b, &t) + f.B.CMove(&f.B, &s, wasInverted) + // newC = c' * t^-1 + s.Mul(&c, &t) + f.C.CMove(&f.C, &s, wasInverted) + return f, wasInverted +} + +// Neg computes the field negation +func (f *fp6) Neg(arg *fp6) *fp6 { + f.A.Neg(&arg.A) + f.B.Neg(&arg.B) + f.C.Neg(&arg.C) + return f +} + +// IsZero returns 1 if fp6 == 0, 0 otherwise +func (f *fp6) IsZero() int { + return f.A.IsZero() & f.B.IsZero() & f.C.IsZero() +} + +// IsOne returns 1 if fp6 == 1, 0 otherwise +func (f *fp6) IsOne() int { + return f.A.IsOne() & f.B.IsZero() & f.B.IsZero() +} + +// Equal returns 1 if fp6 == rhs, 0 otherwise +func (f *fp6) Equal(rhs *fp6) int { + return f.A.Equal(&rhs.A) & f.B.Equal(&rhs.B) & f.C.Equal(&rhs.C) +} + +// CMove performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f *fp6) CMove(arg1, arg2 *fp6, choice int) *fp6 { + f.A.CMove(&arg1.A, &arg2.A, choice) + f.B.CMove(&arg1.B, &arg2.B, choice) + f.C.CMove(&arg1.C, &arg2.C, choice) + return f +} diff --git a/pkg/crypto/core/curves/native/bls12381/fp6_test.go b/pkg/crypto/core/curves/native/bls12381/fp6_test.go new file mode 100755 index 000000000..82319d37d --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fp6_test.go @@ -0,0 +1,217 @@ +package bls12381 + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFp6Arithmetic(t *testing.T) { + a := fp6{ + A: fp2{ + A: fp{ + 0x47f9cb98b1b82d58, + 0x5fe911eba3aa1d9d, + 0x96bf1b5f4dd81db3, + 0x8100d27cc9259f5b, + 0xafa20b9674640eab, + 0x09bbcea7d8d9497d, + }, + B: fp{ + 0x0303cb98b1662daa, + 0xd93110aa0a621d5a, + 0xbfa9820c5be4a468, + 0x0ba3643ecb05a348, + 0xdc3534bb1f1c25a6, + 0x06c305bb19c0e1c1, + }, + }, + B: fp2{ + A: fp{ + 0x46f9cb98b162d858, + 0x0be9109cf7aa1d57, + 0xc791bc55fece41d2, + 0xf84c57704e385ec2, + 0xcb49c1d9c010e60f, + 0x0acdb8e158bfe3c8, + }, + B: fp{ + 0x8aefcb98b15f8306, + 0x3ea1108fe4f21d54, + 0xcf79f69fa1b7df3b, + 0xe4f54aa1d16b1a3c, + 0xba5e4ef86105a679, + 0x0ed86c0797bee5cf, + }, + }, + C: fp2{ + A: fp{ + 0xcee5cb98b15c2db4, + 0x71591082d23a1d51, + 0xd76230e944a17ca4, + 0xd19e3dd3549dd5b6, + 0xa972dc1701fa66e3, + 0x12e31f2dd6bde7d6, + }, + B: fp{ + 0xad2acb98b1732d9d, + 0x2cfd10dd06961d64, + 0x07396b86c6ef24e8, + 0xbd76e2fdb1bfc820, + 0x6afea7f6de94d0d5, + 0x10994b0c5744c040, + }, + }, + } + b := fp6{ + A: fp2{ + A: fp{ + 0xf120cb98b16fd84b, + 0x5fb510cff3de1d61, + 0x0f21a5d069d8c251, + 0xaa1fd62f34f2839a, + 0x5a1335157f89913f, + 0x14a3fe329643c247, + }, + B: fp{ + 0x3516cb98b16c82f9, + 0x926d10c2e1261d5f, + 0x1709e01a0cc25fba, + 0x96c8c960b8253f14, + 0x4927c234207e51a9, + 0x18aeb158d542c44e, + }, + }, + B: fp2{ + A: fp{ + 0xbf0dcb98b16982fc, + 0xa67910b71d1a1d5c, + 0xb7c147c2b8fb06ff, + 0x1efa710d47d2e7ce, + 0xed20a79c7e27653c, + 0x02b85294dac1dfba, + }, + B: fp{ + 0x9d52cb98b18082e5, + 0x621d111151761d6f, + 0xe79882603b48af43, + 0x0ad31637a4f4da37, + 0xaeac737c5ac1cf2e, + 0x006e7e735b48b824, + }, + }, + C: fp2{ + A: fp{ + 0xe148cb98b17d2d93, + 0x94d511043ebe1d6c, + 0xef80bca9de324cac, + 0xf77c0969282795b1, + 0x9dc1009afbb68f97, + 0x047931999a47ba2b, + }, + B: fp{ + 0x253ecb98b179d841, + 0xc78d10f72c061d6a, + 0xf768f6f3811bea15, + 0xe424fc9aab5a512b, + 0x8cd58db99cab5001, + 0x0883e4bfd946bc32, + }, + }, + } + c := fp6{ + A: fp2{ + A: fp{ + 0x6934cb98b17682ef, + 0xfa4510ea194e1d67, + 0xff51313d2405877e, + 0xd0cdefcc2e8d0ca5, + 0x7bea1ad83da0106b, + 0x0c8e97e61845be39, + }, + B: fp{ + 0x4779cb98b18d82d8, + 0xb5e911444daa1d7a, + 0x2f286bdaa6532fc2, + 0xbca694f68baeff0f, + 0x3d75e6b81a3a7a5d, + 0x0a44c3c498cc96a3, + }, + }, + B: fp2{ + A: fp{ + 0x8b6fcb98b18a2d86, + 0xe8a111373af21d77, + 0x3710a624493ccd2b, + 0xa94f88280ee1ba89, + 0x2c8a73d6bb2f3ac7, + 0x0e4f76ead7cb98aa, + }, + B: fp{ + 0xcf65cb98b186d834, + 0x1b59112a283a1d74, + 0x3ef8e06dec266a95, + 0x95f87b5992147603, + 0x1b9f00f55c23fb31, + 0x125a2a1116ca9ab1, + }, + }, + C: fp2{ + A: fp{ + 0x135bcb98b18382e2, + 0x4e11111d15821d72, + 0x46e11ab78f1007fe, + 0x82a16e8b1547317d, + 0x0ab38e13fd18bb9b, + 0x1664dd3755c99cb8, + }, + B: fp{ + 0xce65cb98b1318334, + 0xc7590fdb7c3a1d2e, + 0x6fcb81649d1c8eb3, + 0x0d44004d1727356a, + 0x3746b738a7d0d296, + 0x136c144a96b134fc, + }, + }, + } + + d := new(fp6).Square(&a) + e := new(fp6).Mul(&a, &a) + require.Equal(t, 1, e.Equal(d)) + + d.Square(&b) + e.Mul(&b, &b) + require.Equal(t, 1, e.Equal(d)) + + d.Square(&c) + e.Mul(&c, &c) + require.Equal(t, 1, e.Equal(d)) + + // (a + b) * c^2 + d.Add(&a, &b) + d.Mul(d, new(fp6).Square(&c)) + + e.Mul(&c, &c) + e.Mul(e, &a) + tt := new(fp6).Mul(&c, &c) + tt.Mul(tt, &b) + e.Add(e, tt) + + require.Equal(t, 1, d.Equal(e)) + + _, wasInverted := d.Invert(&a) + require.Equal(t, 1, wasInverted) + _, wasInverted = e.Invert(&b) + require.Equal(t, 1, wasInverted) + + tt.Mul(&a, &b) + _, wasInverted = tt.Invert(tt) + require.Equal(t, 1, wasInverted) + d.Mul(d, e) + require.Equal(t, 1, tt.Equal(d)) + + _, _ = d.Invert(&a) + e.SetOne() + require.Equal(t, 1, e.Equal(d.Mul(d, &a))) +} diff --git a/pkg/crypto/core/curves/native/bls12381/fp_test.go b/pkg/crypto/core/curves/native/bls12381/fp_test.go new file mode 100755 index 000000000..6ad685a77 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fp_test.go @@ -0,0 +1,297 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls12381 + +import ( + crand "crypto/rand" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func TestFpSetOne(t *testing.T) { + var fp fp + fp.SetOne() + require.NotNil(t, fp) + require.Equal(t, fp, r) +} + +func TestFpSetUint64(t *testing.T) { + var act fp + act.SetUint64(1 << 60) + require.NotNil(t, act) + // Remember it will be in montgomery form + require.Equal(t, act[0], uint64(0xf6ea9fde37db5e8c)) +} + +func TestFpAdd(t *testing.T) { + var lhs, rhs, exp, res fp + lhs.SetOne() + rhs.SetOne() + exp.SetUint64(2) + res.Add(&lhs, &rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(&exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + e := l + r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + res.Add(&lhs, &rhs) + require.NotNil(t, res) + require.Equal(t, exp, res) + } +} + +func TestFpSub(t *testing.T) { + var lhs, rhs, exp, res fp + lhs.SetOne() + rhs.SetOne() + exp.SetZero() + res.Sub(&lhs, &rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(&exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + if l < r { + l, r = r, l + } + e := l - r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + res.Sub(&lhs, &rhs) + require.NotNil(t, res) + require.Equal(t, exp, res) + } +} + +func TestFpMul(t *testing.T) { + var lhs, rhs, exp, res fp + lhs.SetOne() + rhs.SetOne() + exp.SetOne() + res.Mul(&lhs, &rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(&exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint32() + r := rand.Uint32() + e := uint64(l) * uint64(r) + lhs.SetUint64(uint64(l)) + rhs.SetUint64(uint64(r)) + exp.SetUint64(e) + + res.Mul(&lhs, &rhs) + require.NotNil(t, res) + require.Equal(t, exp, res) + } +} + +func TestFpDouble(t *testing.T) { + var a, e, res fp + a.SetUint64(2) + e.SetUint64(4) + require.Equal(t, &e, res.Double(&a)) + + for i := 0; i < 25; i++ { + tv := rand.Uint32() + ttv := uint64(tv) * 2 + a.SetUint64(uint64(tv)) + e.SetUint64(ttv) + require.Equal(t, &e, res.Double(&a)) + } +} + +func TestFpSquare(t *testing.T) { + var a, e, res fp + a.SetUint64(4) + e.SetUint64(16) + require.Equal(t, 1, e.Equal(res.Square(&a))) + + a.SetUint64(2854263694) + e.SetUint64(8146821234886525636) + require.Equal(t, 1, e.Equal(res.Square(&a))) + + for i := 0; i < 25; i++ { + j := rand.Uint32() + exp := uint64(j) * uint64(j) + e.SetUint64(exp) + a.SetUint64(uint64(j)) + require.Equal(t, 1, e.Equal(res.Square(&a)), "exp = %d, j = %d", exp, j) + } +} + +func TestFpNeg(t *testing.T) { + var g, a, e fp + g.SetLimbs(&[Limbs]uint64{7, 0, 0, 0, 0, 0}) + a.SetOne() + a.Neg(&a) + e.SetRaw(&[Limbs]uint64{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206}) + require.Equal(t, 1, e.Equal(&a)) + a.Neg(&g) + e.SetRaw(&[Limbs]uint64{0x21baffffffe90017, 0x445bffa5cba3ffed, 0xd028c5627db257bc, 0x14275ad5a2de0d96, 0x3e7434202365960e, 0x0249d4217f792796}) + require.Equal(t, e, a) +} + +func TestFpExp(t *testing.T) { + var a, e, by fp + e.SetUint64(8) + a.SetUint64(2) + by.SetUint64(3) + require.Equal(t, &e, a.Exp(&a, &by)) +} + +func TestFpSqrt(t *testing.T) { + var t1, t2, t3 fp + t1.SetUint64(2) + t2.Neg(&t1) + t3.Square(&t1) + _, wasSquare := t3.Sqrt(&t3) + + require.Equal(t, 1, wasSquare) + require.Equal(t, 1, t1.Equal(&t3)|t2.Equal(&t3)) + t1.SetUint64(5) + _, wasSquare = t1.Sqrt(&t1) + require.Equal(t, 0, wasSquare) +} + +func TestFpInvert(t *testing.T) { + var two, twoInv, a, lhs, rhs, rhsInv fp + twoInv.SetRaw(&[Limbs]uint64{0x1804000000015554, 0x855000053ab00001, 0x633cb57c253c276f, 0x6e22d1ec31ebb502, 0xd3916126f2d14ca2, 0x17fbb8571a006596}) + two.SetUint64(2) + _, inverted := a.Invert(&two) + require.Equal(t, 1, inverted) + require.Equal(t, &a, &twoInv) + + lhs.SetUint64(9) + rhs.SetUint64(3) + _, inverted = rhsInv.Invert(&rhs) + require.Equal(t, 1, inverted) + require.Equal(t, &rhs, lhs.Mul(&lhs, &rhsInv)) + + rhs.SetZero() + _, inverted = lhs.Invert(&rhs) + require.Equal(t, 0, inverted) +} + +func TestFpCMove(t *testing.T) { + var t1, t2, tt fp + t1.SetUint64(5) + t2.SetUint64(10) + require.Equal(t, &t1, tt.CMove(&t1, &t2, 0)) + require.Equal(t, &t2, tt.CMove(&t1, &t2, 1)) +} + +func TestFpBytes(t *testing.T) { + var t1, t2 fp + t1.SetUint64(99) + seq := t1.Bytes() + _, suc := t2.SetBytes(&seq) + require.Equal(t, 1, suc) + require.Equal(t, t1, t2) + + for i := 0; i < 25; i++ { + t1.SetUint64(rand.Uint64()) + seq = t1.Bytes() + _, suc = t2.SetBytes(&seq) + require.Equal(t, 1, suc) + require.Equal(t, t1, t2) + } +} + +func TestFpBigInt(t *testing.T) { + var t1, t2, e fp + t1.SetBigInt(big.NewInt(9999)) + t2.SetBigInt(t1.BigInt()) + require.Equal(t, t1, t2) + + e.SetRaw(&[Limbs]uint64{0x922af810e5e35f31, 0x6bc75973ed382d59, 0xd4716c9d4d491d42, 0x69d98d1ebeeb3f6e, 0x7e425d7b46d4a82b, 0x12d04b0965870e92}) + b := new(big.Int).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}) + t1.SetBigInt(b) + require.Equal(t, e, t1) + e.Neg(&e) + b.Neg(b) + t1.SetBigInt(b) + require.Equal(t, e, t1) +} + +func TestFpSetBytesWideBigInt(t *testing.T) { + var a fp + var tv2 [96]byte + for i := 0; i < 25; i++ { + _, _ = crand.Read(tv2[:]) + e := new(big.Int).SetBytes(tv2[:]) + e.Mod(e, biModulus) + + tv := internal.ReverseScalarBytes(tv2[:]) + copy(tv2[:], tv) + a.SetBytesWide(&tv2) + require.Equal(t, 0, e.Cmp(a.BigInt())) + } +} + +func TestFpToMontgomery(t *testing.T) { + var v fp + v.SetUint64(2) + require.Equal(t, fp{0x321300000006554f, 0xb93c0018d6c40005, 0x57605e0db0ddbb51, 0x8b256521ed1f9bcb, 0x6cf28d7901622c03, 0x11ebab9dbb81e28c}, v) +} + +func TestFpFromMontgomery(t *testing.T) { + var v fp + e := fp{2, 0, 0, 0, 0, 0} + v.SetUint64(2) + v.fromMontgomery(&v) + require.Equal(t, e, v) +} + +func TestFpLexicographicallyLargest(t *testing.T) { + require.Equal(t, 0, new(fp).SetZero().LexicographicallyLargest()) + require.Equal(t, 0, new(fp).SetOne().LexicographicallyLargest()) + require.Equal(t, 0, (&fp{ + 0xa1fafffffffe5557, + 0x995bfff976a3fffe, + 0x03f41d24d174ceb4, + 0xf6547998c1995dbd, + 0x778a468f507a6034, + 0x020559931f7f8103, + }).LexicographicallyLargest()) + require.Equal(t, 1, (&fp{ + 0x1804000000015554, + 0x855000053ab00001, + 0x633cb57c253c276f, + 0x6e22d1ec31ebb502, + 0xd3916126f2d14ca2, + 0x17fbb8571a006596, + }).LexicographicallyLargest()) + require.Equal(t, 1, (&fp{ + 0x43f5fffffffcaaae, + 0x32b7fff2ed47fffd, + 0x07e83a49a2e99d69, + 0xeca8f3318332bb7a, + 0xef148d1ea0f4c069, + 0x040ab3263eff0206, + }).LexicographicallyLargest()) +} diff --git a/pkg/crypto/core/curves/native/bls12381/fq.go b/pkg/crypto/core/curves/native/bls12381/fq.go new file mode 100755 index 000000000..f925beb5b --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fq.go @@ -0,0 +1,416 @@ +package bls12381 + +import ( + "encoding/binary" + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +type Fq [native.FieldLimbs]uint64 + +var ( + bls12381FqInitonce sync.Once + bls12381FqParams native.FieldParams +) + +// 2^S * t = MODULUS - 1 with t odd +const fqS = 32 + +// qInv = -(q^{-1} mod 2^64) mod 2^64 +const qInv = 0xfffffffeffffffff + +// fqGenerator = 7 (multiplicative fqGenerator of r-1 order, that is also quadratic nonresidue) +var fqGenerator = [native.FieldLimbs]uint64{0x0000000efffffff1, 0x17e363d300189c0f, 0xff9c57876f8457b0, 0x351332208fc5a8c4} + +// fqModulus +var fqModulus = [native.FieldLimbs]uint64{0xffffffff00000001, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48} + +func Bls12381FqNew() *native.Field { + return &native.Field{ + Value: [native.FieldLimbs]uint64{}, + Params: getBls12381FqParams(), + Arithmetic: bls12381FqArithmetic{}, + } +} + +func bls12381FqParamsInit() { + bls12381FqParams = native.FieldParams{ + R: [native.FieldLimbs]uint64{0x00000001fffffffe, 0x5884b7fa00034802, 0x998c4fefecbc4ff5, 0x1824b159acc5056f}, + R2: [native.FieldLimbs]uint64{0xc999e990f3f29c6d, 0x2b6cedcb87925c23, 0x05d314967254398f, 0x0748d9d99f59ff11}, + R3: [native.FieldLimbs]uint64{0xc62c1807439b73af, 0x1b3e0d188cf06990, 0x73d13c71c7b5f418, 0x6e2a5bb9c8db33e9}, + Modulus: [native.FieldLimbs]uint64{0xffffffff00000001, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48}, + BiModulus: new(big.Int).SetBytes([]byte{ + 0x73, 0xed, 0xa7, 0x53, 0x29, 0x9d, 0x7d, 0x48, 0x33, 0x39, 0xd8, 0x08, 0x09, 0xa1, 0xd8, 0x05, 0x53, 0xbd, 0xa4, 0x02, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, + }), + } +} + +func getBls12381FqParams() *native.FieldParams { + bls12381FqInitonce.Do(bls12381FqParamsInit) + return &bls12381FqParams +} + +// bls12381FqArithmetic is a struct with all the methods needed for working +// in mod q +type bls12381FqArithmetic struct{} + +// ToMontgomery converts this field to montgomery form +func (f bls12381FqArithmetic) ToMontgomery(out, arg *[native.FieldLimbs]uint64) { + // arg.R^0 * R^2 / R = arg.R + f.Mul(out, arg, &getBls12381FqParams().R2) +} + +// FromMontgomery converts this field from montgomery form +func (f bls12381FqArithmetic) FromMontgomery(out, arg *[native.FieldLimbs]uint64) { + // Mul by 1 is division by 2^256 mod q + // f.Mul(out, arg, &[native.FieldLimbs]uint64{1, 0, 0, 0}) + f.montReduce(out, &[native.FieldLimbs * 2]uint64{arg[0], arg[1], arg[2], arg[3], 0, 0, 0, 0}) +} + +// Neg performs modular negation +func (f bls12381FqArithmetic) Neg(out, arg *[native.FieldLimbs]uint64) { + // Subtract `arg` from `fqModulus`. Ignore final borrow + // since it can't underflow. + var t [native.FieldLimbs]uint64 + var borrow uint64 + t[0], borrow = sbb(fqModulus[0], arg[0], 0) + t[1], borrow = sbb(fqModulus[1], arg[1], borrow) + t[2], borrow = sbb(fqModulus[2], arg[2], borrow) + t[3], _ = sbb(fqModulus[3], arg[3], borrow) + + // t could be `fqModulus` if `arg`=0. Set mask=0 if self=0 + // and 0xff..ff if `arg`!=0 + mask := t[0] | t[1] | t[2] | t[3] + mask = -((mask | -mask) >> 63) + out[0] = t[0] & mask + out[1] = t[1] & mask + out[2] = t[2] & mask + out[3] = t[3] & mask +} + +// Square performs modular square +func (f bls12381FqArithmetic) Square(out, arg *[native.FieldLimbs]uint64) { + var r [2 * native.FieldLimbs]uint64 + var carry uint64 + + r[1], carry = mac(0, arg[0], arg[1], 0) + r[2], carry = mac(0, arg[0], arg[2], carry) + r[3], r[4] = mac(0, arg[0], arg[3], carry) + + r[3], carry = mac(r[3], arg[1], arg[2], 0) + r[4], r[5] = mac(r[4], arg[1], arg[3], carry) + + r[5], r[6] = mac(r[5], arg[2], arg[3], 0) + + r[7] = r[6] >> 63 + r[6] = (r[6] << 1) | r[5]>>63 + r[5] = (r[5] << 1) | r[4]>>63 + r[4] = (r[4] << 1) | r[3]>>63 + r[3] = (r[3] << 1) | r[2]>>63 + r[2] = (r[2] << 1) | r[1]>>63 + r[1] = r[1] << 1 + + r[0], carry = mac(0, arg[0], arg[0], 0) + r[1], carry = adc(0, r[1], carry) + r[2], carry = mac(r[2], arg[1], arg[1], carry) + r[3], carry = adc(0, r[3], carry) + r[4], carry = mac(r[4], arg[2], arg[2], carry) + r[5], carry = adc(0, r[5], carry) + r[6], carry = mac(r[6], arg[3], arg[3], carry) + r[7], _ = adc(0, r[7], carry) + + f.montReduce(out, &r) +} + +// Mul performs modular multiplication +func (f bls12381FqArithmetic) Mul(out, arg1, arg2 *[native.FieldLimbs]uint64) { + // Schoolbook multiplication + var r [2 * native.FieldLimbs]uint64 + var carry uint64 + + r[0], carry = mac(0, arg1[0], arg2[0], 0) + r[1], carry = mac(0, arg1[0], arg2[1], carry) + r[2], carry = mac(0, arg1[0], arg2[2], carry) + r[3], r[4] = mac(0, arg1[0], arg2[3], carry) + + r[1], carry = mac(r[1], arg1[1], arg2[0], 0) + r[2], carry = mac(r[2], arg1[1], arg2[1], carry) + r[3], carry = mac(r[3], arg1[1], arg2[2], carry) + r[4], r[5] = mac(r[4], arg1[1], arg2[3], carry) + + r[2], carry = mac(r[2], arg1[2], arg2[0], 0) + r[3], carry = mac(r[3], arg1[2], arg2[1], carry) + r[4], carry = mac(r[4], arg1[2], arg2[2], carry) + r[5], r[6] = mac(r[5], arg1[2], arg2[3], carry) + + r[3], carry = mac(r[3], arg1[3], arg2[0], 0) + r[4], carry = mac(r[4], arg1[3], arg2[1], carry) + r[5], carry = mac(r[5], arg1[3], arg2[2], carry) + r[6], r[7] = mac(r[6], arg1[3], arg2[3], carry) + + f.montReduce(out, &r) +} + +// Add performs modular addition +func (f bls12381FqArithmetic) Add(out, arg1, arg2 *[native.FieldLimbs]uint64) { + var t [native.FieldLimbs]uint64 + var carry uint64 + + t[0], carry = adc(arg1[0], arg2[0], 0) + t[1], carry = adc(arg1[1], arg2[1], carry) + t[2], carry = adc(arg1[2], arg2[2], carry) + t[3], _ = adc(arg1[3], arg2[3], carry) + + // Subtract the fqModulus to ensure the value + // is smaller. + f.Sub(out, &t, &fqModulus) +} + +// Sub performs modular subtraction +func (f bls12381FqArithmetic) Sub(out, arg1, arg2 *[native.FieldLimbs]uint64) { + d0, borrow := sbb(arg1[0], arg2[0], 0) + d1, borrow := sbb(arg1[1], arg2[1], borrow) + d2, borrow := sbb(arg1[2], arg2[2], borrow) + d3, borrow := sbb(arg1[3], arg2[3], borrow) + + // If underflow occurred on the final limb, borrow 0xff...ff, otherwise + // borrow = 0x00...00. Conditionally mask to add the fqModulus + borrow = -borrow + d0, carry := adc(d0, fqModulus[0]&borrow, 0) + d1, carry = adc(d1, fqModulus[1]&borrow, carry) + d2, carry = adc(d2, fqModulus[2]&borrow, carry) + d3, _ = adc(d3, fqModulus[3]&borrow, carry) + + out[0] = d0 + out[1] = d1 + out[2] = d2 + out[3] = d3 +} + +// Sqrt performs modular square root +func (f bls12381FqArithmetic) Sqrt(wasSquare *int, out, arg *[native.FieldLimbs]uint64) { + // See sqrt_ts_ct at + // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-I.4 + // c1 := fqS + // c2 := (q - 1) / (2^c1) + c2 := [4]uint64{ + 0xfffe5bfeffffffff, + 0x09a1d80553bda402, + 0x299d7d483339d808, + 0x0000000073eda753, + } + // c3 := (c2 - 1) / 2 + c3 := [native.FieldLimbs]uint64{ + 0x7fff2dff7fffffff, + 0x04d0ec02a9ded201, + 0x94cebea4199cec04, + 0x0000000039f6d3a9, + } + // c4 := fqGenerator + var c5 [native.FieldLimbs]uint64 + native.Pow(&c5, &fqGenerator, &c2, getBls12381FqParams(), f) + // c5 := [native.FieldLimbs]uint64{0x1015708f7e368fe1, 0x31c6c5456ecc4511, 0x5281fe8998a19ea1, 0x0279089e10c63fe8} + var z, t, b, c, tv [native.FieldLimbs]uint64 + + native.Pow(&z, arg, &c3, getBls12381FqParams(), f) + f.Square(&t, &z) + f.Mul(&t, &t, arg) + f.Mul(&z, &z, arg) + + copy(b[:], t[:]) + copy(c[:], c5[:]) + + for i := fqS; i >= 2; i-- { + for j := 1; j <= i-2; j++ { + f.Square(&b, &b) + } + // if b == 1 flag = 0 else flag = 1 + flag := -(&native.Field{ + Value: b, + Params: getBls12381FqParams(), + Arithmetic: f, + }).IsOne() + 1 + f.Mul(&tv, &z, &c) + f.Selectznz(&z, &z, &tv, flag) + f.Square(&c, &c) + f.Mul(&tv, &t, &c) + f.Selectznz(&t, &t, &tv, flag) + copy(b[:], t[:]) + } + f.Square(&c, &z) + *wasSquare = (&native.Field{ + Value: c, + Params: getBls12381FqParams(), + Arithmetic: f, + }).Equal(&native.Field{ + Value: *arg, + Params: getBls12381FqParams(), + Arithmetic: f, + }) + f.Selectznz(out, out, &z, *wasSquare) +} + +// Invert performs modular inverse +func (f bls12381FqArithmetic) Invert(wasInverted *int, out, arg *[native.FieldLimbs]uint64) { + // Using an addition chain from + // https://github.com/kwantam/addchain + var t0, t1, t2, t3, t4, t5, t6, t7, t8 [native.FieldLimbs]uint64 + var t9, t11, t12, t13, t14, t15, t16, t17 [native.FieldLimbs]uint64 + + f.Square(&t0, arg) + f.Mul(&t1, &t0, arg) + f.Square(&t16, &t0) + f.Square(&t6, &t16) + f.Mul(&t5, &t6, &t0) + f.Mul(&t0, &t6, &t16) + f.Mul(&t12, &t5, &t16) + f.Square(&t2, &t6) + f.Mul(&t7, &t5, &t6) + f.Mul(&t15, &t0, &t5) + f.Square(&t17, &t12) + f.Mul(&t1, &t1, &t17) + f.Mul(&t3, &t7, &t2) + f.Mul(&t8, &t1, &t17) + f.Mul(&t4, &t8, &t2) + f.Mul(&t9, &t8, &t7) + f.Mul(&t7, &t4, &t5) + f.Mul(&t11, &t4, &t17) + f.Mul(&t5, &t9, &t17) + f.Mul(&t14, &t7, &t15) + f.Mul(&t13, &t11, &t12) + f.Mul(&t12, &t11, &t17) + f.Mul(&t15, &t15, &t12) + f.Mul(&t16, &t16, &t15) + f.Mul(&t3, &t3, &t16) + f.Mul(&t17, &t17, &t3) + f.Mul(&t0, &t0, &t17) + f.Mul(&t6, &t6, &t0) + f.Mul(&t2, &t2, &t6) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t17) + native.Pow2k(&t0, &t0, 9, f) + f.Mul(&t0, &t0, &t16) + native.Pow2k(&t0, &t0, 9, f) + f.Mul(&t0, &t0, &t15) + native.Pow2k(&t0, &t0, 9, f) + f.Mul(&t0, &t0, &t15) + native.Pow2k(&t0, &t0, 7, f) + f.Mul(&t0, &t0, &t14) + native.Pow2k(&t0, &t0, 7, f) + f.Mul(&t0, &t0, &t13) + native.Pow2k(&t0, &t0, 10, f) + f.Mul(&t0, &t0, &t12) + native.Pow2k(&t0, &t0, 9, f) + f.Mul(&t0, &t0, &t11) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t8) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, arg) + native.Pow2k(&t0, &t0, 14, f) + f.Mul(&t0, &t0, &t9) + native.Pow2k(&t0, &t0, 10, f) + f.Mul(&t0, &t0, &t8) + native.Pow2k(&t0, &t0, 15, f) + f.Mul(&t0, &t0, &t7) + native.Pow2k(&t0, &t0, 10, f) + f.Mul(&t0, &t0, &t6) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t5) + native.Pow2k(&t0, &t0, 16, f) + f.Mul(&t0, &t0, &t3) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t2) + native.Pow2k(&t0, &t0, 7, f) + f.Mul(&t0, &t0, &t4) + native.Pow2k(&t0, &t0, 9, f) + f.Mul(&t0, &t0, &t2) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t3) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t2) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t2) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t2) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t3) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t2) + native.Pow2k(&t0, &t0, 8, f) + f.Mul(&t0, &t0, &t2) + native.Pow2k(&t0, &t0, 5, f) + f.Mul(&t0, &t0, &t1) + native.Pow2k(&t0, &t0, 5, f) + f.Mul(&t0, &t0, &t1) + + *wasInverted = (&native.Field{ + Value: *arg, + Params: getBls12381FqParams(), + Arithmetic: f, + }).IsNonZero() + f.Selectznz(out, out, &t0, *wasInverted) +} + +// FromBytes converts a little endian byte array into a field element +func (f bls12381FqArithmetic) FromBytes(out *[native.FieldLimbs]uint64, arg *[native.FieldBytes]byte) { + out[0] = binary.LittleEndian.Uint64(arg[:8]) + out[1] = binary.LittleEndian.Uint64(arg[8:16]) + out[2] = binary.LittleEndian.Uint64(arg[16:24]) + out[3] = binary.LittleEndian.Uint64(arg[24:]) +} + +// ToBytes converts a field element to a little endian byte array +func (f bls12381FqArithmetic) ToBytes(out *[native.FieldBytes]byte, arg *[native.FieldLimbs]uint64) { + binary.LittleEndian.PutUint64(out[:8], arg[0]) + binary.LittleEndian.PutUint64(out[8:16], arg[1]) + binary.LittleEndian.PutUint64(out[16:24], arg[2]) + binary.LittleEndian.PutUint64(out[24:], arg[3]) +} + +// Selectznz performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f bls12381FqArithmetic) Selectznz(out, arg1, arg2 *[native.FieldLimbs]uint64, choice int) { + b := uint64(-choice) + out[0] = arg1[0] ^ ((arg1[0] ^ arg2[0]) & b) + out[1] = arg1[1] ^ ((arg1[1] ^ arg2[1]) & b) + out[2] = arg1[2] ^ ((arg1[2] ^ arg2[2]) & b) + out[3] = arg1[3] ^ ((arg1[3] ^ arg2[3]) & b) +} + +func (f bls12381FqArithmetic) montReduce(out *[native.FieldLimbs]uint64, r *[2 * native.FieldLimbs]uint64) { + // Taken from Algorithm 14.32 in Handbook of Applied Cryptography + var r1, r2, r3, r4, r5, r6, carry, carry2, k uint64 + var rr [native.FieldLimbs]uint64 + + k = r[0] * qInv + _, carry = mac(r[0], k, fqModulus[0], 0) + r1, carry = mac(r[1], k, fqModulus[1], carry) + r2, carry = mac(r[2], k, fqModulus[2], carry) + r3, carry = mac(r[3], k, fqModulus[3], carry) + r4, carry2 = adc(r[4], 0, carry) + + k = r1 * qInv + _, carry = mac(r1, k, fqModulus[0], 0) + r2, carry = mac(r2, k, fqModulus[1], carry) + r3, carry = mac(r3, k, fqModulus[2], carry) + r4, carry = mac(r4, k, fqModulus[3], carry) + r5, carry2 = adc(r[5], carry2, carry) + + k = r2 * qInv + _, carry = mac(r2, k, fqModulus[0], 0) + r3, carry = mac(r3, k, fqModulus[1], carry) + r4, carry = mac(r4, k, fqModulus[2], carry) + r5, carry = mac(r5, k, fqModulus[3], carry) + r6, carry2 = adc(r[6], carry2, carry) + + k = r3 * qInv + _, carry = mac(r3, k, fqModulus[0], 0) + rr[0], carry = mac(r4, k, fqModulus[1], carry) + rr[1], carry = mac(r5, k, fqModulus[2], carry) + rr[2], carry = mac(r6, k, fqModulus[3], carry) + rr[3], _ = adc(r[7], carry2, carry) + + f.Sub(out, &rr, &fqModulus) +} diff --git a/pkg/crypto/core/curves/native/bls12381/fq_test.go b/pkg/crypto/core/curves/native/bls12381/fq_test.go new file mode 100755 index 000000000..0ff2e322c --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/fq_test.go @@ -0,0 +1,342 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls12381 + +import ( + crand "crypto/rand" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func TestFqSetOne(t *testing.T) { + fq := Bls12381FqNew().SetOne() + require.NotNil(t, fq) + require.Equal(t, fq.Value, getBls12381FqParams().R) +} + +func TestFqSetUint64(t *testing.T) { + act := Bls12381FqNew().SetUint64(1 << 60) + require.NotNil(t, act) + // Remember it will be in montgomery form + require.Equal(t, act.Value[0], uint64(0xbc98da2820121c89)) +} + +func TestFqAdd(t *testing.T) { + lhs := Bls12381FqNew().SetOne() + rhs := Bls12381FqNew().SetOne() + exp := Bls12381FqNew().SetUint64(2) + res := Bls12381FqNew().Add(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + e := l + r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := Bls12381FqNew().Add(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqSub(t *testing.T) { + lhs := Bls12381FqNew().SetOne() + rhs := Bls12381FqNew().SetOne() + exp := Bls12381FqNew().SetZero() + res := Bls12381FqNew().Sub(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + if l < r { + l, r = r, l + } + e := l - r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := Bls12381FqNew().Sub(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqMul(t *testing.T) { + lhs := Bls12381FqNew().SetOne() + rhs := Bls12381FqNew().SetOne() + exp := Bls12381FqNew().SetOne() + res := Bls12381FqNew().Mul(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint32() + r := rand.Uint32() + e := uint64(l) * uint64(r) + lhs.SetUint64(uint64(l)) + rhs.SetUint64(uint64(r)) + exp.SetUint64(e) + + a := Bls12381FqNew().Mul(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqDouble(t *testing.T) { + a := Bls12381FqNew().SetUint64(2) + e := Bls12381FqNew().SetUint64(4) + require.Equal(t, e, Bls12381FqNew().Double(a)) + + for i := 0; i < 25; i++ { + tv := rand.Uint32() + ttv := uint64(tv) * 2 + a = Bls12381FqNew().SetUint64(uint64(tv)) + e = Bls12381FqNew().SetUint64(ttv) + require.Equal(t, e, Bls12381FqNew().Double(a)) + } +} + +func TestFqSquare(t *testing.T) { + a := Bls12381FqNew().SetUint64(4) + e := Bls12381FqNew().SetUint64(16) + require.Equal(t, 1, e.Equal(a.Square(a))) + + a.SetUint64(2854263694) + e.SetUint64(8146821234886525636) + require.Equal(t, 1, e.Equal(a.Square(a))) + + for i := 0; i < 25; i++ { + j := rand.Uint32() + exp := uint64(j) * uint64(j) + e.SetUint64(exp) + a.SetUint64(uint64(j)) + require.Equal(t, 1, e.Equal(a.Square(a)), "exp = %d, j = %d", exp, j) + } +} + +func TestFqNeg(t *testing.T) { + g := Bls12381FqNew().SetRaw(&fqGenerator) + a := Bls12381FqNew().SetOne() + a.Neg(a) + e := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{0xfffffffd00000003, 0xfb38ec08fffb13fc, 0x99ad88181ce5880f, 0x5bc8f5f97cd877d8}) + require.Equal(t, 1, e.Equal(a)) + a.Neg(g) + e = Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{0xfffffff000000010, 0x3bda402fffe5bfef, 0x339d80809a1d8055, 0x3eda753299d7d483}) + require.Equal(t, e, a) +} + +func TestFqExp(t *testing.T) { + e := Bls12381FqNew().SetUint64(8) + a := Bls12381FqNew().SetUint64(2) + by := Bls12381FqNew().SetUint64(3) + require.Equal(t, e, a.Exp(a, by)) +} + +func TestFqSqrt(t *testing.T) { + t1 := Bls12381FqNew().SetUint64(2) + t2 := Bls12381FqNew().Neg(t1) + t3 := Bls12381FqNew().Square(t1) + _, wasSquare := t3.Sqrt(t3) + + require.True(t, wasSquare) + require.Equal(t, 1, t1.Equal(t3)|t2.Equal(t3)) + t1.SetUint64(5) + _, wasSquare = Bls12381FqNew().Sqrt(t1) + require.False(t, wasSquare) +} + +func TestFqInvert(t *testing.T) { + twoInv := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{0xffffffff, 0xac425bfd0001a401, 0xccc627f7f65e27fa, 0xc1258acd66282b7}) + two := Bls12381FqNew().SetUint64(2) + a, inverted := Bls12381FqNew().Invert(two) + require.True(t, inverted) + require.Equal(t, a, twoInv) + + rootOfUnity := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{0xb9b58d8c5f0e466a, 0x5b1b4c801819d7ec, 0x0af53ae352a31e64, 0x5bf3adda19e9b27b}) + rootOfUnityInv := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{0x4256481adcf3219a, 0x45f37b7f96b6cad3, 0xf9c3f1d75f7a3b27, 0x2d2fc049658afd43}) + a, inverted = Bls12381FqNew().Invert(rootOfUnity) + require.True(t, inverted) + require.Equal(t, a, rootOfUnityInv) + + lhs := Bls12381FqNew().SetUint64(9) + rhs := Bls12381FqNew().SetUint64(3) + rhsInv, inverted := Bls12381FqNew().Invert(rhs) + require.True(t, inverted) + require.Equal(t, rhs, Bls12381FqNew().Mul(lhs, rhsInv)) + + rhs.SetZero() + _, inverted = Bls12381FqNew().Invert(rhs) + require.False(t, inverted) +} + +func TestFqCMove(t *testing.T) { + t1 := Bls12381FqNew().SetUint64(5) + t2 := Bls12381FqNew().SetUint64(10) + require.Equal(t, t1, Bls12381FqNew().CMove(t1, t2, 0)) + require.Equal(t, t2, Bls12381FqNew().CMove(t1, t2, 1)) +} + +func TestFqBytes(t *testing.T) { + t1 := Bls12381FqNew().SetUint64(99) + seq := t1.Bytes() + t2, err := Bls12381FqNew().SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + + for i := 0; i < 25; i++ { + t1.SetUint64(rand.Uint64()) + seq = t1.Bytes() + _, err = t2.SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + } +} + +func TestFqCmp(t *testing.T) { + tests := []struct { + a *native.Field + b *native.Field + e int + }{ + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{2731658267414164836, 14655288906067898431, 6537465423330262322, 8306191141697566219}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{6472764012681988529, 10848812988401906064, 2961825807536828898, 4282183981941645679}), + e: 1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{8023004109510539223, 4652004072850285717, 1877219145646046927, 383214385093921911}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{10099384440823804262, 16139476942229308465, 8636966320777393798, 5435928725024696785}), + e: -1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{3741840066202388211, 12165774400417314871, 16619312580230515379, 16195032234110087705}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{3905865991286066744, 543690822309071825, 17963103015950210055, 3745476720756119742}), + e: 1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{16660853697936147788, 7799793619412111108, 13515141085171033220, 2641079731236069032}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{17790588295388238399, 571847801379669440, 14537208974498222469, 12792570372087452754}), + e: -1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{3912839285384959186, 2701177075110484070, 6453856448115499033, 6475797457962597458}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{1282566391665688512, 13503640416992806563, 2962240104675990153, 3374904770947067689}), + e: 1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{5716631803409360103, 7859567470082614154, 12747956220853330146, 18434584096087315020}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{16317076441459028418, 12854146980376319601, 2258436689269031143, 9531877130792223752}), + e: 1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{17955191469941083403, 10350326247207200880, 17263512235150705075, 12700328451238078022}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{6767595547459644695, 7146403825494928147, 12269344038346710612, 9122477829383225603}), + e: 1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{17099388671847024438, 6426264987820696548, 10641143464957227405, 7709745403700754098}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{10799154372990268556, 17178492485719929374, 5705777922258988797, 8051037767683567782}), + e: -1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{4567139260680454325, 1629385880182139061, 16607020832317899145, 1261011562621553200}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{13487234491304534488, 17872642955936089265, 17651026784972590233, 9468934643333871559}), + e: -1, + }, + { + a: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{18071070103467571798, 11787850505799426140, 10631355976141928593, 4867785203635092610}), + b: Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{12596443599426461624, 10176122686151524591, 17075755296887483439, 6726169532695070719}), + e: -1, + }, + } + + for _, test := range tests { + require.Equal(t, test.e, test.a.Cmp(test.b)) + require.Equal(t, -test.e, test.b.Cmp(test.a)) + require.Equal(t, 0, test.a.Cmp(test.a)) + require.Equal(t, 0, test.b.Cmp(test.b)) + } +} + +func TestFqBigInt(t *testing.T) { + t1 := Bls12381FqNew().SetBigInt(big.NewInt(9999)) + t2 := Bls12381FqNew().SetBigInt(t1.BigInt()) + require.Equal(t, t1, t2) + + e := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{0x673053fc60e06500, 0x86e6d480b4f76ada, 0x7fc68f9fefa23291, 0x3fb17f49bdda126d}) + b := new(big.Int).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}) + t1.SetBigInt(b) + require.Equal(t, e, t1) + e.Neg(e) + b.Neg(b) + t1.SetBigInt(b) + require.Equal(t, e, t1) +} + +func TestFqSetBytesWide(t *testing.T) { + e := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{0xc759fba87ff8c5a6, 0x9ef5194839e7df44, 0x21375d22b678bf0e, 0x38b105387033fd57}) + + a := Bls12381FqNew().SetBytesWide(&[64]byte{ + 0x69, 0x23, 0x5a, 0x0b, 0xce, 0x0c, 0xa8, 0x64, + 0x3c, 0x78, 0xbc, 0x01, 0x05, 0xef, 0xf2, 0x84, + 0xde, 0xbb, 0x6b, 0xc8, 0x63, 0x5e, 0x6e, 0x69, + 0x62, 0xcc, 0xc6, 0x2d, 0xf5, 0x72, 0x40, 0x92, + 0x28, 0x11, 0xd6, 0xc8, 0x07, 0xa5, 0x88, 0x82, + 0xfe, 0xe3, 0x97, 0xf6, 0x1e, 0xfb, 0x2e, 0x3b, + 0x27, 0x5f, 0x85, 0x06, 0x8d, 0x99, 0xa4, 0x75, + 0xc0, 0x2c, 0x71, 0x69, 0x9e, 0x58, 0xea, 0x52, + }) + require.Equal(t, e, a) +} + +func TestFqSetBytesWideBigInt(t *testing.T) { + params := getBls12381FqParams() + var tv2 [64]byte + for i := 0; i < 25; i++ { + _, _ = crand.Read(tv2[:]) + e := new(big.Int).SetBytes(tv2[:]) + e.Mod(e, params.BiModulus) + + tv := internal.ReverseScalarBytes(tv2[:]) + copy(tv2[:], tv) + a := Bls12381FqNew().SetBytesWide(&tv2) + require.Equal(t, 0, e.Cmp(a.BigInt())) + } +} + +func TestFqToMontgomery(t *testing.T) { + v := Bls12381FqNew().SetUint64(2) + require.Equal(t, [native.FieldLimbs]uint64{0x3fffffffc, 0xb1096ff400069004, 0x33189fdfd9789fea, 0x304962b3598a0adf}, v.Value) +} + +func TestFqFromMontgomery(t *testing.T) { + e := [native.FieldLimbs]uint64{2, 0, 0, 0} + a := [native.FieldLimbs]uint64{0, 0, 0, 0} + v := Bls12381FqNew().SetUint64(2) + v.Arithmetic.FromMontgomery(&a, &v.Value) + require.Equal(t, e, a) +} diff --git a/pkg/crypto/core/curves/native/bls12381/g1.go b/pkg/crypto/core/curves/native/bls12381/g1.go new file mode 100755 index 000000000..96180077f --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/g1.go @@ -0,0 +1,1123 @@ +package bls12381 + +import ( + "fmt" + "io" + "math/big" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + g1x = fp{ + 0x5cb38790fd530c16, + 0x7817fc679976fff5, + 0x154f95c7143ba1c1, + 0xf0ae6acdf3d0e747, + 0xedce6ecc21dbf440, + 0x120177419e0bfb75, + } + g1y = fp{ + 0xbaac93d50ce72271, + 0x8c22631a7918fd8e, + 0xdd595f13570725ce, + 0x51ac582950405194, + 0x0e1c8c3fad0059c0, + 0x0bbc3efc5008a26a, + } + curveG1B = fp{ + 0xaa270000000cfff3, + 0x53cc0032fc34000a, + 0x478fe97a6b0a807f, + 0xb1d37ebee6ba24d7, + 0x8ec9733bbf78ab2f, + 0x09d645513d83de7e, + } + osswuMapA = fp{ + 0x2f65aa0e9af5aa51, + 0x86464c2d1e8416c3, + 0xb85ce591b7bd31e2, + 0x27e11c91b5f24e7c, + 0x28376eda6bfc1835, + 0x155455c3e5071d85, + } + osswuMapB = fp{ + 0xfb996971fe22a1e0, + 0x9aa93eb35b742d6f, + 0x8c476013de99c5c4, + 0x873e27c3a221e571, + 0xca72b5e45a52d888, + 0x06824061418a386b, + } + osswuMapC1 = fp{ + 0xee7fbfffffffeaaa, + 0x07aaffffac54ffff, + 0xd9cc34a83dac3d89, + 0xd91dd2e13ce144af, + 0x92c6e9ed90d2eb35, + 0x0680447a8e5ff9a6, + } + osswuMapC2 = fp{ + 0x43b571cad3215f1f, + 0xccb460ef1c702dc2, + 0x742d884f4f97100b, + 0xdb2c3e3238a3382b, + 0xe40f3fa13fce8f88, + 0x0073a2af9892a2ff, + } + oswwuMapZ = fp{ + 0x886c00000023ffdc, + 0x0f70008d3090001d, + 0x77672417ed5828c3, + 0x9dac23e943dc1740, + 0x50553f1b9c131521, + 0x078c712fbe0ab6e8, + } + oswwuMapXd1 = *((&fp{}).Mul(&oswwuMapZ, &osswuMapA)) + negOsswuMapA = *(&fp{}).Neg(&osswuMapA) + + g1IsoXNum = []fp{ + { + 0x4d18b6f3af00131c, + 0x19fa219793fee28c, + 0x3f2885f1467f19ae, + 0x23dcea34f2ffb304, + 0xd15b58d2ffc00054, + 0x0913be200a20bef4, + }, + { + 0x898985385cdbbd8b, + 0x3c79e43cc7d966aa, + 0x1597e193f4cd233a, + 0x8637ef1e4d6623ad, + 0x11b22deed20d827b, + 0x07097bc5998784ad, + }, + { + 0xa542583a480b664b, + 0xfc7169c026e568c6, + 0x5ba2ef314ed8b5a6, + 0x5b5491c05102f0e7, + 0xdf6e99707d2a0079, + 0x0784151ed7605524, + }, + { + 0x494e212870f72741, + 0xab9be52fbda43021, + 0x26f5577994e34c3d, + 0x049dfee82aefbd60, + 0x65dadd7828505289, + 0x0e93d431ea011aeb, + }, + { + 0x90ee774bd6a74d45, + 0x7ada1c8a41bfb185, + 0x0f1a8953b325f464, + 0x104c24211be4805c, + 0x169139d319ea7a8f, + 0x09f20ead8e532bf6, + }, + { + 0x6ddd93e2f43626b7, + 0xa5482c9aa1ccd7bd, + 0x143245631883f4bd, + 0x2e0a94ccf77ec0db, + 0xb0282d480e56489f, + 0x18f4bfcbb4368929, + }, + { + 0x23c5f0c953402dfd, + 0x7a43ff6958ce4fe9, + 0x2c390d3d2da5df63, + 0xd0df5c98e1f9d70f, + 0xffd89869a572b297, + 0x1277ffc72f25e8fe, + }, + { + 0x79f4f0490f06a8a6, + 0x85f894a88030fd81, + 0x12da3054b18b6410, + 0xe2a57f6505880d65, + 0xbba074f260e400f1, + 0x08b76279f621d028, + }, + { + 0xe67245ba78d5b00b, + 0x8456ba9a1f186475, + 0x7888bff6e6b33bb4, + 0xe21585b9a30f86cb, + 0x05a69cdcef55feee, + 0x09e699dd9adfa5ac, + }, + { + 0x0de5c357bff57107, + 0x0a0db4ae6b1a10b2, + 0xe256bb67b3b3cd8d, + 0x8ad456574e9db24f, + 0x0443915f50fd4179, + 0x098c4bf7de8b6375, + }, + { + 0xe6b0617e7dd929c7, + 0xfe6e37d442537375, + 0x1dafdeda137a489e, + 0xe4efd1ad3f767ceb, + 0x4a51d8667f0fe1cf, + 0x054fdf4bbf1d821c, + }, + { + 0x72db2a50658d767b, + 0x8abf91faa257b3d5, + 0xe969d6833764ab47, + 0x464170142a1009eb, + 0xb14f01aadb30be2f, + 0x18ae6a856f40715d, + }, + } + g1IsoXDen = []fp{ + { + 0xb962a077fdb0f945, + 0xa6a9740fefda13a0, + 0xc14d568c3ed6c544, + 0xb43fc37b908b133e, + 0x9c0b3ac929599016, + 0x0165aa6c93ad115f, + }, + { + 0x23279a3ba506c1d9, + 0x92cfca0a9465176a, + 0x3b294ab13755f0ff, + 0x116dda1c5070ae93, + 0xed4530924cec2045, + 0x083383d6ed81f1ce, + }, + { + 0x9885c2a6449fecfc, + 0x4a2b54ccd37733f0, + 0x17da9ffd8738c142, + 0xa0fba72732b3fafd, + 0xff364f36e54b6812, + 0x0f29c13c660523e2, + }, + { + 0xe349cc118278f041, + 0xd487228f2f3204fb, + 0xc9d325849ade5150, + 0x43a92bd69c15c2df, + 0x1c2c7844bc417be4, + 0x12025184f407440c, + }, + { + 0x587f65ae6acb057b, + 0x1444ef325140201f, + 0xfbf995e71270da49, + 0xccda066072436a42, + 0x7408904f0f186bb2, + 0x13b93c63edf6c015, + }, + { + 0xfb918622cd141920, + 0x4a4c64423ecaddb4, + 0x0beb232927f7fb26, + 0x30f94df6f83a3dc2, + 0xaeedd424d780f388, + 0x06cc402dd594bbeb, + }, + { + 0xd41f761151b23f8f, + 0x32a92465435719b3, + 0x64f436e888c62cb9, + 0xdf70a9a1f757c6e4, + 0x6933a38d5b594c81, + 0x0c6f7f7237b46606, + }, + { + 0x693c08747876c8f7, + 0x22c9850bf9cf80f0, + 0x8e9071dab950c124, + 0x89bc62d61c7baf23, + 0xbc6be2d8dad57c23, + 0x17916987aa14a122, + }, + { + 0x1be3ff439c1316fd, + 0x9965243a7571dfa7, + 0xc7f7f62962f5cd81, + 0x32c6aa9af394361c, + 0xbbc2ee18e1c227f4, + 0x0c102cbac531bb34, + }, + { + 0x997614c97bacbf07, + 0x61f86372b99192c0, + 0x5b8c95fc14353fc3, + 0xca2b066c2a87492f, + 0x16178f5bbf698711, + 0x12a6dcd7f0f4e0e8, + }, + { + 0x760900000002fffd, + 0xebf4000bc40c0002, + 0x5f48985753c758ba, + 0x77ce585370525745, + 0x5c071a97a256ec6d, + 0x15f65ec3fa80e493, + }, + } + g1IsoYNum = []fp{ + { + 0x2b567ff3e2837267, + 0x1d4d9e57b958a767, + 0xce028fea04bd7373, + 0xcc31a30a0b6cd3df, + 0x7d7b18a682692693, + 0x0d300744d42a0310, + }, + { + 0x99c2555fa542493f, + 0xfe7f53cc4874f878, + 0x5df0608b8f97608a, + 0x14e03832052b49c8, + 0x706326a6957dd5a4, + 0x0a8dadd9c2414555, + }, + { + 0x13d942922a5cf63a, + 0x357e33e36e261e7d, + 0xcf05a27c8456088d, + 0x0000bd1de7ba50f0, + 0x83d0c7532f8c1fde, + 0x13f70bf38bbf2905, + }, + { + 0x5c57fd95bfafbdbb, + 0x28a359a65e541707, + 0x3983ceb4f6360b6d, + 0xafe19ff6f97e6d53, + 0xb3468f4550192bf7, + 0x0bb6cde49d8ba257, + }, + { + 0x590b62c7ff8a513f, + 0x314b4ce372cacefd, + 0x6bef32ce94b8a800, + 0x6ddf84a095713d5f, + 0x64eace4cb0982191, + 0x0386213c651b888d, + }, + { + 0xa5310a31111bbcdd, + 0xa14ac0f5da148982, + 0xf9ad9cc95423d2e9, + 0xaa6ec095283ee4a7, + 0xcf5b1f022e1c9107, + 0x01fddf5aed881793, + }, + { + 0x65a572b0d7a7d950, + 0xe25c2d8183473a19, + 0xc2fcebe7cb877dbd, + 0x05b2d36c769a89b0, + 0xba12961be86e9efb, + 0x07eb1b29c1dfde1f, + }, + { + 0x93e09572f7c4cd24, + 0x364e929076795091, + 0x8569467e68af51b5, + 0xa47da89439f5340f, + 0xf4fa918082e44d64, + 0x0ad52ba3e6695a79, + }, + { + 0x911429844e0d5f54, + 0xd03f51a3516bb233, + 0x3d587e5640536e66, + 0xfa86d2a3a9a73482, + 0xa90ed5adf1ed5537, + 0x149c9c326a5e7393, + }, + { + 0x462bbeb03c12921a, + 0xdc9af5fa0a274a17, + 0x9a558ebde836ebed, + 0x649ef8f11a4fae46, + 0x8100e1652b3cdc62, + 0x1862bd62c291dacb, + }, + { + 0x05c9b8ca89f12c26, + 0x0194160fa9b9ac4f, + 0x6a643d5a6879fa2c, + 0x14665bdd8846e19d, + 0xbb1d0d53af3ff6bf, + 0x12c7e1c3b28962e5, + }, + { + 0xb55ebf900b8a3e17, + 0xfedc77ec1a9201c4, + 0x1f07db10ea1a4df4, + 0x0dfbd15dc41a594d, + 0x389547f2334a5391, + 0x02419f98165871a4, + }, + { + 0xb416af000745fc20, + 0x8e563e9d1ea6d0f5, + 0x7c763e17763a0652, + 0x01458ef0159ebbef, + 0x8346fe421f96bb13, + 0x0d2d7b829ce324d2, + }, + { + 0x93096bb538d64615, + 0x6f2a2619951d823a, + 0x8f66b3ea59514fa4, + 0xf563e63704f7092f, + 0x724b136c4cf2d9fa, + 0x046959cfcfd0bf49, + }, + { + 0xea748d4b6e405346, + 0x91e9079c2c02d58f, + 0x41064965946d9b59, + 0xa06731f1d2bbe1ee, + 0x07f897e267a33f1b, + 0x1017290919210e5f, + }, + { + 0x872aa6c17d985097, + 0xeecc53161264562a, + 0x07afe37afff55002, + 0x54759078e5be6838, + 0xc4b92d15db8acca8, + 0x106d87d1b51d13b9, + }, + } + g1IsoYDen = []fp{ + { + 0xeb6c359d47e52b1c, + 0x18ef5f8a10634d60, + 0xddfa71a0889d5b7e, + 0x723e71dcc5fc1323, + 0x52f45700b70d5c69, + 0x0a8b981ee47691f1, + }, + { + 0x616a3c4f5535b9fb, + 0x6f5f037395dbd911, + 0xf25f4cc5e35c65da, + 0x3e50dffea3c62658, + 0x6a33dca523560776, + 0x0fadeff77b6bfe3e, + }, + { + 0x2be9b66df470059c, + 0x24a2c159a3d36742, + 0x115dbe7ad10c2a37, + 0xb6634a652ee5884d, + 0x04fe8bb2b8d81af4, + 0x01c2a7a256fe9c41, + }, + { + 0xf27bf8ef3b75a386, + 0x898b367476c9073f, + 0x24482e6b8c2f4e5f, + 0xc8e0bbd6fe110806, + 0x59b0c17f7631448a, + 0x11037cd58b3dbfbd, + }, + { + 0x31c7912ea267eec6, + 0x1dbf6f1c5fcdb700, + 0xd30d4fe3ba86fdb1, + 0x3cae528fbee9a2a4, + 0xb1cce69b6aa9ad9a, + 0x044393bb632d94fb, + }, + { + 0xc66ef6efeeb5c7e8, + 0x9824c289dd72bb55, + 0x71b1a4d2f119981d, + 0x104fc1aafb0919cc, + 0x0e49df01d942a628, + 0x096c3a09773272d4, + }, + { + 0x9abc11eb5fadeff4, + 0x32dca50a885728f0, + 0xfb1fa3721569734c, + 0xc4b76271ea6506b3, + 0xd466a75599ce728e, + 0x0c81d4645f4cb6ed, + }, + { + 0x4199f10e5b8be45b, + 0xda64e495b1e87930, + 0xcb353efe9b33e4ff, + 0x9e9efb24aa6424c6, + 0xf08d33680a237465, + 0x0d3378023e4c7406, + }, + { + 0x7eb4ae92ec74d3a5, + 0xc341b4aa9fac3497, + 0x5be603899e907687, + 0x03bfd9cca75cbdeb, + 0x564c2935a96bfa93, + 0x0ef3c33371e2fdb5, + }, + { + 0x7ee91fd449f6ac2e, + 0xe5d5bd5cb9357a30, + 0x773a8ca5196b1380, + 0xd0fda172174ed023, + 0x6cb95e0fa776aead, + 0x0d22d5a40cec7cff, + }, + { + 0xf727e09285fd8519, + 0xdc9d55a83017897b, + 0x7549d8bd057894ae, + 0x178419613d90d8f8, + 0xfce95ebdeb5b490a, + 0x0467ffaef23fc49e, + }, + { + 0xc1769e6a7c385f1b, + 0x79bc930deac01c03, + 0x5461c75a23ede3b5, + 0x6e20829e5c230c45, + 0x828e0f1e772a53cd, + 0x116aefa749127bff, + }, + { + 0x101c10bf2744c10a, + 0xbbf18d053a6a3154, + 0xa0ecf39ef026f602, + 0xfc009d4996dc5153, + 0xb9000209d5bd08d3, + 0x189e5fe4470cd73c, + }, + { + 0x7ebd546ca1575ed2, + 0xe47d5a981d081b55, + 0x57b2b625b6d4ca21, + 0xb0a1ba04228520cc, + 0x98738983c2107ff3, + 0x13dddbc4799d81d6, + }, + { + 0x09319f2e39834935, + 0x039e952cbdb05c21, + 0x55ba77a9a2f76493, + 0xfd04e3dfc6086467, + 0xfb95832e7d78742e, + 0x0ef9c24eccaf5e0e, + }, + { + 0x760900000002fffd, + 0xebf4000bc40c0002, + 0x5f48985753c758ba, + 0x77ce585370525745, + 0x5c071a97a256ec6d, + 0x15f65ec3fa80e493, + }, + } +) + +// G1 is a point in g1 +type G1 struct { + x, y, z fp +} + +// Random creates a random point on the curve +// from the specified reader +func (g1 *G1) Random(reader io.Reader) (*G1, error) { + var seed [native.WideFieldBytes]byte + n, err := reader.Read(seed[:]) + if err != nil { + return nil, errors.Wrap(err, "random could not read from stream") + } + if n != native.WideFieldBytes { + return nil, fmt.Errorf("insufficient bytes read %d when %d are needed", n, WideFieldBytes) + } + dst := []byte("BLS12381G1_XMD:SHA-256_SSWU_RO_") + return g1.Hash(native.EllipticPointHasherSha256(), seed[:], dst), nil +} + +// Hash uses the hasher to map bytes to a valid point +func (g1 *G1) Hash(hash *native.EllipticPointHasher, msg, dst []byte) *G1 { + var u []byte + var u0, u1 fp + var r0, r1, q0, q1 G1 + + switch hash.Type() { + case native.XMD: + u = native.ExpandMsgXmd(hash, msg, dst, 128) + case native.XOF: + u = native.ExpandMsgXof(hash, msg, dst, 128) + } + + var buf [WideFieldBytes]byte + copy(buf[:64], internal.ReverseScalarBytes(u[:64])) + u0.SetBytesWide(&buf) + copy(buf[:64], internal.ReverseScalarBytes(u[64:])) + u1.SetBytesWide(&buf) + + r0.osswu3mod4(&u0) + r1.osswu3mod4(&u1) + q0.isogenyMap(&r0) + q1.isogenyMap(&r1) + g1.Add(&q0, &q1) + return g1.ClearCofactor(g1) +} + +// Identity returns the identity point +func (g1 *G1) Identity() *G1 { + g1.x.SetZero() + g1.y.SetOne() + g1.z.SetZero() + return g1 +} + +// Generator returns the base point +func (g1 *G1) Generator() *G1 { + g1.x.Set(&g1x) + g1.y.Set(&g1y) + g1.z.SetOne() + return g1 +} + +// IsIdentity returns true if this point is at infinity +func (g1 *G1) IsIdentity() int { + return g1.z.IsZero() +} + +// IsOnCurve determines if this point represents a valid curve point +func (g1 *G1) IsOnCurve() int { + // Y^2 Z = X^3 + b Z^3 + var lhs, rhs, t fp + lhs.Square(&g1.y) + lhs.Mul(&lhs, &g1.z) + + rhs.Square(&g1.x) + rhs.Mul(&rhs, &g1.x) + t.Square(&g1.z) + t.Mul(&t, &g1.z) + t.Mul(&t, &curveG1B) + rhs.Add(&rhs, &t) + + return lhs.Equal(&rhs) +} + +// InCorrectSubgroup returns 1 if the point is torsion free, 0 otherwise +func (g1 *G1) InCorrectSubgroup() int { + var t G1 + t.multiply(g1, &fqModulusBytes) + return t.IsIdentity() +} + +// Add adds this point to another point. +func (g1 *G1) Add(arg1, arg2 *G1) *G1 { + // Algorithm 7, https://eprint.iacr.org/2015/1060.pdf + var t0, t1, t2, t3, t4, x3, y3, z3 fp + + t0.Mul(&arg1.x, &arg2.x) + t1.Mul(&arg1.y, &arg2.y) + t2.Mul(&arg1.z, &arg2.z) + t3.Add(&arg1.x, &arg1.y) + t4.Add(&arg2.x, &arg2.y) + t3.Mul(&t3, &t4) + t4.Add(&t0, &t1) + t3.Sub(&t3, &t4) + t4.Add(&arg1.y, &arg1.z) + x3.Add(&arg2.y, &arg2.z) + t4.Mul(&t4, &x3) + x3.Add(&t1, &t2) + t4.Sub(&t4, &x3) + x3.Add(&arg1.x, &arg1.z) + y3.Add(&arg2.x, &arg2.z) + x3.Mul(&x3, &y3) + y3.Add(&t0, &t2) + y3.Sub(&x3, &y3) + x3.Double(&t0) + t0.Add(&t0, &x3) + t2.MulBy3b(&t2) + z3.Add(&t1, &t2) + t1.Sub(&t1, &t2) + y3.MulBy3b(&y3) + x3.Mul(&t4, &y3) + t2.Mul(&t3, &t1) + x3.Sub(&t2, &x3) + y3.Mul(&y3, &t0) + t1.Mul(&t1, &z3) + y3.Add(&t1, &y3) + t0.Mul(&t0, &t3) + z3.Mul(&z3, &t4) + z3.Add(&z3, &t0) + + g1.x.Set(&x3) + g1.y.Set(&y3) + g1.z.Set(&z3) + return g1 +} + +// Sub subtracts the two points +func (g1 *G1) Sub(arg1, arg2 *G1) *G1 { + var t G1 + t.Neg(arg2) + return g1.Add(arg1, &t) +} + +// Double this point +func (g1 *G1) Double(a *G1) *G1 { + // Algorithm 9, https://eprint.iacr.org/2015/1060.pdf + var t0, t1, t2, x3, y3, z3 fp + + t0.Square(&a.y) + z3.Double(&t0) + z3.Double(&z3) + z3.Double(&z3) + t1.Mul(&a.y, &a.z) + t2.Square(&a.z) + t2.MulBy3b(&t2) + x3.Mul(&t2, &z3) + y3.Add(&t0, &t2) + z3.Mul(&t1, &z3) + t1.Double(&t2) + t2.Add(&t2, &t1) + t0.Sub(&t0, &t2) + y3.Mul(&t0, &y3) + y3.Add(&y3, &x3) + t1.Mul(&a.x, &a.y) + x3.Mul(&t0, &t1) + x3.Double(&x3) + + e := a.IsIdentity() + g1.x.CMove(&x3, t0.SetZero(), e) + g1.z.CMove(&z3, &t0, e) + g1.y.CMove(&y3, t0.SetOne(), e) + return g1 +} + +// Mul multiplies this point by the input scalar +func (g1 *G1) Mul(a *G1, s *native.Field) *G1 { + bytes := s.Bytes() + return g1.multiply(a, &bytes) +} + +func (g1 *G1) multiply(a *G1, bytes *[native.FieldBytes]byte) *G1 { + var p G1 + precomputed := [16]*G1{} + precomputed[0] = new(G1).Identity() + precomputed[1] = new(G1).Set(a) + for i := 2; i < 16; i += 2 { + precomputed[i] = new(G1).Double(precomputed[i>>1]) + precomputed[i+1] = new(G1).Add(precomputed[i], a) + } + p.Identity() + for i := 0; i < 256; i += 4 { + // Brouwer / windowing method. window size of 4. + for j := 0; j < 4; j++ { + p.Double(&p) + } + window := bytes[32-1-i>>3] >> (4 - i&0x04) & 0x0F + p.Add(&p, precomputed[window]) + } + return g1.Set(&p) +} + +// MulByX multiplies by BLS X using double and add +func (g1 *G1) MulByX(a *G1) *G1 { + // Skip first bit since its always zero + var s, t, r G1 + r.Identity() + t.Set(a) + + for x := paramX >> 1; x != 0; x >>= 1 { + t.Double(&t) + s.Add(&r, &t) + r.CMove(&r, &s, int(x&1)) + } + // Since BLS_X is negative, flip the sign + return g1.Neg(&r) +} + +// ClearCofactor multiplies by (1 - z), where z is the parameter of BLS12-381, which +// [suffices to clear](https://ia.cr/2019/403) the cofactor and map +// elliptic curve points to elements of G1. +func (g1 *G1) ClearCofactor(a *G1) *G1 { + var t G1 + t.MulByX(a) + return g1.Sub(a, &t) +} + +// Neg negates this point +func (g1 *G1) Neg(a *G1) *G1 { + g1.Set(a) + g1.y.CNeg(&a.y, -(a.IsIdentity() - 1)) + return g1 +} + +// Set copies a into g1 +func (g1 *G1) Set(a *G1) *G1 { + g1.x.Set(&a.x) + g1.y.Set(&a.y) + g1.z.Set(&a.z) + return g1 +} + +// BigInt returns the x and y as big.Ints in affine +func (g1 *G1) BigInt() (x, y *big.Int) { + var t G1 + t.ToAffine(g1) + x = t.x.BigInt() + y = t.y.BigInt() + return +} + +// SetBigInt creates a point from affine x, y +// and returns the point if it is on the curve +func (g1 *G1) SetBigInt(x, y *big.Int) (*G1, error) { + var xx, yy fp + var pp G1 + pp.x = *(xx.SetBigInt(x)) + pp.y = *(yy.SetBigInt(y)) + + if pp.x.IsZero()&pp.y.IsZero() == 1 { + pp.Identity() + return g1.Set(&pp), nil + } + + pp.z.SetOne() + + // If not the identity point and not on the curve then invalid + if (pp.IsOnCurve()&pp.InCorrectSubgroup())|(xx.IsZero()&yy.IsZero()) == 0 { + return nil, fmt.Errorf("invalid coordinates") + } + return g1.Set(&pp), nil +} + +// ToCompressed serializes this element into compressed form. +func (g1 *G1) ToCompressed() [FieldBytes]byte { + var out [FieldBytes]byte + var t G1 + t.ToAffine(g1) + xBytes := t.x.Bytes() + copy(out[:], internal.ReverseScalarBytes(xBytes[:])) + isInfinity := byte(g1.IsIdentity()) + // Compressed flag + out[0] |= 1 << 7 + // Is infinity + out[0] |= (1 << 6) & -isInfinity + // Sign of y only set if not infinity + out[0] |= (byte(t.y.LexicographicallyLargest()) << 5) & (isInfinity - 1) + return out +} + +// FromCompressed deserializes this element from compressed form. +func (g1 *G1) FromCompressed(input *[FieldBytes]byte) (*G1, error) { + var xFp, yFp fp + var x [FieldBytes]byte + var p G1 + compressedFlag := int((input[0] >> 7) & 1) + infinityFlag := int((input[0] >> 6) & 1) + sortFlag := int((input[0] >> 5) & 1) + + if compressedFlag != 1 { + return nil, errors.New("compressed flag must be set") + } + + if infinityFlag == 1 { + return g1.Identity(), nil + } + + copy(x[:], internal.ReverseScalarBytes(input[:])) + // Mask away the flag bits + x[FieldBytes-1] &= 0x1F + _, valid := xFp.SetBytes(&x) + + if valid != 1 { + return nil, errors.New("invalid bytes - not in field") + } + + yFp.Square(&xFp) + yFp.Mul(&yFp, &xFp) + yFp.Add(&yFp, &curveG1B) + + _, wasSquare := yFp.Sqrt(&yFp) + if wasSquare != 1 { + return nil, errors.New("point is not on the curve") + } + + yFp.CNeg(&yFp, yFp.LexicographicallyLargest()^sortFlag) + p.x.Set(&xFp) + p.y.Set(&yFp) + p.z.SetOne() + if p.InCorrectSubgroup() == 0 { + return nil, errors.New("point is not in correct subgroup") + } + return g1.Set(&p), nil +} + +// ToUncompressed serializes this element into uncompressed form. +func (g1 *G1) ToUncompressed() [WideFieldBytes]byte { + var out [WideFieldBytes]byte + var t G1 + t.ToAffine(g1) + xBytes := t.x.Bytes() + yBytes := t.y.Bytes() + copy(out[:FieldBytes], internal.ReverseScalarBytes(xBytes[:])) + copy(out[FieldBytes:], internal.ReverseScalarBytes(yBytes[:])) + isInfinity := byte(g1.IsIdentity()) + out[0] |= (1 << 6) & -isInfinity + return out +} + +// FromUncompressed deserializes this element from uncompressed form. +func (g1 *G1) FromUncompressed(input *[WideFieldBytes]byte) (*G1, error) { + var xFp, yFp fp + var t [FieldBytes]byte + var p G1 + infinityFlag := int((input[0] >> 6) & 1) + + if infinityFlag == 1 { + return g1.Identity(), nil + } + + copy(t[:], internal.ReverseScalarBytes(input[:FieldBytes])) + // Mask away top bits + t[FieldBytes-1] &= 0x1F + + _, valid := xFp.SetBytes(&t) + if valid == 0 { + return nil, errors.New("invalid bytes - x not in field") + } + copy(t[:], internal.ReverseScalarBytes(input[FieldBytes:])) + _, valid = yFp.SetBytes(&t) + if valid == 0 { + return nil, errors.New("invalid bytes - y not in field") + } + + p.x.Set(&xFp) + p.y.Set(&yFp) + p.z.SetOne() + + if p.IsOnCurve() == 0 { + return nil, errors.New("point is not on the curve") + } + if p.InCorrectSubgroup() == 0 { + return nil, errors.New("point is not in correct subgroup") + } + return g1.Set(&p), nil +} + +// ToAffine converts the point into affine coordinates +func (g1 *G1) ToAffine(a *G1) *G1 { + var wasInverted int + var zero, x, y, z fp + _, wasInverted = z.Invert(&a.z) + x.Mul(&a.x, &z) + y.Mul(&a.y, &z) + + g1.x.CMove(&zero, &x, wasInverted) + g1.y.CMove(&zero, &y, wasInverted) + g1.z.CMove(&zero, z.SetOne(), wasInverted) + return g1 +} + +// GetX returns the affine X coordinate +func (g1 *G1) GetX() *fp { + var t G1 + t.ToAffine(g1) + return &t.x +} + +// GetY returns the affine Y coordinate +func (g1 *G1) GetY() *fp { + var t G1 + t.ToAffine(g1) + return &t.y +} + +// Equal returns 1 if the two points are equal 0 otherwise. +func (g1 *G1) Equal(rhs *G1) int { + var x1, x2, y1, y2 fp + var e1, e2 int + + // This technique avoids inversions + x1.Mul(&g1.x, &rhs.z) + x2.Mul(&rhs.x, &g1.z) + + y1.Mul(&g1.y, &rhs.z) + y2.Mul(&rhs.y, &g1.z) + + e1 = g1.z.IsZero() + e2 = rhs.z.IsZero() + + // Both at infinity or coordinates are the same + return (e1 & e2) | (^e1 & ^e2)&x1.Equal(&x2)&y1.Equal(&y2) +} + +// CMove sets g1 = arg1 if choice == 0 and g1 = arg2 if choice == 1 +func (g1 *G1) CMove(arg1, arg2 *G1, choice int) *G1 { + g1.x.CMove(&arg1.x, &arg2.x, choice) + g1.y.CMove(&arg1.y, &arg2.y, choice) + g1.z.CMove(&arg1.z, &arg2.z, choice) + return g1 +} + +// SumOfProducts computes the multi-exponentiation for the specified +// points and scalars and stores the result in `g1`. +// Returns an error if the lengths of the arguments is not equal. +func (g1 *G1) SumOfProducts(points []*G1, scalars []*native.Field) (*G1, error) { + const Upper = 256 + const W = 4 + const Windows = Upper / W // careful--use ceiling division in case this doesn't divide evenly + var sum G1 + if len(points) != len(scalars) { + return nil, fmt.Errorf("length mismatch") + } + + bucketSize := 1 << W + windows := make([]G1, Windows) + bytes := make([][32]byte, len(scalars)) + buckets := make([]G1, bucketSize) + + for i := 0; i < len(windows); i++ { + windows[i].Identity() + } + + for i, scalar := range scalars { + bytes[i] = scalar.Bytes() + } + + for j := 0; j < len(windows); j++ { + for i := 0; i < bucketSize; i++ { + buckets[i].Identity() + } + + for i := 0; i < len(scalars); i++ { + // j*W to get the nibble + // >> 3 to convert to byte, / 8 + // (W * j & W) gets the nibble, mod W + // 1 << W - 1 to get the offset + index := bytes[i][j*W>>3] >> (W * j & W) & (1< 0; i-- { + sum.Add(&sum, &buckets[i]) + windows[j].Add(&windows[j], &sum) + } + } + + g1.Identity() + for i := len(windows) - 1; i >= 0; i-- { + for j := 0; j < W; j++ { + g1.Double(g1) + } + + g1.Add(g1, &windows[i]) + } + return g1, nil +} + +func (g1 *G1) osswu3mod4(u *fp) *G1 { + // Taken from section 8.8.1 in + // + var tv1, tv2, tv3, tv4, xd, x1n, x2n, gxd, gx1, y1, y2 fp + + // tv1 = u^2 + tv1.Square(u) + // tv3 = Z * tv1 + tv3.Mul(&oswwuMapZ, &tv1) + // tv2 = tv3^2 + tv2.Square(&tv3) + // xd = tv2 + tv3 + xd.Add(&tv2, &tv3) + // x1n = xd + 1 + x1n.Add(&xd, &r) + // x1n = x1n * B + x1n.Mul(&x1n, &osswuMapB) + // xd = -A * xd + xd.Mul(&negOsswuMapA, &xd) + // xd = CMOV(xd, Z * A, xd == 0) + xd.CMove(&xd, &oswwuMapXd1, xd.IsZero()) + // tv2 = xd^2 + tv2.Square(&xd) + + gxd.Mul(&tv2, &xd) + tv2.Mul(&tv2, &osswuMapA) + gx1.Square(&x1n) + gx1.Add(&gx1, &tv2) + gx1.Mul(&gx1, &x1n) + tv2.Mul(&osswuMapB, &gxd) + + gx1.Add(&gx1, &tv2) + tv4.Square(&gxd) + tv2.Mul(&gx1, &gxd) + tv4.Mul(&tv4, &tv2) + y1.pow(&tv4, &osswuMapC1) + y1.Mul(&y1, &tv2) + + x2n.Mul(&tv3, &x1n) + y2.Mul(&y1, &osswuMapC2) + y2.Mul(&y2, &tv1) + y2.Mul(&y2, u) + + tv2.Square(&y1) + tv2.Mul(&tv2, &gxd) + e2 := tv2.Equal(&gx1) + + x2n.CMove(&x2n, &x1n, e2) + y2.CMove(&y2, &y1, e2) + + e3 := u.Sgn0() ^ y2.Sgn0() + y2.CNeg(&y2, e3) + + g1.z.SetOne() + g1.y.Set(&y2) + _, _ = g1.x.Invert(&xd) + g1.x.Mul(&g1.x, &x2n) + return g1 +} + +func (g1 *G1) isogenyMap(a *G1) *G1 { + const Degree = 16 + var xs [Degree]fp + xs[0] = r + xs[1].Set(&a.x) + xs[2].Square(&a.x) + for i := 3; i < Degree; i++ { + xs[i].Mul(&xs[i-1], &a.x) + } + + xNum := computeKFp(xs[:], g1IsoXNum) + xDen := computeKFp(xs[:], g1IsoXDen) + yNum := computeKFp(xs[:], g1IsoYNum) + yDen := computeKFp(xs[:], g1IsoYDen) + + g1.x.Invert(&xDen) + g1.x.Mul(&g1.x, &xNum) + + g1.y.Invert(&yDen) + g1.y.Mul(&g1.y, &yNum) + g1.y.Mul(&g1.y, &a.y) + g1.z.SetOne() + return g1 +} + +func computeKFp(xxs []fp, k []fp) fp { + var xx, t fp + for i := range k { + xx.Add(&xx, t.Mul(&xxs[i], &k[i])) + } + return xx +} diff --git a/pkg/crypto/core/curves/native/bls12381/g1_test.go b/pkg/crypto/core/curves/native/bls12381/g1_test.go new file mode 100755 index 000000000..441ab0927 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/g1_test.go @@ -0,0 +1,412 @@ +package bls12381 + +import ( + crand "crypto/rand" + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +func TestG1IsOnCurve(t *testing.T) { + require.Equal(t, 1, new(G1).Identity().IsOnCurve()) + require.Equal(t, 1, new(G1).Generator().IsOnCurve()) + + z := fp{ + 0xba7afa1f9a6fe250, + 0xfa0f5b595eafe731, + 0x3bdc477694c306e7, + 0x2149be4b3949fa24, + 0x64aa6e0649b2078c, + 0x12b108ac33643c3e, + } + + gen := new(G1).Generator() + test := G1{ + x: *(gen.x.Mul(&gen.x, &z)), + y: *(gen.y.Mul(&gen.y, &z)), + z: z, + } + require.Equal(t, 1, test.IsOnCurve()) + test.x = z + require.Equal(t, 0, test.IsOnCurve()) +} + +func TestG1Equality(t *testing.T) { + a := new(G1).Generator() + b := new(G1).Identity() + + require.Equal(t, 1, a.Equal(a)) + require.Equal(t, 1, b.Equal(b)) + require.Equal(t, 0, a.Equal(b)) + require.Equal(t, 0, b.Equal(a)) + + z := fp{ + 0xba7afa1f9a6fe250, + 0xfa0f5b595eafe731, + 0x3bdc477694c306e7, + 0x2149be4b3949fa24, + 0x64aa6e0649b2078c, + 0x12b108ac33643c3e, + } + + c := G1{} + c.x.Mul(&a.x, &z) + c.y.Mul(&a.y, &z) + c.z.Set(&z) + + require.Equal(t, 1, c.IsOnCurve()) + + require.Equal(t, 1, a.Equal(&c)) + require.Equal(t, 0, b.Equal(&c)) + + c.y.Neg(&c.y) + require.Equal(t, 1, c.IsOnCurve()) + + require.Equal(t, 0, a.Equal(&c)) + + c.y.Neg(&c.y) + c.x.Set(&z) + require.Equal(t, 0, c.IsOnCurve()) +} + +func TestG1Double(t *testing.T) { + t0 := new(G1).Identity() + t0.Double(t0) + require.Equal(t, 1, t0.IsIdentity()) + require.Equal(t, 1, t0.IsOnCurve()) + + t0.Double(t0.Generator()) + require.Equal(t, 0, t0.IsIdentity()) + require.Equal(t, 1, t0.IsOnCurve()) + e := G1{ + x: fp{ + 0x53e978ce58a9ba3c, + 0x3ea0583c4f3d65f9, + 0x4d20bb47f0012960, + 0xa54c664ae5b2b5d9, + 0x26b552a39d7eb21f, + 0x0008895d26e68785, + }, + y: fp{ + 0x70110b3298293940, + 0xda33c5393f1f6afc, + 0xb86edfd16a5aa785, + 0xaec6d1c9e7b1c895, + 0x25cfc2b522d11720, + 0x06361c83f8d09b15, + }, + z: r, + } + + require.Equal(t, 1, e.Equal(t0)) +} + +func TestG1Add(t *testing.T) { + g := new(G1).Generator() + a := new(G1).Identity() + b := new(G1).Identity() + c := new(G1).Add(a, b) + require.Equal(t, 1, c.IsIdentity()) + require.Equal(t, 1, c.IsOnCurve()) + + b.Generator() + z := fp{ + 0xba7afa1f9a6fe250, + 0xfa0f5b595eafe731, + 0x3bdc477694c306e7, + 0x2149be4b3949fa24, + 0x64aa6e0649b2078c, + 0x12b108ac33643c3e, + } + b.x.Mul(&b.x, &z) + b.y.Mul(&b.y, &z) + b.z.Set(&z) + c.Add(a, b) + require.Equal(t, 0, c.IsIdentity()) + require.Equal(t, 1, g.Equal(c)) + + a.Generator() + a.Double(a) + a.Double(a) + b.Generator() + b.Double(b) + c.Add(a, b) + d := new(G1).Generator() + for i := 0; i < 5; i++ { + d.Add(d, g) + } + require.Equal(t, 0, c.IsIdentity()) + require.Equal(t, 1, c.IsOnCurve()) + require.Equal(t, 0, d.IsIdentity()) + require.Equal(t, 1, d.IsOnCurve()) + require.Equal(t, 1, c.Equal(d)) + + beta := fp{ + 0xcd03c9e48671f071, + 0x5dab22461fcda5d2, + 0x587042afd3851b95, + 0x8eb60ebe01bacb9e, + 0x03f97d6e83d050d2, + 0x18f0206554638741, + } + beta.Square(&beta) + a.Generator() + a.Double(a) + a.Double(a) + b.x.Mul(&a.x, &beta) + b.y.Neg(&a.y) + b.z.Set(&a.z) + require.Equal(t, 1, a.IsOnCurve()) + require.Equal(t, 1, b.IsOnCurve()) + c.Add(a, b) + d.x.Set(&fp{ + 0x29e1e987ef68f2d0, + 0xc5f3ec531db03233, + 0xacd6c4b6ca19730f, + 0x18ad9e827bc2bab7, + 0x46e3b2c5785cc7a9, + 0x07e571d42d22ddd6, + }) + d.y.Set(&fp{ + 0x94d117a7e5a539e7, + 0x8e17ef673d4b5d22, + 0x9d746aaf508a33ea, + 0x8c6d883d2516c9a2, + 0x0bc3b8d5fb0447f7, + 0x07bfa4c7210f4f44, + }) + d.z.SetOne() + require.Equal(t, 1, c.Equal(d)) +} + +func TestG1Sub(t *testing.T) { + a := new(G1).Generator() + b := new(G1).Generator() + require.Equal(t, 1, a.Sub(a, b).IsIdentity()) + b.Double(b) + a.Generator() + require.Equal(t, 1, b.Sub(b, a).Equal(a)) +} + +func TestG1Mul(t *testing.T) { + g := new(G1).Generator() + a := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{ + 0x2b568297a56da71c, + 0xd8c39ecb0ef375d1, + 0x435c38da67bfbf96, + 0x8088a05026b659b2, + }) + b := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{ + 0x785fdd9b26ef8b85, + 0xc997f25837695c18, + 0x4c8dbc39e7b756c1, + 0x70d9b6cc6d87df20, + }) + c := Bls12381FqNew().Mul(a, b) + t1 := new(G1).Generator() + t1.Mul(t1, a) + t1.Mul(t1, b) + require.Equal(t, 1, t1.Equal(g.Mul(g, c))) +} + +func TestG1Neg(t *testing.T) { + a := new(G1).Generator() + b := new(G1).Neg(a) + require.Equal(t, 1, new(G1).Add(a, b).IsIdentity()) + require.Equal(t, 1, new(G1).Sub(a, b.Neg(b)).IsIdentity()) + a.Identity() + require.Equal(t, 1, a.Neg(a).IsIdentity()) +} + +func TestG1InCorrectSubgroup(t *testing.T) { + // ZCash test vector + a := G1{ + x: fp{ + 0x0abaf895b97e43c8, + 0xba4c6432eb9b61b0, + 0x12506f52adfe307f, + 0x75028c3439336b72, + 0x84744f05b8e9bd71, + 0x113d554fb09554f7, + }, + y: fp{ + 0x73e90e88f5cf01c0, + 0x37007b65dd3197e2, + 0x5cf9a1992f0d7c78, + 0x4f83c10b9eb3330d, + 0xf6a63f6f07f60961, + 0x0c53b5b97e634df3, + }, + z: *(new(fp).SetOne()), + } + require.Equal(t, 0, a.InCorrectSubgroup()) + + require.Equal(t, 1, new(G1).Identity().InCorrectSubgroup()) + require.Equal(t, 1, new(G1).Generator().InCorrectSubgroup()) +} + +func TestG1MulByX(t *testing.T) { + // multiplying by `x` a point in G1 is the same as multiplying by + // the equivalent scalar. + generator := new(G1).Generator() + x := Bls12381FqNew().SetUint64(paramX) + x.Neg(x) + lhs := new(G1).Mul(generator, x) + rhs := new(G1).MulByX(generator) + require.Equal(t, 1, lhs.Equal(rhs)) + + pt := new(G1).Generator() + s := Bls12381FqNew().SetUint64(42) + pt.Mul(pt, s) + lhs.Mul(pt, x) + rhs.MulByX(pt) + require.Equal(t, 1, lhs.Equal(rhs)) +} + +func TestG1ClearCofactor(t *testing.T) { + // the generator (and the identity) are always on the curve, + // even after clearing the cofactor + generator := new(G1).Generator() + generator.ClearCofactor(generator) + require.Equal(t, 1, generator.IsOnCurve()) + id := new(G1).Identity() + id.ClearCofactor(id) + require.Equal(t, 1, id.IsOnCurve()) + + z := fp{ + 0x3d2d1c670671394e, + 0x0ee3a800a2f7c1ca, + 0x270f4f21da2e5050, + 0xe02840a53f1be768, + 0x55debeb597512690, + 0x08bd25353dc8f791, + } + + point := G1{ + x: fp{ + 0x48af5ff540c817f0, + 0xd73893acaf379d5a, + 0xe6c43584e18e023c, + 0x1eda39c30f188b3e, + 0xf618c6d3ccc0f8d8, + 0x0073542cd671e16c, + }, + y: fp{ + 0x57bf8be79461d0ba, + 0xfc61459cee3547c3, + 0x0d23567df1ef147b, + 0x0ee187bcce1d9b64, + 0xb0c8cfbe9dc8fdc1, + 0x1328661767ef368b, + }, + z: *(&fp{}).Set(&z), + } + point.x.Mul(&point.x, &z) + point.z.Square(&z) + point.z.Mul(&point.z, &z) + + require.Equal(t, 1, point.IsOnCurve()) + require.Equal(t, 0, point.InCorrectSubgroup()) + clearedPoint := new(G1).ClearCofactor(&point) + require.Equal(t, 1, clearedPoint.IsOnCurve()) + require.Equal(t, 1, clearedPoint.InCorrectSubgroup()) + + // in BLS12-381 the cofactor in G1 can be + // cleared multiplying by (1-x) + hEff := Bls12381FqNew().SetOne() + hEff.Add(hEff, Bls12381FqNew().SetUint64(paramX)) + point.Mul(&point, hEff) + require.Equal(t, 1, clearedPoint.Equal(&point)) +} + +func TestG1Hash(t *testing.T) { + dst := []byte("QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_") + tests := []struct { + input, expected string + }{ + {"", "052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a108ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265"}, + {"abc", "03567bc5ef9c690c2ab2ecdf6a96ef1c139cc0b2f284dca0a9a7943388a49a3aee664ba5379a7655d3c68900be2f69030b9c15f3fe6e5cf4211f346271d7b01c8f3b28be689c8429c85b67af215533311f0b8dfaaa154fa6b88176c229f2885d"}, + {"abcdef0123456789", "11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d9803a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709"}, + {"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", "15f68eaa693b95ccb85215dc65fa81038d69629f70aeee0d0f677cf22285e7bf58d7cb86eefe8f2e9bc3f8cb84fac4881807a1d50c29f430b8cafc4f8638dfeeadf51211e1602a5f184443076715f91bb90a48ba1e370edce6ae1062f5e6dd38"}, + {"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "082aabae8b7dedb0e78aeb619ad3bfd9277a2f77ba7fad20ef6aabdc6c31d19ba5a6d12283553294c1825c4b3ca2dcfe05b84ae5a942248eea39e1d91030458c40153f3b654ab7872d779ad1e942856a20c438e8d99bc8abfbf74729ce1f7ac8"}, + } + + pt := new(G1).Identity() + ept := new(G1).Identity() + var b [WideFieldBytes]byte + for _, tst := range tests { + i := []byte(tst.input) + e, _ := hex.DecodeString(tst.expected) + copy(b[:], e) + _, _ = ept.FromUncompressed(&b) + pt.Hash(native.EllipticPointHasherSha256(), i, dst) + require.Equal(t, 1, pt.Equal(ept)) + } +} + +func TestSerialization(t *testing.T) { + a := new(G1).Hash(native.EllipticPointHasherSha256(), []byte("a"), []byte("BLS12381G1_XMD:SHA-256_SSWU_RO_")) + b := new(G1).Hash(native.EllipticPointHasherSha256(), []byte("b"), []byte("BLS12381G1_XMD:SHA-256_SSWU_RO_")) + + aBytes := a.ToCompressed() + bBytes := b.ToCompressed() + + aa, err := new(G1).FromCompressed(&aBytes) + require.NoError(t, err) + require.Equal(t, 1, a.Equal(aa)) + + bb, err := new(G1).FromCompressed(&bBytes) + require.NoError(t, err) + require.Equal(t, 1, b.Equal(bb)) + + auBytes := a.ToUncompressed() + buBytes := b.ToUncompressed() + + _, err = aa.FromUncompressed(&auBytes) + require.NoError(t, err) + require.Equal(t, 1, a.Equal(aa)) + + _, err = bb.FromUncompressed(&buBytes) + require.NoError(t, err) + require.Equal(t, 1, b.Equal(bb)) + + bBytes = a.ToCompressed() + a.Neg(a) + aBytes = a.ToCompressed() + _, err = aa.FromCompressed(&aBytes) + require.NoError(t, err) + require.Equal(t, 1, a.Equal(aa)) + _, err = aa.FromCompressed(&bBytes) + require.NoError(t, err) + require.Equal(t, 0, a.Equal(aa)) + require.Equal(t, 1, aa.Equal(a.Neg(a))) +} + +func TestSumOfProducts(t *testing.T) { + var b [64]byte + h0, _ := new(G1).Random(crand.Reader) + _, _ = crand.Read(b[:]) + s := Bls12381FqNew().SetBytesWide(&b) + _, _ = crand.Read(b[:]) + sTilde := Bls12381FqNew().SetBytesWide(&b) + _, _ = crand.Read(b[:]) + c := Bls12381FqNew().SetBytesWide(&b) + + lhs := new(G1).Mul(h0, s) + rhs, _ := new(G1).SumOfProducts([]*G1{h0}, []*native.Field{s}) + require.Equal(t, 1, lhs.Equal(rhs)) + + u := new(G1).Mul(h0, s) + uTilde := new(G1).Mul(h0, sTilde) + sHat := Bls12381FqNew().Mul(c, s) + sHat.Sub(sTilde, sHat) + + rhs.Mul(u, c) + rhs.Add(rhs, new(G1).Mul(h0, sHat)) + require.Equal(t, 1, uTilde.Equal(rhs)) + _, _ = rhs.SumOfProducts([]*G1{u, h0}, []*native.Field{c, sHat}) + require.Equal(t, 1, uTilde.Equal(rhs)) +} diff --git a/pkg/crypto/core/curves/native/bls12381/g2.go b/pkg/crypto/core/curves/native/bls12381/g2.go new file mode 100755 index 000000000..0278290a9 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/g2.go @@ -0,0 +1,1122 @@ +package bls12381 + +import ( + "fmt" + "io" + "math/big" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + g2x = fp2{ + A: fp{ + 0xf5f2_8fa2_0294_0a10, + 0xb3f5_fb26_87b4_961a, + 0xa1a8_93b5_3e2a_e580, + 0x9894_999d_1a3c_aee9, + 0x6f67_b763_1863_366b, + 0x0581_9192_4350_bcd7, + }, + B: fp{ + 0xa5a9_c075_9e23_f606, + 0xaaa0_c59d_bccd_60c3, + 0x3bb1_7e18_e286_7806, + 0x1b1a_b6cc_8541_b367, + 0xc2b6_ed0e_f215_8547, + 0x1192_2a09_7360_edf3, + }, + } + g2y = fp2{ + A: fp{ + 0x4c73_0af8_6049_4c4a, + 0x597c_fa1f_5e36_9c5a, + 0xe7e6_856c_aa0a_635a, + 0xbbef_b5e9_6e0d_495f, + 0x07d3_a975_f0ef_25a2, + 0x0083_fd8e_7e80_dae5, + }, + B: fp{ + 0xadc0_fc92_df64_b05d, + 0x18aa_270a_2b14_61dc, + 0x86ad_ac6a_3be4_eba0, + 0x7949_5c4e_c93d_a33a, + 0xe717_5850_a43c_caed, + 0x0b2b_c2a1_63de_1bf2, + }, + } + curveG2B = fp2{ + A: fp{ + 0xaa27_0000_000c_fff3, + 0x53cc_0032_fc34_000a, + 0x478f_e97a_6b0a_807f, + 0xb1d3_7ebe_e6ba_24d7, + 0x8ec9_733b_bf78_ab2f, + 0x09d6_4551_3d83_de7e, + }, + B: fp{ + 0xaa27_0000_000c_fff3, + 0x53cc_0032_fc34_000a, + 0x478f_e97a_6b0a_807f, + 0xb1d3_7ebe_e6ba_24d7, + 0x8ec9_733b_bf78_ab2f, + 0x09d6_4551_3d83_de7e, + }, + } + curveG23B = fp2{ + A: fp{ + 0x447600000027552e, + 0xdcb8009a43480020, + 0x6f7ee9ce4a6e8b59, + 0xb10330b7c0a95bc6, + 0x6140b1fcfb1e54b7, + 0x0381be097f0bb4e1, + }, + B: fp{ + 0x447600000027552e, + 0xdcb8009a43480020, + 0x6f7ee9ce4a6e8b59, + 0xb10330b7c0a95bc6, + 0x6140b1fcfb1e54b7, + 0x0381be097f0bb4e1, + }, + } + sswuMapA = fp2{ + A: fp{}, + B: fp{ + 0xe53a000003135242, + 0x01080c0fdef80285, + 0xe7889edbe340f6bd, + 0x0b51375126310601, + 0x02d6985717c744ab, + 0x1220b4e979ea5467, + }, + } + sswuMapB = fp2{ + A: fp{ + 0x22ea00000cf89db2, + 0x6ec832df71380aa4, + 0x6e1b94403db5a66e, + 0x75bf3c53a79473ba, + 0x3dd3a569412c0a34, + 0x125cdb5e74dc4fd1, + }, + B: fp{ + 0x22ea00000cf89db2, + 0x6ec832df71380aa4, + 0x6e1b94403db5a66e, + 0x75bf3c53a79473ba, + 0x3dd3a569412c0a34, + 0x125cdb5e74dc4fd1, + }, + } + sswuMapZ = fp2{ + A: fp{ + 0x87ebfffffff9555c, + 0x656fffe5da8ffffa, + 0x0fd0749345d33ad2, + 0xd951e663066576f4, + 0xde291a3d41e980d3, + 0x0815664c7dfe040d, + }, + B: fp{ + 0x43f5fffffffcaaae, + 0x32b7fff2ed47fffd, + 0x07e83a49a2e99d69, + 0xeca8f3318332bb7a, + 0xef148d1ea0f4c069, + 0x040ab3263eff0206, + }, + } + sswuMapZInv = fp2{ + A: fp{ + 0xacd0000000011110, + 0x9dd9999dc88ccccd, + 0xb5ca2ac9b76352bf, + 0xf1b574bcf4bc90ce, + 0x42dab41f28a77081, + 0x132fc6ac14cd1e12, + }, + B: fp{ + 0xe396ffffffff2223, + 0x4fbf332fcd0d9998, + 0x0c4bbd3c1aff4cc4, + 0x6b9c91267926ca58, + 0x29ae4da6aef7f496, + 0x10692e942f195791, + }, + } + swwuMapMbDivA = fp2{ + A: fp{ + 0x903c555555474fb3, + 0x5f98cc95ce451105, + 0x9f8e582eefe0fade, + 0xc68946b6aebbd062, + 0x467a4ad10ee6de53, + 0x0e7146f483e23a05, + }, + B: fp{ + 0x29c2aaaaaab85af8, + 0xbf133368e30eeefa, + 0xc7a27a7206cffb45, + 0x9dee04ce44c9425c, + 0x04a15ce53464ce83, + 0x0b8fcaf5b59dac95, + }, + } + + g2IsoXNum = []fp2{ + { + A: fp{ + 0x47f671c71ce05e62, + 0x06dd57071206393e, + 0x7c80cd2af3fd71a2, + 0x048103ea9e6cd062, + 0xc54516acc8d037f6, + 0x13808f550920ea41, + }, + B: fp{ + 0x47f671c71ce05e62, + 0x06dd57071206393e, + 0x7c80cd2af3fd71a2, + 0x048103ea9e6cd062, + 0xc54516acc8d037f6, + 0x13808f550920ea41, + }, + }, + { + A: fp{ + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + B: fp{ + 0x5fe55555554c71d0, + 0x873fffdd236aaaa3, + 0x6a6b4619b26ef918, + 0x21c2888408874945, + 0x2836cda7028cabc5, + 0x0ac73310a7fd5abd, + }, + }, + { + A: fp{ + 0x0a0c5555555971c3, + 0xdb0c00101f9eaaae, + 0xb1fb2f941d797997, + 0xd3960742ef416e1c, + 0xb70040e2c20556f4, + 0x149d7861e581393b, + }, + B: fp{ + 0xaff2aaaaaaa638e8, + 0x439fffee91b55551, + 0xb535a30cd9377c8c, + 0x90e144420443a4a2, + 0x941b66d3814655e2, + 0x0563998853fead5e, + }, + }, + { + A: fp{ + 0x40aac71c71c725ed, + 0x190955557a84e38e, + 0xd817050a8f41abc3, + 0xd86485d4c87f6fb1, + 0x696eb479f885d059, + 0x198e1a74328002d2, + }, + B: fp{ + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + }, + } + g2IsoXDen = []fp2{ + { + A: fp{ + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + B: fp{ + 0x1f3affffff13ab97, + 0xf25bfc611da3ff3e, + 0xca3757cb3819b208, + 0x3e6427366f8cec18, + 0x03977bc86095b089, + 0x04f69db13f39a952, + }, + }, + { + A: fp{ + 0x447600000027552e, + 0xdcb8009a43480020, + 0x6f7ee9ce4a6e8b59, + 0xb10330b7c0a95bc6, + 0x6140b1fcfb1e54b7, + 0x0381be097f0bb4e1, + }, + B: fp{ + 0x7588ffffffd8557d, + 0x41f3ff646e0bffdf, + 0xf7b1e8d2ac426aca, + 0xb3741acd32dbb6f8, + 0xe9daf5b9482d581f, + 0x167f53e0ba7431b8, + }, + }, + { + A: fp{ + 0x760900000002fffd, + 0xebf4000bc40c0002, + 0x5f48985753c758ba, + 0x77ce585370525745, + 0x5c071a97a256ec6d, + 0x15f65ec3fa80e493, + }, + B: fp{ + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + }, + } + g2IsoYNum = []fp2{ + { + A: fp{ + 0x96d8f684bdfc77be, + 0xb530e4f43b66d0e2, + 0x184a88ff379652fd, + 0x57cb23ecfae804e1, + 0x0fd2e39eada3eba9, + 0x08c8055e31c5d5c3, + }, + B: fp{ + 0x96d8f684bdfc77be, + 0xb530e4f43b66d0e2, + 0x184a88ff379652fd, + 0x57cb23ecfae804e1, + 0x0fd2e39eada3eba9, + 0x08c8055e31c5d5c3, + }, + }, + { + A: fp{ + 0o00000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + B: fp{ + 0xbf0a71c71c91b406, + 0x4d6d55d28b7638fd, + 0x9d82f98e5f205aee, + 0xa27aa27b1d1a18d5, + 0x02c3b2b2d2938e86, + 0x0c7d13420b09807f, + }, + }, + { + A: fp{ + 0xd7f9555555531c74, + 0x21cffff748daaaa8, + 0x5a9ad1866c9bbe46, + 0x4870a2210221d251, + 0x4a0db369c0a32af1, + 0x02b1ccc429ff56af, + }, + B: fp{ + 0xe205aaaaaaac8e37, + 0xfcdc000768795556, + 0x0c96011a8a1537dd, + 0x1c06a963f163406e, + 0x010df44c82a881e6, + 0x174f45260f808feb, + }, + }, + { + A: fp{ + 0xa470bda12f67f35c, + 0xc0fe38e23327b425, + 0xc9d3d0f2c6f0678d, + 0x1c55c9935b5a982e, + 0x27f6c0e2f0746764, + 0x117c5e6e28aa9054, + }, + B: fp{ + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + }, + } + g2IsoYDen = []fp2{ + { + A: fp{ + 0x0162fffffa765adf, + 0x8f7bea480083fb75, + 0x561b3c2259e93611, + 0x11e19fc1a9c875d5, + 0xca713efc00367660, + 0x03c6a03d41da1151, + }, + B: fp{ + 0x0162fffffa765adf, + 0x8f7bea480083fb75, + 0x561b3c2259e93611, + 0x11e19fc1a9c875d5, + 0xca713efc00367660, + 0x03c6a03d41da1151, + }, + }, + { + A: fp{ + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + B: fp{ + 0x5db0fffffd3b02c5, + 0xd713f52358ebfdba, + 0x5ea60761a84d161a, + 0xbb2c75a34ea6c44a, + 0x0ac6735921c1119b, + 0x0ee3d913bdacfbf6, + }, + }, + { + A: fp{ + 0x66b10000003affc5, + 0xcb1400e764ec0030, + 0xa73e5eb56fa5d106, + 0x8984c913a0fe09a9, + 0x11e10afb78ad7f13, + 0x05429d0e3e918f52, + }, + B: fp{ + 0x534dffffffc4aae6, + 0x5397ff174c67ffcf, + 0xbff273eb870b251d, + 0xdaf2827152870915, + 0x393a9cbaca9e2dc3, + 0x14be74dbfaee5748, + }, + }, + { + A: fp{ + 0x760900000002fffd, + 0xebf4000bc40c0002, + 0x5f48985753c758ba, + 0x77ce585370525745, + 0x5c071a97a256ec6d, + 0x15f65ec3fa80e493, + }, + B: fp{ + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + }, + } + + // 1 / ((u+1) ^ ((q-1)/3)) + psiCoeffX = fp2{ + A: fp{}, + B: fp{ + 0x890dc9e4867545c3, + 0x2af322533285a5d5, + 0x50880866309b7e2c, + 0xa20d1b8c7e881024, + 0x14e4f04fe2db9068, + 0x14e56d3f1564853a, + }, + } + // 1 / ((u+1) ^ (p-1)/2) + psiCoeffY = fp2{ + A: fp{ + 0x3e2f585da55c9ad1, + 0x4294213d86c18183, + 0x382844c88b623732, + 0x92ad2afd19103e18, + 0x1d794e4fac7cf0b9, + 0x0bd592fc7d825ec8, + }, + B: fp{ + 0x7bcfa7a25aa30fda, + 0xdc17dec12a927e7c, + 0x2f088dd86b4ebef1, + 0xd1ca2087da74d4a7, + 0x2da2596696cebc1d, + 0x0e2b7eedbbfd87d2, + }, + } + + // 1 / 2 ^ ((q-1)/3) + psi2CoeffX = fp2{ + A: fp{ + 0xcd03c9e48671f071, + 0x5dab22461fcda5d2, + 0x587042afd3851b95, + 0x8eb60ebe01bacb9e, + 0x03f97d6e83d050d2, + 0x18f0206554638741, + }, + B: fp{}, + } +) + +// G2 is a point in g2 +type G2 struct { + x, y, z fp2 +} + +// Random creates a random point on the curve +// from the specified reader +func (g2 *G2) Random(reader io.Reader) (*G2, error) { + var seed [native.WideFieldBytes]byte + n, err := reader.Read(seed[:]) + if err != nil { + return nil, errors.Wrap(err, "random could not read from stream") + } + if n != native.WideFieldBytes { + return nil, fmt.Errorf("insufficient bytes read %d when %d are needed", n, WideFieldBytes) + } + dst := []byte("BLS12381G2_XMD:SHA-256_SSWU_RO_") + return g2.Hash(native.EllipticPointHasherSha256(), seed[:], dst), nil +} + +// Hash uses the hasher to map bytes to a valid point +func (g2 *G2) Hash(hash *native.EllipticPointHasher, msg, dst []byte) *G2 { + var u []byte + var u0, u1 fp2 + var r0, r1, q0, q1 G2 + + switch hash.Type() { + case native.XMD: + u = native.ExpandMsgXmd(hash, msg, dst, 256) + case native.XOF: + u = native.ExpandMsgXof(hash, msg, dst, 256) + } + + var buf [96]byte + copy(buf[:64], internal.ReverseScalarBytes(u[:64])) + u0.A.SetBytesWide(&buf) + copy(buf[:64], internal.ReverseScalarBytes(u[64:128])) + u0.B.SetBytesWide(&buf) + copy(buf[:64], internal.ReverseScalarBytes(u[128:192])) + u1.A.SetBytesWide(&buf) + copy(buf[:64], internal.ReverseScalarBytes(u[192:])) + u1.B.SetBytesWide(&buf) + + r0.sswu(&u0) + r1.sswu(&u1) + q0.isogenyMap(&r0) + q1.isogenyMap(&r1) + g2.Add(&q0, &q1) + return g2.ClearCofactor(g2) +} + +// Identity returns the identity point +func (g2 *G2) Identity() *G2 { + g2.x.SetZero() + g2.y.SetOne() + g2.z.SetZero() + return g2 +} + +// Generator returns the base point +func (g2 *G2) Generator() *G2 { + g2.x.Set(&g2x) + g2.y.Set(&g2y) + g2.z.SetOne() + return g2 +} + +// IsIdentity returns true if this point is at infinity +func (g2 *G2) IsIdentity() int { + return g2.z.IsZero() +} + +// IsOnCurve determines if this point represents a valid curve point +func (g2 *G2) IsOnCurve() int { + // Y^2 Z = X^3 + b Z^3 + var lhs, rhs, t fp2 + lhs.Square(&g2.y) + lhs.Mul(&lhs, &g2.z) + + rhs.Square(&g2.x) + rhs.Mul(&rhs, &g2.x) + t.Square(&g2.z) + t.Mul(&t, &g2.z) + t.Mul(&t, &curveG2B) + rhs.Add(&rhs, &t) + + return lhs.Equal(&rhs) +} + +// InCorrectSubgroup returns 1 if the point is torsion free, 0 otherwise +func (g2 *G2) InCorrectSubgroup() int { + var t G2 + t.multiply(g2, &fqModulusBytes) + return t.IsIdentity() +} + +// Add adds this point to another point. +func (g2 *G2) Add(arg1, arg2 *G2) *G2 { + // Algorithm 7, https://eprint.iacr.org/2015/1060.pdf + var t0, t1, t2, t3, t4, x3, y3, z3 fp2 + + t0.Mul(&arg1.x, &arg2.x) + t1.Mul(&arg1.y, &arg2.y) + t2.Mul(&arg1.z, &arg2.z) + t3.Add(&arg1.x, &arg1.y) + t4.Add(&arg2.x, &arg2.y) + t3.Mul(&t3, &t4) + t4.Add(&t0, &t1) + t3.Sub(&t3, &t4) + t4.Add(&arg1.y, &arg1.z) + x3.Add(&arg2.y, &arg2.z) + t4.Mul(&t4, &x3) + x3.Add(&t1, &t2) + t4.Sub(&t4, &x3) + x3.Add(&arg1.x, &arg1.z) + y3.Add(&arg2.x, &arg2.z) + x3.Mul(&x3, &y3) + y3.Add(&t0, &t2) + y3.Sub(&x3, &y3) + x3.Double(&t0) + t0.Add(&t0, &x3) + t2.MulBy3b(&t2) + z3.Add(&t1, &t2) + t1.Sub(&t1, &t2) + y3.MulBy3b(&y3) + x3.Mul(&t4, &y3) + t2.Mul(&t3, &t1) + x3.Sub(&t2, &x3) + y3.Mul(&y3, &t0) + t1.Mul(&t1, &z3) + y3.Add(&t1, &y3) + t0.Mul(&t0, &t3) + z3.Mul(&z3, &t4) + z3.Add(&z3, &t0) + + g2.x.Set(&x3) + g2.y.Set(&y3) + g2.z.Set(&z3) + return g2 +} + +// Sub subtracts the two points +func (g2 *G2) Sub(arg1, arg2 *G2) *G2 { + var t G2 + t.Neg(arg2) + return g2.Add(arg1, &t) +} + +// Double this point +func (g2 *G2) Double(a *G2) *G2 { + // Algorithm 9, https://eprint.iacr.org/2015/1060.pdf + var t0, t1, t2, x3, y3, z3 fp2 + + t0.Square(&a.y) + z3.Double(&t0) + z3.Double(&z3) + z3.Double(&z3) + t1.Mul(&a.y, &a.z) + t2.Square(&a.z) + t2.MulBy3b(&t2) + x3.Mul(&t2, &z3) + y3.Add(&t0, &t2) + z3.Mul(&t1, &z3) + t1.Double(&t2) + t2.Add(&t2, &t1) + t0.Sub(&t0, &t2) + y3.Mul(&t0, &y3) + y3.Add(&y3, &x3) + t1.Mul(&a.x, &a.y) + x3.Mul(&t0, &t1) + x3.Double(&x3) + + e := a.IsIdentity() + g2.x.CMove(&x3, t0.SetZero(), e) + g2.z.CMove(&z3, &t0, e) + g2.y.CMove(&y3, t0.SetOne(), e) + return g2 +} + +// Mul multiplies this point by the input scalar +func (g2 *G2) Mul(a *G2, s *native.Field) *G2 { + bytes := s.Bytes() + return g2.multiply(a, &bytes) +} + +func (g2 *G2) multiply(a *G2, bytes *[native.FieldBytes]byte) *G2 { + var p G2 + precomputed := [16]*G2{} + precomputed[0] = new(G2).Identity() + precomputed[1] = new(G2).Set(a) + for i := 2; i < 16; i += 2 { + precomputed[i] = new(G2).Double(precomputed[i>>1]) + precomputed[i+1] = new(G2).Add(precomputed[i], a) + } + p.Identity() + for i := 0; i < 256; i += 4 { + // Brouwer / windowing method. window size of 4. + for j := 0; j < 4; j++ { + p.Double(&p) + } + window := bytes[32-1-i>>3] >> (4 - i&0x04) & 0x0F + p.Add(&p, precomputed[window]) + } + return g2.Set(&p) +} + +// MulByX multiplies by BLS X using double and add +func (g2 *G2) MulByX(a *G2) *G2 { + // Skip first bit since its always zero + var s, t, r G2 + r.Identity() + t.Set(a) + + for x := paramX >> 1; x != 0; x >>= 1 { + t.Double(&t) + s.Add(&r, &t) + r.CMove(&r, &s, int(x&1)) + } + // Since BLS_X is negative, flip the sign + return g2.Neg(&r) +} + +// ClearCofactor using [Budroni-Pintore](https://ia.cr/2017/419). +// This is equivalent to multiplying by h_{eff} = 3(z^2 - 1) * h_2 +// where h_2 is the cofactor of G_2 and z is the parameter of BLS12-381. +func (g2 *G2) ClearCofactor(a *G2) *G2 { + var t1, t2, t3, pt G2 + + t1.MulByX(a) + t2.psi(a) + + pt.Double(a) + pt.psi2(&pt) + + t3.Add(&t1, &t2) + t3.MulByX(&t3) + + pt.Add(&pt, &t3) + pt.Sub(&pt, &t1) + pt.Sub(&pt, &t2) + pt.Sub(&pt, a) + return g2.Set(&pt) +} + +// Neg negates this point +func (g2 *G2) Neg(a *G2) *G2 { + g2.Set(a) + g2.y.CNeg(&a.y, -(a.IsIdentity() - 1)) + return g2 +} + +// Set copies a into g2 +func (g2 *G2) Set(a *G2) *G2 { + g2.x.Set(&a.x) + g2.y.Set(&a.y) + g2.z.Set(&a.z) + return g2 +} + +// BigInt returns the x and y as big.Ints in affine +func (g2 *G2) BigInt() (x, y *big.Int) { + var t G2 + out := t.ToUncompressed() + x = new(big.Int).SetBytes(out[:WideFieldBytes]) + y = new(big.Int).SetBytes(out[WideFieldBytes:]) + return +} + +// SetBigInt creates a point from affine x, y +// and returns the point if it is on the curve +func (g2 *G2) SetBigInt(x, y *big.Int) (*G2, error) { + var tt [DoubleWideFieldBytes]byte + + if len(x.Bytes()) == 0 && len(y.Bytes()) == 0 { + return g2.Identity(), nil + } + x.FillBytes(tt[:WideFieldBytes]) + y.FillBytes(tt[WideFieldBytes:]) + + return g2.FromUncompressed(&tt) +} + +// ToCompressed serializes this element into compressed form. +func (g2 *G2) ToCompressed() [WideFieldBytes]byte { + var out [WideFieldBytes]byte + var t G2 + t.ToAffine(g2) + xABytes := t.x.A.Bytes() + xBBytes := t.x.B.Bytes() + copy(out[:FieldBytes], internal.ReverseScalarBytes(xBBytes[:])) + copy(out[FieldBytes:], internal.ReverseScalarBytes(xABytes[:])) + isInfinity := byte(g2.IsIdentity()) + // Compressed flag + out[0] |= 1 << 7 + // Is infinity + out[0] |= (1 << 6) & -isInfinity + // Sign of y only set if not infinity + out[0] |= (byte(t.y.LexicographicallyLargest()) << 5) & (isInfinity - 1) + return out +} + +// FromCompressed deserializes this element from compressed form. +func (g2 *G2) FromCompressed(input *[WideFieldBytes]byte) (*G2, error) { + var xFp, yFp fp2 + var xA, xB [FieldBytes]byte + var p G2 + compressedFlag := int((input[0] >> 7) & 1) + infinityFlag := int((input[0] >> 6) & 1) + sortFlag := int((input[0] >> 5) & 1) + + if compressedFlag != 1 { + return nil, errors.New("compressed flag must be set") + } + + if infinityFlag == 1 { + return g2.Identity(), nil + } + + copy(xB[:], internal.ReverseScalarBytes(input[:FieldBytes])) + copy(xA[:], internal.ReverseScalarBytes(input[FieldBytes:])) + // Mask away the flag bits + xB[FieldBytes-1] &= 0x1F + _, validA := xFp.A.SetBytes(&xA) + _, validB := xFp.B.SetBytes(&xB) + + if validA&validB != 1 { + return nil, errors.New("invalid bytes - not in field") + } + + // Recover a y-coordinate given x by y = sqrt(x^3 + 4) + yFp.Square(&xFp) + yFp.Mul(&yFp, &xFp) + yFp.Add(&yFp, &curveG2B) + + _, wasSquare := yFp.Sqrt(&yFp) + if wasSquare != 1 { + return nil, errors.New("point is not on the curve") + } + + yFp.CNeg(&yFp, yFp.LexicographicallyLargest()^sortFlag) + p.x.Set(&xFp) + p.y.Set(&yFp) + p.z.SetOne() + if p.InCorrectSubgroup() == 0 { + return nil, errors.New("point is not in correct subgroup") + } + return g2.Set(&p), nil +} + +// ToUncompressed serializes this element into uncompressed form. +func (g2 *G2) ToUncompressed() [DoubleWideFieldBytes]byte { + var out [DoubleWideFieldBytes]byte + var t G2 + t.ToAffine(g2) + bytes := t.x.B.Bytes() + copy(out[:FieldBytes], internal.ReverseScalarBytes(bytes[:])) + bytes = t.x.A.Bytes() + copy(out[FieldBytes:WideFieldBytes], internal.ReverseScalarBytes(bytes[:])) + bytes = t.y.B.Bytes() + copy(out[WideFieldBytes:WideFieldBytes+FieldBytes], internal.ReverseScalarBytes(bytes[:])) + bytes = t.y.A.Bytes() + copy(out[WideFieldBytes+FieldBytes:], internal.ReverseScalarBytes(bytes[:])) + isInfinity := byte(g2.IsIdentity()) + out[0] |= (1 << 6) & -isInfinity + return out +} + +// FromUncompressed deserializes this element from uncompressed form. +func (g2 *G2) FromUncompressed(input *[DoubleWideFieldBytes]byte) (*G2, error) { + var a, b fp + var t [FieldBytes]byte + var p G2 + infinityFlag := int((input[0] >> 6) & 1) + + if infinityFlag == 1 { + return g2.Identity(), nil + } + + copy(t[:], internal.ReverseScalarBytes(input[:FieldBytes])) + // Mask away top bits + t[FieldBytes-1] &= 0x1F + + _, valid := b.SetBytes(&t) + if valid == 0 { + return nil, errors.New("invalid bytes - x.B not in field") + } + copy(t[:], internal.ReverseScalarBytes(input[FieldBytes:WideFieldBytes])) + _, valid = a.SetBytes(&t) + if valid == 0 { + return nil, errors.New("invalid bytes - x.A not in field") + } + + p.x.B.Set(&b) + p.x.A.Set(&a) + + copy(t[:], internal.ReverseScalarBytes(input[WideFieldBytes:WideFieldBytes+FieldBytes])) + _, valid = b.SetBytes(&t) + if valid == 0 { + return nil, errors.New("invalid bytes - y.B not in field") + } + copy(t[:], internal.ReverseScalarBytes(input[FieldBytes+WideFieldBytes:])) + _, valid = a.SetBytes(&t) + if valid == 0 { + return nil, errors.New("invalid bytes - y.A not in field") + } + + p.y.B.Set(&b) + p.y.A.Set(&a) + p.z.SetOne() + + if p.IsOnCurve() == 0 { + return nil, errors.New("point is not on the curve") + } + if p.InCorrectSubgroup() == 0 { + return nil, errors.New("point is not in correct subgroup") + } + return g2.Set(&p), nil +} + +// ToAffine converts the point into affine coordinates +func (g2 *G2) ToAffine(a *G2) *G2 { + var wasInverted int + var zero, x, y, z fp2 + _, wasInverted = z.Invert(&a.z) + x.Mul(&a.x, &z) + y.Mul(&a.y, &z) + + g2.x.CMove(&zero, &x, wasInverted) + g2.y.CMove(&zero, &y, wasInverted) + g2.z.CMove(&zero, z.SetOne(), wasInverted) + return g2 +} + +// GetX returns the affine X coordinate +func (g2 *G2) GetX() *fp2 { + var t G2 + t.ToAffine(g2) + return &t.x +} + +// GetY returns the affine Y coordinate +func (g2 *G2) GetY() *fp2 { + var t G2 + t.ToAffine(g2) + return &t.y +} + +// Equal returns 1 if the two points are equal 0 otherwise. +func (g2 *G2) Equal(rhs *G2) int { + var x1, x2, y1, y2 fp2 + var e1, e2 int + + // This technique avoids inversions + x1.Mul(&g2.x, &rhs.z) + x2.Mul(&rhs.x, &g2.z) + + y1.Mul(&g2.y, &rhs.z) + y2.Mul(&rhs.y, &g2.z) + + e1 = g2.z.IsZero() + e2 = rhs.z.IsZero() + + // Both at infinity or coordinates are the same + return (e1 & e2) | (^e1 & ^e2)&x1.Equal(&x2)&y1.Equal(&y2) +} + +// CMove sets g2 = arg1 if choice == 0 and g2 = arg2 if choice == 1 +func (g2 *G2) CMove(arg1, arg2 *G2, choice int) *G2 { + g2.x.CMove(&arg1.x, &arg2.x, choice) + g2.y.CMove(&arg1.y, &arg2.y, choice) + g2.z.CMove(&arg1.z, &arg2.z, choice) + return g2 +} + +// SumOfProducts computes the multi-exponentiation for the specified +// points and scalars and stores the result in `g2`. +// Returns an error if the lengths of the arguments is not equal. +func (g2 *G2) SumOfProducts(points []*G2, scalars []*native.Field) (*G2, error) { + const Upper = 256 + const W = 4 + const Windows = Upper / W // careful--use ceiling division in case this doesn't divide evenly + var sum G2 + if len(points) != len(scalars) { + return nil, fmt.Errorf("length mismatch") + } + + bucketSize := 1 << W + windows := make([]G2, Windows) + bytes := make([][32]byte, len(scalars)) + buckets := make([]G2, bucketSize) + for i := 0; i < len(windows); i++ { + windows[i].Identity() + } + + for i, scalar := range scalars { + bytes[i] = scalar.Bytes() + } + + for j := 0; j < len(windows); j++ { + for i := 0; i < bucketSize; i++ { + buckets[i].Identity() + } + + for i := 0; i < len(scalars); i++ { + // j*W to get the nibble + // >> 3 to convert to byte, / 8 + // (W * j & W) gets the nibble, mod W + // 1 << W - 1 to get the offset + index := bytes[i][j*W>>3] >> (W * j & W) & (1< 0; i-- { + sum.Add(&sum, &buckets[i]) + windows[j].Add(&windows[j], &sum) + } + } + + g2.Identity() + for i := len(windows) - 1; i >= 0; i-- { + for j := 0; j < W; j++ { + g2.Double(g2) + } + + g2.Add(g2, &windows[i]) + } + return g2, nil +} + +func (g2 *G2) psi(a *G2) *G2 { + g2.x.FrobeniusMap(&a.x) + g2.y.FrobeniusMap(&a.y) + // z = frobenius(z) + g2.z.FrobeniusMap(&a.z) + + // x = frobenius(x)/((u+1)^((p-1)/3)) + g2.x.Mul(&g2.x, &psiCoeffX) + // y = frobenius(y)/(u+1)^((p-1)/2) + g2.y.Mul(&g2.y, &psiCoeffY) + + return g2 +} + +func (g2 *G2) psi2(a *G2) *G2 { + // x = frobenius^2(x)/2^((p-1)/3); note that q^2 is the order of the field. + g2.x.Mul(&a.x, &psi2CoeffX) + // y = -frobenius^2(y); note that q^2 is the order of the field. + g2.y.Neg(&a.y) + g2.z.Set(&a.z) + return g2 +} + +func (g2 *G2) sswu(u *fp2) *G2 { + /// simplified swu map for q = 9 mod 16 where AB == 0 + // + var tv1, tv2, x1, x2, gx1, gx2, x, y, y2, t fp2 + + tv1.Square(u) + tv1.Mul(&tv1, &sswuMapZ) + + tv2.Square(&tv1) + + x1.Add(&tv1, &tv2) + x1.Invert(&x1) + x1.Add(&x1, (&fp2{}).SetOne()) + x1.CMove(&x1, &sswuMapZInv, x1.IsZero()) + x1.Mul(&x1, &swwuMapMbDivA) + + gx1.Square(&x1) + gx1.Add(&gx1, &sswuMapA) + gx1.Mul(&gx1, &x1) + gx1.Add(&gx1, &sswuMapB) + + x2.Mul(&tv1, &x1) + + tv2.Mul(&tv2, &tv1) + + gx2.Mul(&gx1, &tv2) + + _, e2 := t.Sqrt(&gx1) + + x.CMove(&x2, &x1, e2) + y2.CMove(&gx2, &gx1, e2) + + y.Sqrt(&y2) + + y.CNeg(&y, u.Sgn0()^y.Sgn0()) + g2.x.Set(&x) + g2.y.Set(&y) + g2.z.SetOne() + return g2 +} + +func (g2 *G2) isogenyMap(a *G2) *G2 { + const Degree = 4 + var xs [Degree]fp2 + xs[0].SetOne() + xs[1].Set(&a.x) + xs[2].Square(&a.x) + for i := 3; i < Degree; i++ { + xs[i].Mul(&xs[i-1], &a.x) + } + + xNum := computeKFp2(xs[:], g2IsoXNum) + xDen := computeKFp2(xs[:], g2IsoXDen) + yNum := computeKFp2(xs[:], g2IsoYNum) + yDen := computeKFp2(xs[:], g2IsoYDen) + + g2.x.Invert(&xDen) + g2.x.Mul(&g2.x, &xNum) + + g2.y.Invert(&yDen) + g2.y.Mul(&g2.y, &yNum) + g2.y.Mul(&g2.y, &a.y) + g2.z.SetOne() + return g2 +} + +func computeKFp2(xxs []fp2, k []fp2) fp2 { + var xx, t fp2 + for i := range k { + xx.Add(&xx, t.Mul(&xxs[i], &k[i])) + } + return xx +} diff --git a/pkg/crypto/core/curves/native/bls12381/g2_test.go b/pkg/crypto/core/curves/native/bls12381/g2_test.go new file mode 100755 index 000000000..cfdcf128d --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/g2_test.go @@ -0,0 +1,554 @@ +package bls12381 + +import ( + crand "crypto/rand" + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +func TestG2IsOnCurve(t *testing.T) { + require.Equal(t, 1, new(G2).Identity().IsOnCurve()) + require.Equal(t, 1, new(G2).Generator().IsOnCurve()) + + z := fp2{ + A: fp{ + 0xba7a_fa1f_9a6f_e250, + 0xfa0f_5b59_5eaf_e731, + 0x3bdc_4776_94c3_06e7, + 0x2149_be4b_3949_fa24, + 0x64aa_6e06_49b2_078c, + 0x12b1_08ac_3364_3c3e, + }, + B: fp{ + 0x1253_25df_3d35_b5a8, + 0xdc46_9ef5_555d_7fe3, + 0x02d7_16d2_4431_06a9, + 0x05a1_db59_a6ff_37d0, + 0x7cf7_784e_5300_bb8f, + 0x16a8_8922_c7a5_e844, + }, + } + + test := new(G2).Generator() + test.x.Mul(&test.x, &z) + test.y.Mul(&test.y, &z) + test.z.Set(&z) + + require.Equal(t, 1, test.IsOnCurve()) + + test.x.Set(&z) + require.Equal(t, 0, test.IsOnCurve()) +} + +func TestG2Equal(t *testing.T) { + a := new(G2).Generator() + b := new(G2).Identity() + + require.Equal(t, 1, a.Equal(a)) + require.Equal(t, 0, a.Equal(b)) + require.Equal(t, 1, b.Equal(b)) +} + +func TestG2ToAffine(t *testing.T) { + a := new(G2).Generator() + + z := fp2{ + A: fp{ + 0xba7afa1f9a6fe250, + 0xfa0f5b595eafe731, + 0x3bdc477694c306e7, + 0x2149be4b3949fa24, + 0x64aa6e0649b2078c, + 0x12b108ac33643c3e, + }, + B: fp{ + 0x125325df3d35b5a8, + 0xdc469ef5555d7fe3, + 0x02d716d2443106a9, + 0x05a1db59a6ff37d0, + 0x7cf7784e5300bb8f, + 0x16a88922c7a5e844, + }, + } + + a.x.Mul(&a.x, &z) + a.y.Mul(&a.y, &z) + a.z.Set(&z) + + require.Equal(t, 1, a.ToAffine(a).Equal(new(G2).Generator())) +} + +func TestG2Double(t *testing.T) { + a := new(G2).Identity() + require.Equal(t, 1, a.Double(a).IsIdentity()) + + a.Generator() + a.Double(a) + e := G2{ + x: fp2{ + A: fp{ + 0xe9d9e2da9620f98b, + 0x54f1199346b97f36, + 0x3db3b820376bed27, + 0xcfdb31c9b0b64f4c, + 0x41d7c12786354493, + 0x05710794c255c064, + }, + B: fp{ + 0xd6c1d3ca6ea0d06e, + 0xda0cbd905595489f, + 0x4f5352d43479221d, + 0x8ade5d736f8c97e0, + 0x48cc8433925ef70e, + 0x08d7ea71ea91ef81, + }, + }, + y: fp2{ + A: fp{ + 0x15ba26eb4b0d186f, + 0x0d086d64b7e9e01e, + 0xc8b848dd652f4c78, + 0xeecf46a6123bae4f, + 0x255e8dd8b6dc812a, + 0x164142af21dcf93f, + }, + B: fp{ + 0xf9b4a1a895984db4, + 0xd417b114cccff748, + 0x6856301fc89f086e, + 0x41c777878931e3da, + 0x3556b155066a2105, + 0x00acf7d325cb89cf, + }, + }, + z: *((&fp2{}).SetOne()), + } + require.Equal(t, 1, e.Equal(a)) +} + +func TestG2Add(t *testing.T) { + a := new(G2).Identity() + b := new(G2).Identity() + c := new(G2).Add(a, b) + require.Equal(t, 1, c.IsIdentity()) + b.Generator() + c.Add(a, b) + require.Equal(t, 1, c.Equal(b)) + + a.Generator() + a.Double(a) + a.Double(a) + b.Double(b) + c.Add(a, b) + + d := new(G2).Generator() + e := new(G2).Generator() + for i := 0; i < 5; i++ { + e.Add(e, d) + } + require.Equal(t, 1, e.Equal(c)) + + // Degenerate case + beta := fp2{ + A: fp{ + 0xcd03c9e48671f071, + 0x5dab22461fcda5d2, + 0x587042afd3851b95, + 0x8eb60ebe01bacb9e, + 0x03f97d6e83d050d2, + 0x18f0206554638741, + }, + B: fp{}, + } + beta.Square(&beta) + b.x.Mul(&a.x, &beta) + b.y.Neg(&a.y) + b.z.Set(&a.z) + require.Equal(t, 1, b.IsOnCurve()) + + c.Add(a, b) + + e.x.Set(&fp2{ + A: fp{ + 0x705abc799ca773d3, + 0xfe132292c1d4bf08, + 0xf37ece3e07b2b466, + 0x887e1c43f447e301, + 0x1e0970d033bc77e8, + 0x1985c81e20a693f2, + }, + B: fp{ + 0x1d79b25db36ab924, + 0x23948e4d529639d3, + 0x471ba7fb0d006297, + 0x2c36d4b4465dc4c0, + 0x82bbc3cfec67f538, + 0x051d2728b67bf952, + }, + }) + e.y.Set(&fp2{ + A: fp{ + 0x41b1bbf6576c0abf, + 0xb6cc93713f7a0f9a, + 0x6b65b43e48f3f01f, + 0xfb7a4cfcaf81be4f, + 0x3e32dadc6ec22cb6, + 0x0bb0fc49d79807e3, + }, + B: fp{ + 0x7d1397788f5f2ddf, + 0xab2907144ff0d8e8, + 0x5b7573e0cdb91f92, + 0x4cb8932dd31daf28, + 0x62bbfac6db052a54, + 0x11f95c16d14c3bbe, + }, + }) + e.z.SetOne() + require.Equal(t, 1, e.Equal(c)) +} + +func TestG2Neg(t *testing.T) { + a := new(G2).Generator() + b := new(G2).Neg(a) + require.Equal(t, 1, new(G2).Add(a, b).IsIdentity()) + require.Equal(t, 1, new(G2).Sub(a, b.Neg(b)).IsIdentity()) + a.Identity() + require.Equal(t, 1, a.Neg(a).IsIdentity()) +} + +func TestG2Mul(t *testing.T) { + g := new(G2).Generator() + a := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{ + 0x2b56_8297_a56d_a71c, + 0xd8c3_9ecb_0ef3_75d1, + 0x435c_38da_67bf_bf96, + 0x8088_a050_26b6_59b2, + }) + b := Bls12381FqNew().SetRaw(&[native.FieldLimbs]uint64{ + 0x785f_dd9b_26ef_8b85, + 0xc997_f258_3769_5c18, + 0x4c8d_bc39_e7b7_56c1, + 0x70d9_b6cc_6d87_df20, + }) + c := Bls12381FqNew().Mul(a, b) + + t1 := new(G2).Generator() + t1.Mul(t1, a) + t1.Mul(t1, b) + require.Equal(t, 1, t1.Equal(g.Mul(g, c))) +} + +func TestG2InCorrectSubgroup(t *testing.T) { + a := G2{ + x: fp2{ + A: fp{ + 0x89f550c813db6431, + 0xa50be8c456cd8a1a, + 0xa45b374114cae851, + 0xbb6190f5bf7fff63, + 0x970ca02c3ba80bc7, + 0x02b85d24e840fbac, + }, + B: fp{ + 0x6888bc53d70716dc, + 0x3dea6b4117682d70, + 0xd8f5f930500ca354, + 0x6b5ecb6556f5c155, + 0xc96bef0434778ab0, + 0x05081505515006ad, + }, + }, + y: fp2{ + A: fp{ + 0x3cf1ea0d434b0f40, + 0x1a0dc610e603e333, + 0x7f89956160c72fa0, + 0x25ee03decf6431c5, + 0xeee8e206ec0fe137, + 0x097592b226dfef28, + }, + B: fp{ + 0x71e8bb5f29247367, + 0xa5fe049e211831ce, + 0x0ce6b354502a3896, + 0x93b012000997314e, + 0x6759f3b6aa5b42ac, + 0x156944c4dfe92bbb, + }, + }, + z: *(&fp2{}).SetOne(), + } + require.Equal(t, 0, a.InCorrectSubgroup()) + + require.Equal(t, 1, new(G2).Identity().InCorrectSubgroup()) + require.Equal(t, 1, new(G2).Generator().InCorrectSubgroup()) +} + +func TestG2MulByX(t *testing.T) { + // multiplying by `x` a point in G2 is the same as multiplying by + // the equivalent scalar. + x := Bls12381FqNew().SetUint64(paramX) + x.Neg(x) + t1 := new(G2).Generator() + t1.MulByX(t1) + t2 := new(G2).Generator() + t2.Mul(t2, x) + require.Equal(t, 1, t1.Equal(t2)) + + point := new(G2).Generator() + a := Bls12381FqNew().SetUint64(42) + point.Mul(point, a) + + t1.MulByX(point) + t2.Mul(point, x) + require.Equal(t, 1, t1.Equal(t2)) +} + +func TestG2Psi(t *testing.T) { + generator := new(G2).Generator() + + z := fp2{ + A: fp{ + 0x0ef2ddffab187c0a, + 0x2424522b7d5ecbfc, + 0xc6f341a3398054f4, + 0x5523ddf409502df0, + 0xd55c0b5a88e0dd97, + 0x066428d704923e52, + }, + B: fp{ + 0x538bbe0c95b4878d, + 0xad04a50379522881, + 0x6d5c05bf5c12fb64, + 0x4ce4a069a2d34787, + 0x59ea6c8d0dffaeaf, + 0x0d42a083a75bd6f3, + }, + } + + // `point` is a random point in the curve + point := G2{ + x: fp2{ + A: fp{ + 0xee4c8cb7c047eaf2, + 0x44ca22eee036b604, + 0x33b3affb2aefe101, + 0x15d3e45bbafaeb02, + 0x7bfc2154cd7419a4, + 0x0a2d0c2b756e5edc, + }, + B: fp{ + 0xfc224361029a8777, + 0x4cbf2baab8740924, + 0xc5008c6ec6592c89, + 0xecc2c57b472a9c2d, + 0x8613eafd9d81ffb1, + 0x10fe54daa2d3d495, + }, + }, + y: fp2{ + A: fp{ + 0x7de7edc43953b75c, + 0x58be1d2de35e87dc, + 0x5731d30b0e337b40, + 0xbe93b60cfeaae4c9, + 0x8b22c203764bedca, + 0x01616c8d1033b771, + }, + B: fp{ + 0xea126fe476b5733b, + 0x85cee68b5dae1652, + 0x98247779f7272b04, + 0xa649c8b468c6e808, + 0xb5b9a62dff0c4e45, + 0x1555b67fc7bbe73d, + }, + }, + z: *(&fp2{}).Set(&z), + } + point.x.Mul(&point.x, &z) + point.z.Square(&point.z) + point.z.Mul(&point.z, &z) + require.Equal(t, 1, point.IsOnCurve()) + + // psi2(P) = psi(psi(P)) + tv1 := new(G2).psi2(generator) + tv2 := new(G2).psi(generator) + tv2.psi(tv2) + require.Equal(t, 1, tv1.Equal(tv2)) + + tv1.psi2(&point) + tv2.psi(&point) + tv2.psi(tv2) + require.Equal(t, 1, tv1.Equal(tv2)) + + // psi(P) is a morphism + tv1.Double(generator) + tv1.psi(tv1) + tv2.psi(generator) + tv2.Double(tv2) + require.Equal(t, 1, tv1.Equal(tv2)) + + tv1.psi(&point) + tv2.psi(generator) + tv1.Add(tv1, tv2) + + tv2.Set(&point) + tv3 := new(G2).Generator() + tv2.Add(tv2, tv3) + tv2.psi(tv2) + require.Equal(t, 1, tv1.Equal(tv2)) +} + +func TestG2ClearCofactor(t *testing.T) { + z := fp2{ + A: fp{ + 0x0ef2ddffab187c0a, + 0x2424522b7d5ecbfc, + 0xc6f341a3398054f4, + 0x5523ddf409502df0, + 0xd55c0b5a88e0dd97, + 0x066428d704923e52, + }, + B: fp{ + 0x538bbe0c95b4878d, + 0xad04a50379522881, + 0x6d5c05bf5c12fb64, + 0x4ce4a069a2d34787, + 0x59ea6c8d0dffaeaf, + 0x0d42a083a75bd6f3, + }, + } + + // `point` is a random point in the curve + point := G2{ + x: fp2{ + A: fp{ + 0xee4c8cb7c047eaf2, + 0x44ca22eee036b604, + 0x33b3affb2aefe101, + 0x15d3e45bbafaeb02, + 0x7bfc2154cd7419a4, + 0x0a2d0c2b756e5edc, + }, + B: fp{ + 0xfc224361029a8777, + 0x4cbf2baab8740924, + 0xc5008c6ec6592c89, + 0xecc2c57b472a9c2d, + 0x8613eafd9d81ffb1, + 0x10fe54daa2d3d495, + }, + }, + y: fp2{ + A: fp{ + 0x7de7edc43953b75c, + 0x58be1d2de35e87dc, + 0x5731d30b0e337b40, + 0xbe93b60cfeaae4c9, + 0x8b22c203764bedca, + 0x01616c8d1033b771, + }, + B: fp{ + 0xea126fe476b5733b, + 0x85cee68b5dae1652, + 0x98247779f7272b04, + 0xa649c8b468c6e808, + 0xb5b9a62dff0c4e45, + 0x1555b67fc7bbe73d, + }, + }, + z: fp2{}, + } + point.x.Mul(&point.x, &z) + point.z.Square(&z) + point.z.Mul(&point.z, &z) + + require.Equal(t, 1, point.IsOnCurve()) + require.Equal(t, 0, point.InCorrectSubgroup()) + + clearedPoint := new(G2).ClearCofactor(&point) + + require.Equal(t, 1, clearedPoint.IsOnCurve()) + require.Equal(t, 1, clearedPoint.InCorrectSubgroup()) + + // the generator (and the identity) are always on the curve, + // even after clearing the cofactor + generator := new(G2).Generator() + generator.ClearCofactor(generator) + require.Equal(t, 1, generator.InCorrectSubgroup()) + id := new(G2).Identity() + id.ClearCofactor(id) + require.Equal(t, 1, id.InCorrectSubgroup()) + + // test the effect on q-torsion points multiplying by h_eff modulo q + // h_eff % q = 0x2b116900400069009a40200040001ffff + hEffModq := [native.FieldBytes]byte{ + 0xff, 0xff, 0x01, 0x00, 0x04, 0x00, 0x02, 0xa4, 0x09, 0x90, 0x06, 0x00, 0x04, 0x90, 0x16, + 0xb1, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + } + generator.Generator() + generator.multiply(generator, &hEffModq) + point.Generator().ClearCofactor(&point) + require.Equal(t, 1, point.Equal(generator)) + point.ClearCofactor(clearedPoint) + require.Equal(t, 1, point.Equal(clearedPoint.multiply(clearedPoint, &hEffModq))) +} + +func TestG2Hash(t *testing.T) { + dst := []byte("QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_") + + tests := []struct { + input, expected string + }{ + {"", "05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d60503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92"}, + {"abc", "139cddbccdc5e91b9623efd38c49f81a6f83f175e80b06fc374de9eb4b41dfe4ca3a230ed250fbe3a2acf73a41177fd802c2d18e033b960562aae3cab37a27ce00d80ccd5ba4b7fe0e7a210245129dbec7780ccc7954725f4168aff2787776e600aa65dae3c8d732d10ecd2c50f8a1baf3001578f71c694e03866e9f3d49ac1e1ce70dd94a733534f106d4cec0eddd161787327b68159716a37440985269cf584bcb1e621d3a7202be6ea05c4cfe244aeb197642555a0645fb87bf7466b2ba48"}, + {"abcdef0123456789", "190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd00bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8"}, + {"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", "0934aba516a52d8ae479939a91998299c76d39cc0c035cd18813bec433f587e2d7a4fef038260eef0cef4d02aae3eb9119a84dd7248a1066f737cc34502ee5555bd3c19f2ecdb3c7d9e24dc65d4e25e50d83f0f77105e955d78f4762d33c17da09bcccfa036b4847c9950780733633f13619994394c23ff0b32fa6b795844f4a0673e20282d07bc69641cee04f5e566214f81cd421617428bc3b9fe25afbb751d934a00493524bc4e065635b0555084dd54679df1536101b2c979c0152d09192"}, + {"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "11fca2ff525572795a801eed17eb12785887c7b63fb77a42be46ce4a34131d71f7a73e95fee3f812aea3de78b4d0156901a6ba2f9a11fa5598b2d8ace0fbe0a0eacb65deceb476fbbcb64fd24557c2f4b18ecfc5663e54ae16a84f5ab7f6253403a47f8e6d1763ba0cad63d6114c0accbef65707825a511b251a660a9b3994249ae4e63fac38b23da0c398689ee2ab520b6798718c8aed24bc19cb27f866f1c9effcdbf92397ad6448b5c9db90d2b9da6cbabf48adc1adf59a1a28344e79d57e"}, + } + + pt := new(G2).Identity() + ept := new(G2).Identity() + var b [DoubleWideFieldBytes]byte + for _, tst := range tests { + i := []byte(tst.input) + e, _ := hex.DecodeString(tst.expected) + copy(b[:], e) + _, _ = ept.FromUncompressed(&b) + pt.Hash(native.EllipticPointHasherSha256(), i, dst) + require.Equal(t, 1, pt.Equal(ept)) + } +} + +func TestG2SumOfProducts(t *testing.T) { + var b [64]byte + h0, _ := new(G2).Random(crand.Reader) + _, _ = crand.Read(b[:]) + s := Bls12381FqNew().SetBytesWide(&b) + _, _ = crand.Read(b[:]) + sTilde := Bls12381FqNew().SetBytesWide(&b) + _, _ = crand.Read(b[:]) + c := Bls12381FqNew().SetBytesWide(&b) + + lhs := new(G2).Mul(h0, s) + rhs, _ := new(G2).SumOfProducts([]*G2{h0}, []*native.Field{s}) + require.Equal(t, 1, lhs.Equal(rhs)) + + u := new(G2).Mul(h0, s) + uTilde := new(G2).Mul(h0, sTilde) + sHat := Bls12381FqNew().Mul(c, s) + sHat.Sub(sTilde, sHat) + + rhs.Mul(u, c) + rhs.Add(rhs, new(G2).Mul(h0, sHat)) + require.Equal(t, 1, uTilde.Equal(rhs)) + _, _ = rhs.SumOfProducts([]*G2{u, h0}, []*native.Field{c, sHat}) + require.Equal(t, 1, uTilde.Equal(rhs)) +} diff --git a/pkg/crypto/core/curves/native/bls12381/gt.go b/pkg/crypto/core/curves/native/bls12381/gt.go new file mode 100755 index 000000000..5c48d5179 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/gt.go @@ -0,0 +1,434 @@ +package bls12381 + +import ( + "io" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// GtFieldBytes is the number of bytes needed to represent this field +const GtFieldBytes = 576 + +// Gt is the target group +type Gt fp12 + +// Random generates a random field element +func (gt *Gt) Random(reader io.Reader) (*Gt, error) { + _, err := (*fp12)(gt).Random(reader) + return gt, err +} + +// FinalExponentiation performs a "final exponentiation" routine to convert the result +// of a Miller loop into an element of `Gt` with help of efficient squaring +// operation in the so-called `cyclotomic subgroup` of `Fq6` so that +// it can be compared with other elements of `Gt`. +func (gt *Gt) FinalExponentiation(a *Gt) *Gt { + var t0, t1, t2, t3, t4, t5, t6, t fp12 + t0.FrobeniusMap((*fp12)(a)) + t0.FrobeniusMap(&t0) + t0.FrobeniusMap(&t0) + t0.FrobeniusMap(&t0) + t0.FrobeniusMap(&t0) + t0.FrobeniusMap(&t0) + + // Shouldn't happen since we enforce `a` to be non-zero but just in case + _, wasInverted := t1.Invert((*fp12)(a)) + t2.Mul(&t0, &t1) + t1.Set(&t2) + t2.FrobeniusMap(&t2) + t2.FrobeniusMap(&t2) + t2.Mul(&t2, &t1) + t1.cyclotomicSquare(&t2) + t1.Conjugate(&t1) + + t3.cyclotomicExp(&t2) + t4.cyclotomicSquare(&t3) + t5.Mul(&t1, &t3) + t1.cyclotomicExp(&t5) + t0.cyclotomicExp(&t1) + t6.cyclotomicExp(&t0) + t6.Mul(&t6, &t4) + t4.cyclotomicExp(&t6) + t5.Conjugate(&t5) + t4.Mul(&t4, &t5) + t4.Mul(&t4, &t2) + t5.Conjugate(&t2) + t1.Mul(&t1, &t2) + t1.FrobeniusMap(&t1) + t1.FrobeniusMap(&t1) + t1.FrobeniusMap(&t1) + t6.Mul(&t6, &t5) + t6.FrobeniusMap(&t6) + t3.Mul(&t3, &t0) + t3.FrobeniusMap(&t3) + t3.FrobeniusMap(&t3) + t3.Mul(&t3, &t1) + t3.Mul(&t3, &t6) + t.Mul(&t3, &t4) + (*fp12)(gt).CMove((*fp12)(gt), &t, wasInverted) + return gt +} + +// IsZero returns 1 if gt == 0, 0 otherwise +func (gt *Gt) IsZero() int { + return (*fp12)(gt).IsZero() +} + +// IsOne returns 1 if gt == 1, 0 otherwise +func (gt *Gt) IsOne() int { + return (*fp12)(gt).IsOne() +} + +// SetOne gt = one +func (gt *Gt) SetOne() *Gt { + (*fp12)(gt).SetOne() + return gt +} + +// Set copies a into gt +func (gt *Gt) Set(a *Gt) *Gt { + gt.A.Set(&a.A) + gt.B.Set(&a.B) + return gt +} + +// Bytes returns the Gt field byte representation +func (gt *Gt) Bytes() [GtFieldBytes]byte { + var out [GtFieldBytes]byte + t := gt.A.A.A.Bytes() + copy(out[:FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.A.A.B.Bytes() + copy(out[FieldBytes:2*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.A.B.A.Bytes() + copy(out[2*FieldBytes:3*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.A.B.B.Bytes() + copy(out[3*FieldBytes:4*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.A.C.A.Bytes() + copy(out[4*FieldBytes:5*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.A.C.B.Bytes() + copy(out[5*FieldBytes:6*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.B.A.A.Bytes() + copy(out[6*FieldBytes:7*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.B.A.B.Bytes() + copy(out[7*FieldBytes:8*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.B.B.A.Bytes() + copy(out[8*FieldBytes:9*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.B.B.B.Bytes() + copy(out[9*FieldBytes:10*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.B.C.A.Bytes() + copy(out[10*FieldBytes:11*FieldBytes], internal.ReverseScalarBytes(t[:])) + t = gt.B.C.B.Bytes() + copy(out[11*FieldBytes:12*FieldBytes], internal.ReverseScalarBytes(t[:])) + + return out +} + +// SetBytes attempts to convert a big-endian byte representation of +// a scalar into a `Gt`, failing if the input is not canonical. +func (gt *Gt) SetBytes(input *[GtFieldBytes]byte) (*Gt, int) { + var t [FieldBytes]byte + var valid [12]int + copy(t[:], internal.ReverseScalarBytes(input[:FieldBytes])) + _, valid[0] = gt.A.A.A.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[FieldBytes:2*FieldBytes])) + _, valid[1] = gt.A.A.B.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[2*FieldBytes:3*FieldBytes])) + _, valid[2] = gt.A.B.A.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[3*FieldBytes:4*FieldBytes])) + _, valid[3] = gt.A.B.B.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[4*FieldBytes:5*FieldBytes])) + _, valid[4] = gt.A.C.A.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[5*FieldBytes:6*FieldBytes])) + _, valid[5] = gt.A.C.B.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[6*FieldBytes:7*FieldBytes])) + _, valid[6] = gt.B.A.A.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[7*FieldBytes:8*FieldBytes])) + _, valid[7] = gt.B.A.B.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[8*FieldBytes:9*FieldBytes])) + _, valid[8] = gt.B.B.A.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[9*FieldBytes:10*FieldBytes])) + _, valid[9] = gt.B.B.B.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[10*FieldBytes:11*FieldBytes])) + _, valid[10] = gt.B.C.A.SetBytes(&t) + copy(t[:], internal.ReverseScalarBytes(input[11*FieldBytes:12*FieldBytes])) + _, valid[11] = gt.B.C.B.SetBytes(&t) + + return gt, valid[0] & valid[1] & + valid[2] & valid[3] & + valid[4] & valid[5] & + valid[6] & valid[7] & + valid[8] & valid[9] & + valid[10] & valid[11] +} + +// Equal returns 1 if gt == rhs, 0 otherwise +func (gt *Gt) Equal(rhs *Gt) int { + return (*fp12)(gt).Equal((*fp12)(rhs)) +} + +// Generator returns the base point +func (gt *Gt) Generator() *Gt { + // pairing(&G1::generator(), &G2::generator()) + gt.Set((*Gt)(&fp12{ + A: fp6{ + A: fp2{ + A: fp{ + 0x1972e433a01f85c5, + 0x97d32b76fd772538, + 0xc8ce546fc96bcdf9, + 0xcef63e7366d40614, + 0xa611342781843780, + 0x13f3448a3fc6d825, + }, + B: fp{ + 0xd26331b02e9d6995, + 0x9d68a482f7797e7d, + 0x9c9b29248d39ea92, + 0xf4801ca2e13107aa, + 0xa16c0732bdbcb066, + 0x083ca4afba360478, + }, + }, + B: fp2{ + A: fp{ + 0x59e261db0916b641, + 0x2716b6f4b23e960d, + 0xc8e55b10a0bd9c45, + 0x0bdb0bd99c4deda8, + 0x8cf89ebf57fdaac5, + 0x12d6b7929e777a5e, + }, + B: fp{ + 0x5fc85188b0e15f35, + 0x34a06e3a8f096365, + 0xdb3126a6e02ad62c, + 0xfc6f5aa97d9a990b, + 0xa12f55f5eb89c210, + 0x1723703a926f8889, + }, + }, + C: fp2{ + A: fp{ + 0x93588f2971828778, + 0x43f65b8611ab7585, + 0x3183aaf5ec279fdf, + 0xfa73d7e18ac99df6, + 0x64e176a6a64c99b0, + 0x179fa78c58388f1f, + }, + B: fp{ + 0x672a0a11ca2aef12, + 0x0d11b9b52aa3f16b, + 0xa44412d0699d056e, + 0xc01d0177221a5ba5, + 0x66e0cede6c735529, + 0x05f5a71e9fddc339, + }, + }, + }, + B: fp6{ + A: fp2{ + A: fp{ + 0xd30a88a1b062c679, + 0x5ac56a5d35fc8304, + 0xd0c834a6a81f290d, + 0xcd5430c2da3707c7, + 0xf0c27ff780500af0, + 0x09245da6e2d72eae, + }, + B: fp{ + 0x9f2e0676791b5156, + 0xe2d1c8234918fe13, + 0x4c9e459f3c561bf4, + 0xa3e85e53b9d3e3c1, + 0x820a121e21a70020, + 0x15af618341c59acc, + }, + }, + B: fp2{ + A: fp{ + 0x7c95658c24993ab1, + 0x73eb38721ca886b9, + 0x5256d749477434bc, + 0x8ba41902ea504a8b, + 0x04a3d3f80c86ce6d, + 0x18a64a87fb686eaa, + }, + B: fp{ + 0xbb83e71bb920cf26, + 0x2a5277ac92a73945, + 0xfc0ee59f94f046a0, + 0x7158cdf3786058f7, + 0x7cc1061b82f945f6, + 0x03f847aa9fdbe567, + }, + }, + C: fp2{ + A: fp{ + 0x8078dba56134e657, + 0x1cd7ec9a43998a6e, + 0xb1aa599a1a993766, + 0xc9a0f62f0842ee44, + 0x8e159be3b605dffa, + 0x0c86ba0d4af13fc2, + }, + B: fp{ + 0xe80ff2a06a52ffb1, + 0x7694ca48721a906c, + 0x7583183e03b08514, + 0xf567afdd40cee4e2, + 0x9a6d96d2e526a5fc, + 0x197e9f49861f2242, + }, + }, + }, + })) + return gt +} + +// Add adds this value to another value. +func (gt *Gt) Add(arg1, arg2 *Gt) *Gt { + (*fp12)(gt).Mul((*fp12)(arg1), (*fp12)(arg2)) + return gt +} + +// Double this value +func (gt *Gt) Double(a *Gt) *Gt { + (*fp12)(gt).Square((*fp12)(a)) + return gt +} + +// Sub subtracts the two values +func (gt *Gt) Sub(arg1, arg2 *Gt) *Gt { + var t fp12 + t.Conjugate((*fp12)(arg2)) + (*fp12)(gt).Mul((*fp12)(arg1), &t) + return gt +} + +// Neg negates this value +func (gt *Gt) Neg(a *Gt) *Gt { + (*fp12)(gt).Conjugate((*fp12)(a)) + return gt +} + +// Mul multiplies this value by the input scalar +func (gt *Gt) Mul(a *Gt, s *native.Field) *Gt { + var f, p fp12 + f.Set((*fp12)(a)) + bytes := s.Bytes() + + precomputed := [16]fp12{} + precomputed[1].Set(&f) + for i := 2; i < 16; i += 2 { + precomputed[i].Square(&precomputed[i>>1]) + precomputed[i+1].Mul(&precomputed[i], &f) + } + for i := 0; i < 256; i += 4 { + // Brouwer / windowing method. window size of 4. + for j := 0; j < 4; j++ { + p.Square(&p) + } + window := bytes[32-1-i>>3] >> (4 - i&0x04) & 0x0F + p.Mul(&p, &precomputed[window]) + } + (*fp12)(gt).Set(&p) + return gt +} + +// Square this value +func (gt *Gt) Square(a *Gt) *Gt { + (*fp12)(gt).cyclotomicSquare((*fp12)(a)) + return gt +} + +// Invert this value +func (gt *Gt) Invert(a *Gt) (*Gt, int) { + _, wasInverted := (*fp12)(gt).Invert((*fp12)(a)) + return gt, wasInverted +} + +func fp4Square(a, b, arg1, arg2 *fp2) { + var t0, t1, t2 fp2 + + t0.Square(arg1) + t1.Square(arg2) + t2.MulByNonResidue(&t1) + a.Add(&t2, &t0) + t2.Add(arg1, arg2) + t2.Square(&t2) + t2.Sub(&t2, &t0) + b.Sub(&t2, &t1) +} + +func (f *fp12) cyclotomicSquare(a *fp12) *fp12 { + // Adaptation of Algorithm 5.5.4, Guide to Pairing-Based Cryptography + // Faster Squaring in the Cyclotomic Subgroup of Sixth Degree Extensions + // https://eprint.iacr.org/2009/565.pdf + var z0, z1, z2, z3, z4, z5, t0, t1, t2, t3 fp2 + z0.Set(&a.A.A) + z4.Set(&a.A.B) + z3.Set(&a.A.C) + z2.Set(&a.B.A) + z1.Set(&a.B.B) + z5.Set(&a.B.C) + + fp4Square(&t0, &t1, &z0, &z1) + z0.Sub(&t0, &z0) + z0.Double(&z0) + z0.Add(&z0, &t0) + + z1.Add(&t1, &z1) + z1.Double(&z1) + z1.Add(&z1, &t1) + + fp4Square(&t0, &t1, &z2, &z3) + fp4Square(&t2, &t3, &z4, &z5) + + z4.Sub(&t0, &z4) + z4.Double(&z4) + z4.Add(&z4, &t0) + + z5.Add(&z5, &t1) + z5.Double(&z5) + z5.Add(&z5, &t1) + + t0.MulByNonResidue(&t3) + z2.Add(&z2, &t0) + z2.Double(&z2) + z2.Add(&z2, &t0) + + z3.Sub(&t2, &z3) + z3.Double(&z3) + z3.Add(&z3, &t2) + + f.A.A.Set(&z0) + f.A.B.Set(&z4) + f.A.C.Set(&z3) + + f.B.A.Set(&z2) + f.B.B.Set(&z1) + f.B.C.Set(&z5) + return f +} + +func (f *fp12) cyclotomicExp(a *fp12) *fp12 { + var t fp12 + t.SetOne() + foundOne := 0 + + for i := 63; i >= 0; i-- { + b := int((paramX >> i) & 1) + if foundOne == 1 { + t.cyclotomicSquare(&t) + } else { + foundOne = b + } + if b == 1 { + t.Mul(&t, a) + } + } + f.Conjugate(&t) + return f +} diff --git a/pkg/crypto/core/curves/native/bls12381/pairings.go b/pkg/crypto/core/curves/native/bls12381/pairings.go new file mode 100755 index 000000000..c01ef092a --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/pairings.go @@ -0,0 +1,254 @@ +package bls12381 + +const coefficientsG2 = 68 + +type Engine struct { + pairs []pair +} + +type pair struct { + g1 G1 + g2 G2 +} + +type g2Prepared struct { + identity int + coefficients []coefficients +} + +type coefficients struct { + a, b, c fp2 +} + +func (c *coefficients) CMove(arg1, arg2 *coefficients, choice int) *coefficients { + c.a.CMove(&arg1.a, &arg2.a, choice) + c.b.CMove(&arg1.b, &arg2.b, choice) + c.c.CMove(&arg1.c, &arg2.c, choice) + return c +} + +// AddPair adds a pair of points to be paired +func (e *Engine) AddPair(g1 *G1, g2 *G2) *Engine { + var p pair + p.g1.ToAffine(g1) + p.g2.ToAffine(g2) + if p.g1.IsIdentity()|p.g2.IsIdentity() == 0 { + e.pairs = append(e.pairs, p) + } + return e +} + +// AddPairInvG1 adds a pair of points to be paired. G1 point is negated +func (e *Engine) AddPairInvG1(g1 *G1, g2 *G2) *Engine { + var p G1 + p.Neg(g1) + return e.AddPair(&p, g2) +} + +// AddPairInvG2 adds a pair of points to be paired. G2 point is negated +func (e *Engine) AddPairInvG2(g1 *G1, g2 *G2) *Engine { + var p G2 + p.Neg(g2) + return e.AddPair(g1, &p) +} + +func (e *Engine) Reset() *Engine { + e.pairs = []pair{} + return e +} + +func (e *Engine) Check() bool { + return e.pairing().IsOne() == 1 +} + +func (e *Engine) Result() *Gt { + return e.pairing() +} + +func (e *Engine) pairing() *Gt { + f := new(Gt).SetOne() + if len(e.pairs) == 0 { + return f + } + coeffs := e.computeCoeffs() + e.millerLoop((*fp12)(f), coeffs) + return f.FinalExponentiation(f) +} + +func (e *Engine) millerLoop(f *fp12, coeffs []g2Prepared) { + newF := new(fp12).SetZero() + found := 0 + cIdx := 0 + for i := 63; i >= 0; i-- { + x := int(((paramX >> 1) >> i) & 1) + if found == 0 { + found |= x + continue + } + + // doubling + for j, terms := range coeffs { + identity := e.pairs[j].g1.IsIdentity() | terms.identity + newF.Set(f) + ell(newF, terms.coefficients[cIdx], &e.pairs[j].g1) + f.CMove(newF, f, identity) + } + cIdx++ + + if x == 1 { + // adding + for j, terms := range coeffs { + identity := e.pairs[j].g1.IsIdentity() | terms.identity + newF.Set(f) + ell(newF, terms.coefficients[cIdx], &e.pairs[j].g1) + f.CMove(newF, f, identity) + } + cIdx++ + } + f.Square(f) + } + for j, terms := range coeffs { + identity := e.pairs[j].g1.IsIdentity() | terms.identity + newF.Set(f) + ell(newF, terms.coefficients[cIdx], &e.pairs[j].g1) + f.CMove(newF, f, identity) + } + f.Conjugate(f) +} + +func (e *Engine) computeCoeffs() []g2Prepared { + coeffs := make([]g2Prepared, len(e.pairs)) + for i, p := range e.pairs { + identity := p.g2.IsIdentity() + q := new(G2).Generator() + q.CMove(&p.g2, q, identity) + c := new(G2).Set(q) + cfs := make([]coefficients, coefficientsG2) + found := 0 + k := 0 + + for j := 63; j >= 0; j-- { + x := int(((paramX >> 1) >> j) & 1) + if found == 0 { + found |= x + continue + } + cfs[k] = doublingStep(c) + k++ + + if x == 1 { + cfs[k] = additionStep(c, q) + k++ + } + } + cfs[k] = doublingStep(c) + coeffs[i] = g2Prepared{ + coefficients: cfs, identity: identity, + } + } + return coeffs +} + +func ell(f *fp12, coeffs coefficients, p *G1) { + var x, y fp2 + x.A.Mul(&coeffs.a.A, &p.y) + x.B.Mul(&coeffs.a.B, &p.y) + y.A.Mul(&coeffs.b.A, &p.x) + y.B.Mul(&coeffs.b.B, &p.x) + f.MulByABD(f, &coeffs.c, &y, &x) +} + +func doublingStep(p *G2) coefficients { + // Adaptation of Algorithm 26, https://eprint.iacr.org/2010/354.pdf + var t0, t1, t2, t3, t4, t5, t6, zsqr fp2 + t0.Square(&p.x) + t1.Square(&p.y) + t2.Square(&t1) + t3.Add(&t1, &p.x) + t3.Square(&t3) + t3.Sub(&t3, &t0) + t3.Sub(&t3, &t2) + t3.Double(&t3) + t4.Double(&t0) + t4.Add(&t4, &t0) + t6.Add(&p.x, &t4) + t5.Square(&t4) + zsqr.Square(&p.z) + p.x.Sub(&t5, &t3) + p.x.Sub(&p.x, &t3) + p.z.Add(&p.z, &p.y) + p.z.Square(&p.z) + p.z.Sub(&p.z, &t1) + p.z.Sub(&p.z, &zsqr) + p.y.Sub(&t3, &p.x) + p.y.Mul(&p.y, &t4) + t2.Double(&t2) + t2.Double(&t2) + t2.Double(&t2) + p.y.Sub(&p.y, &t2) + t3.Mul(&t4, &zsqr) + t3.Double(&t3) + t3.Neg(&t3) + t6.Square(&t6) + t6.Sub(&t6, &t0) + t6.Sub(&t6, &t5) + t1.Double(&t1) + t1.Double(&t1) + t6.Sub(&t6, &t1) + t0.Mul(&p.z, &zsqr) + t0.Double(&t0) + + return coefficients{ + a: t0, b: t3, c: t6, + } +} + +func additionStep(r, q *G2) coefficients { + // Adaptation of Algorithm 27, https://eprint.iacr.org/2010/354.pdf + var zsqr, ysqr fp2 + var t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10 fp2 + zsqr.Square(&r.z) + ysqr.Square(&q.y) + t0.Mul(&zsqr, &q.x) + t1.Add(&q.y, &r.z) + t1.Square(&t1) + t1.Sub(&t1, &ysqr) + t1.Sub(&t1, &zsqr) + t1.Mul(&t1, &zsqr) + t2.Sub(&t0, &r.x) + t3.Square(&t2) + t4.Double(&t3) + t4.Double(&t4) + t5.Mul(&t4, &t2) + t6.Sub(&t1, &r.y) + t6.Sub(&t6, &r.y) + t9.Mul(&t6, &q.x) + t7.Mul(&t4, &r.x) + r.x.Square(&t6) + r.x.Sub(&r.x, &t5) + r.x.Sub(&r.x, &t7) + r.x.Sub(&r.x, &t7) + r.z.Add(&r.z, &t2) + r.z.Square(&r.z) + r.z.Sub(&r.z, &zsqr) + r.z.Sub(&r.z, &t3) + t10.Add(&q.y, &r.z) + t8.Sub(&t7, &r.x) + t8.Mul(&t8, &t6) + t0.Mul(&r.y, &t5) + t0.Double(&t0) + r.y.Sub(&t8, &t0) + t10.Square(&t10) + t10.Sub(&t10, &ysqr) + zsqr.Square(&r.z) + t10.Sub(&t10, &zsqr) + t9.Double(&t9) + t9.Sub(&t9, &t10) + t10.Double(&r.z) + t6.Neg(&t6) + t1.Double(&t6) + + return coefficients{ + a: t10, b: t1, c: t9, + } +} diff --git a/pkg/crypto/core/curves/native/bls12381/pairings_test.go b/pkg/crypto/core/curves/native/bls12381/pairings_test.go new file mode 100755 index 000000000..fccb1d601 --- /dev/null +++ b/pkg/crypto/core/curves/native/bls12381/pairings_test.go @@ -0,0 +1,64 @@ +package bls12381 + +import ( + crand "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +func TestSinglePairing(t *testing.T) { + g := new(G1).Generator() + h := new(G2).Generator() + + e := new(Engine) + e.AddPair(g, h) + p := e.Result() + p.Neg(p) + + e.Reset() + e.AddPairInvG2(g, h) + q := e.Result() + e.Reset() + e.AddPairInvG1(g, h) + r := e.Result() + + require.Equal(t, 1, p.Equal(q)) + require.Equal(t, 1, q.Equal(r)) +} + +func TestMultiPairing(t *testing.T) { + const Tests = 10 + e1 := new(Engine) + e2 := new(Engine) + + g1s := make([]*G1, Tests) + g2s := make([]*G2, Tests) + sc := make([]*native.Field, Tests) + res := make([]*Gt, Tests) + expected := new(Gt).SetOne() + + for i := 0; i < Tests; i++ { + var bytes [64]byte + g1s[i] = new(G1).Generator() + g2s[i] = new(G2).Generator() + sc[i] = Bls12381FqNew() + _, _ = crand.Read(bytes[:]) + sc[i].SetBytesWide(&bytes) + if i&1 == 0 { + g1s[i].Mul(g1s[i], sc[i]) + } else { + g2s[i].Mul(g2s[i], sc[i]) + } + e1.AddPair(g1s[i], g2s[i]) + e2.AddPair(g1s[i], g2s[i]) + res[i] = e1.Result() + e1.Reset() + expected.Add(expected, res[i]) + } + + actual := e2.Result() + require.Equal(t, 1, expected.Equal(actual)) +} diff --git a/pkg/crypto/core/curves/native/field.go b/pkg/crypto/core/curves/native/field.go new file mode 100755 index 000000000..c29d0f82e --- /dev/null +++ b/pkg/crypto/core/curves/native/field.go @@ -0,0 +1,388 @@ +package native + +import ( + "encoding/binary" + "fmt" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// FieldLimbs is the number of limbs needed to represent this field +const FieldLimbs = 4 + +// FieldBytes is the number of bytes needed to represent this field +const FieldBytes = 32 + +// WideFieldBytes is the number of bytes needed for safe conversion +// to this field to avoid bias when reduced +const WideFieldBytes = 64 + +// Field represents a field element +type Field struct { + // Value is the field elements value + Value [FieldLimbs]uint64 + // Params are the field parameters + Params *FieldParams + // Arithmetic are the field methods + Arithmetic FieldArithmetic +} + +// FieldParams are the field parameters +type FieldParams struct { + // R is 2^256 mod Modulus + R [FieldLimbs]uint64 + // R2 is 2^512 mod Modulus + R2 [FieldLimbs]uint64 + // R3 is 2^768 mod Modulus + R3 [FieldLimbs]uint64 + // Modulus of the field + Modulus [FieldLimbs]uint64 + // Modulus as big.Int + BiModulus *big.Int +} + +// FieldArithmetic are the methods that can be done on a field +type FieldArithmetic interface { + // ToMontgomery converts this field to montgomery form + ToMontgomery(out, arg *[FieldLimbs]uint64) + // FromMontgomery converts this field from montgomery form + FromMontgomery(out, arg *[FieldLimbs]uint64) + // Neg performs modular negation + Neg(out, arg *[FieldLimbs]uint64) + // Square performs modular square + Square(out, arg *[FieldLimbs]uint64) + // Mul performs modular multiplication + Mul(out, arg1, arg2 *[FieldLimbs]uint64) + // Add performs modular addition + Add(out, arg1, arg2 *[FieldLimbs]uint64) + // Sub performs modular subtraction + Sub(out, arg1, arg2 *[FieldLimbs]uint64) + // Sqrt performs modular square root + Sqrt(wasSquare *int, out, arg *[FieldLimbs]uint64) + // Invert performs modular inverse + Invert(wasInverted *int, out, arg *[FieldLimbs]uint64) + // FromBytes converts a little endian byte array into a field element + FromBytes(out *[FieldLimbs]uint64, arg *[FieldBytes]byte) + // ToBytes converts a field element to a little endian byte array + ToBytes(out *[FieldBytes]byte, arg *[FieldLimbs]uint64) + // Selectznz performs conditional select. + // selects arg1 if choice == 0 and arg2 if choice == 1 + Selectznz(out, arg1, arg2 *[FieldLimbs]uint64, choice int) +} + +// Cmp returns -1 if f < rhs +// 0 if f == rhs +// 1 if f > rhs +func (f *Field) Cmp(rhs *Field) int { + return cmpHelper(&f.Value, &rhs.Value) +} + +// cmpHelper returns -1 if lhs < rhs +// -1 if lhs == rhs +// 1 if lhs > rhs +// Public only for convenience for some internal implementations +func cmpHelper(lhs, rhs *[FieldLimbs]uint64) int { + gt := uint64(0) + lt := uint64(0) + for i := 3; i >= 0; i-- { + // convert to two 64-bit numbers where + // the leading bits are zeros and hold no meaning + // so rhs - fp actually means gt + // and fp - rhs actually means lt. + rhsH := rhs[i] >> 32 + rhsL := rhs[i] & 0xffffffff + lhsH := lhs[i] >> 32 + lhsL := lhs[i] & 0xffffffff + + // Check the leading bit + // if negative then fp > rhs + // if positive then fp < rhs + gt |= (rhsH - lhsH) >> 32 & 1 &^ lt + lt |= (lhsH - rhsH) >> 32 & 1 &^ gt + gt |= (rhsL - lhsL) >> 32 & 1 &^ lt + lt |= (lhsL - rhsL) >> 32 & 1 &^ gt + } + // Make the result -1 for <, 0 for =, 1 for > + return int(gt) - int(lt) +} + +// Equal returns 1 if f == rhs, 0 otherwise +func (f *Field) Equal(rhs *Field) int { + return equalHelper(&f.Value, &rhs.Value) +} + +func equalHelper(lhs, rhs *[FieldLimbs]uint64) int { + t := lhs[0] ^ rhs[0] + t |= lhs[1] ^ rhs[1] + t |= lhs[2] ^ rhs[2] + t |= lhs[3] ^ rhs[3] + return int(((int64(t) | int64(-t)) >> 63) + 1) +} + +// IsZero returns 1 if f == 0, 0 otherwise +func (f *Field) IsZero() int { + t := f.Value[0] + t |= f.Value[1] + t |= f.Value[2] + t |= f.Value[3] + return int(((int64(t) | int64(-t)) >> 63) + 1) +} + +// IsNonZero returns 1 if f != 0, 0 otherwise +func (f *Field) IsNonZero() int { + t := f.Value[0] + t |= f.Value[1] + t |= f.Value[2] + t |= f.Value[3] + return int(-((int64(t) | int64(-t)) >> 63)) +} + +// IsOne returns 1 if f == 1, 0 otherwise +func (f *Field) IsOne() int { + return equalHelper(&f.Value, &f.Params.R) +} + +// Set f = rhs +func (f *Field) Set(rhs *Field) *Field { + f.Value[0] = rhs.Value[0] + f.Value[1] = rhs.Value[1] + f.Value[2] = rhs.Value[2] + f.Value[3] = rhs.Value[3] + f.Params = rhs.Params + f.Arithmetic = rhs.Arithmetic + return f +} + +// SetUint64 f = rhs +func (f *Field) SetUint64(rhs uint64) *Field { + t := &[FieldLimbs]uint64{rhs, 0, 0, 0} + f.Arithmetic.ToMontgomery(&f.Value, t) + return f +} + +// SetOne f = r +func (f *Field) SetOne() *Field { + f.Value[0] = f.Params.R[0] + f.Value[1] = f.Params.R[1] + f.Value[2] = f.Params.R[2] + f.Value[3] = f.Params.R[3] + return f +} + +// SetZero f = 0 +func (f *Field) SetZero() *Field { + f.Value[0] = 0 + f.Value[1] = 0 + f.Value[2] = 0 + f.Value[3] = 0 + return f +} + +// SetBytesWide takes 64 bytes as input and treats them as a 512-bit number. +// Attributed to https://github.com/zcash/pasta_curves/blob/main/src/fields/Fp.rs#L255 +// We reduce an arbitrary 512-bit number by decomposing it into two 256-bit digits +// with the higher bits multiplied by 2^256. Thus, we perform two reductions +// +// 1. the lower bits are multiplied by r^2, as normal +// 2. the upper bits are multiplied by r^2 * 2^256 = r^3 +// +// and computing their sum in the field. It remains to see that arbitrary 256-bit +// numbers can be placed into Montgomery form safely using the reduction. The +// reduction works so long as the product is less than r=2^256 multiplied by +// the modulus. This holds because for any `c` smaller than the modulus, we have +// that (2^256 - 1)*c is an acceptable product for the reduction. Therefore, the +// reduction always works so long as `c` is in the field; in this case it is either the +// constant `r2` or `r3`. +func (f *Field) SetBytesWide(input *[WideFieldBytes]byte) *Field { + d0 := [FieldLimbs]uint64{ + binary.LittleEndian.Uint64(input[:8]), + binary.LittleEndian.Uint64(input[8:16]), + binary.LittleEndian.Uint64(input[16:24]), + binary.LittleEndian.Uint64(input[24:32]), + } + d1 := [FieldLimbs]uint64{ + binary.LittleEndian.Uint64(input[32:40]), + binary.LittleEndian.Uint64(input[40:48]), + binary.LittleEndian.Uint64(input[48:56]), + binary.LittleEndian.Uint64(input[56:64]), + } + // f.Arithmetic.ToMontgomery(&d0, &d0) + // f.Arithmetic.Mul(&d1, &d1, &f.Params.R2) + // f.Arithmetic.Add(&f.Value, &d0, &d0) + // Convert to Montgomery form + tv1 := &[FieldLimbs]uint64{} + tv2 := &[FieldLimbs]uint64{} + // d0*r2 + d1*r3 + f.Arithmetic.Mul(tv1, &d0, &f.Params.R2) + f.Arithmetic.Mul(tv2, &d1, &f.Params.R3) + f.Arithmetic.Add(&f.Value, tv1, tv2) + return f +} + +// SetBytes attempts to convert a little endian byte representation +// of a scalar into a `Fp`, failing if input is not canonical +func (f *Field) SetBytes(input *[FieldBytes]byte) (*Field, error) { + d0 := [FieldLimbs]uint64{0, 0, 0, 0} + f.Arithmetic.FromBytes(&d0, input) + + if cmpHelper(&d0, &f.Params.Modulus) != -1 { + return nil, fmt.Errorf("invalid byte sequence") + } + return f.SetLimbs(&d0), nil +} + +// SetBigInt initializes an element from big.Int +// The value is reduced by the modulus +func (f *Field) SetBigInt(bi *big.Int) *Field { + var buffer [FieldBytes]byte + t := new(big.Int).Set(bi) + t.Mod(t, f.Params.BiModulus) + t.FillBytes(buffer[:]) + copy(buffer[:], internal.ReverseScalarBytes(buffer[:])) + _, _ = f.SetBytes(&buffer) + return f +} + +// SetRaw converts a raw array into a field element +// Assumes input is already in montgomery form +func (f *Field) SetRaw(input *[FieldLimbs]uint64) *Field { + f.Value[0] = input[0] + f.Value[1] = input[1] + f.Value[2] = input[2] + f.Value[3] = input[3] + return f +} + +// SetLimbs converts an array into a field element +// by converting to montgomery form +func (f *Field) SetLimbs(input *[FieldLimbs]uint64) *Field { + f.Arithmetic.ToMontgomery(&f.Value, input) + return f +} + +// Bytes converts this element into a byte representation +// in little endian byte order +func (f *Field) Bytes() [FieldBytes]byte { + var output [FieldBytes]byte + tv := &[FieldLimbs]uint64{} + f.Arithmetic.FromMontgomery(tv, &f.Value) + f.Arithmetic.ToBytes(&output, tv) + return output +} + +// BigInt converts this element into the big.Int struct +func (f *Field) BigInt() *big.Int { + buffer := f.Bytes() + return new(big.Int).SetBytes(internal.ReverseScalarBytes(buffer[:])) +} + +// Raw converts this element into the a [FieldLimbs]uint64 +func (f *Field) Raw() [FieldLimbs]uint64 { + res := &[FieldLimbs]uint64{} + f.Arithmetic.FromMontgomery(res, &f.Value) + return *res +} + +// Double this element +func (f *Field) Double(a *Field) *Field { + f.Arithmetic.Add(&f.Value, &a.Value, &a.Value) + return f +} + +// Square this element +func (f *Field) Square(a *Field) *Field { + f.Arithmetic.Square(&f.Value, &a.Value) + return f +} + +// Sqrt this element, if it exists. If true, then value +// is a square root. If false, value is a QNR +func (f *Field) Sqrt(a *Field) (*Field, bool) { + wasSquare := 0 + f.Arithmetic.Sqrt(&wasSquare, &f.Value, &a.Value) + return f, wasSquare == 1 +} + +// Invert this element i.e. compute the multiplicative inverse +// return false, zero if this element is zero. +func (f *Field) Invert(a *Field) (*Field, bool) { + wasInverted := 0 + f.Arithmetic.Invert(&wasInverted, &f.Value, &a.Value) + return f, wasInverted == 1 +} + +// Mul returns the result from multiplying this element by rhs +func (f *Field) Mul(lhs, rhs *Field) *Field { + f.Arithmetic.Mul(&f.Value, &lhs.Value, &rhs.Value) + return f +} + +// Sub returns the result from subtracting rhs from this element +func (f *Field) Sub(lhs, rhs *Field) *Field { + f.Arithmetic.Sub(&f.Value, &lhs.Value, &rhs.Value) + return f +} + +// Add returns the result from adding rhs to this element +func (f *Field) Add(lhs, rhs *Field) *Field { + f.Arithmetic.Add(&f.Value, &lhs.Value, &rhs.Value) + return f +} + +// Neg returns negation of this element +func (f *Field) Neg(input *Field) *Field { + f.Arithmetic.Neg(&f.Value, &input.Value) + return f +} + +// Exp raises base^exp +func (f *Field) Exp(base, exp *Field) *Field { + e := [FieldLimbs]uint64{} + f.Arithmetic.FromMontgomery(&e, &exp.Value) + Pow(&f.Value, &base.Value, &e, f.Params, f.Arithmetic) + return f +} + +// CMove sets f = lhs if choice == 0 and f = rhs if choice == 1 +func (f *Field) CMove(lhs, rhs *Field, choice int) *Field { + f.Arithmetic.Selectznz(&f.Value, &lhs.Value, &rhs.Value, choice) + return f +} + +// Pow raises base^exp. The result is written to out. +// Public only for convenience for some internal implementations +func Pow(out, base, exp *[FieldLimbs]uint64, params *FieldParams, arithmetic FieldArithmetic) { + res := [FieldLimbs]uint64{params.R[0], params.R[1], params.R[2], params.R[3]} + tmp := [FieldLimbs]uint64{} + + for i := len(exp) - 1; i >= 0; i-- { + for j := 63; j >= 0; j-- { + arithmetic.Square(&res, &res) + arithmetic.Mul(&tmp, &res, base) + arithmetic.Selectznz(&res, &res, &tmp, int(exp[i]>>j)&1) + } + } + out[0] = res[0] + out[1] = res[1] + out[2] = res[2] + out[3] = res[3] +} + +// Pow2k raises arg to the power `2^k`. This result is written to out. +// Public only for convenience for some internal implementations +func Pow2k(out, arg *[FieldLimbs]uint64, k int, arithmetic FieldArithmetic) { + var t [FieldLimbs]uint64 + t[0] = arg[0] + t[1] = arg[1] + t[2] = arg[2] + t[3] = arg[3] + for i := 0; i < k; i++ { + arithmetic.Square(&t, &t) + } + + out[0] = t[0] + out[1] = t[1] + out[2] = t[2] + out[3] = t[3] +} diff --git a/pkg/crypto/core/curves/native/hash2field.go b/pkg/crypto/core/curves/native/hash2field.go new file mode 100755 index 000000000..1d000253d --- /dev/null +++ b/pkg/crypto/core/curves/native/hash2field.go @@ -0,0 +1,107 @@ +package native + +import ( + "hash" + + "golang.org/x/crypto/sha3" +) + +// OversizeDstSalt is the salt used to hash a dst over MaxDstLen +var OversizeDstSalt = []byte("H2C-OVERSIZE-DST-") + +// MaxDstLen the max size for dst in hash to curve +const MaxDstLen = 255 + +func getDomainXmd(h hash.Hash, domain []byte) []byte { + var out []byte + if len(domain) > MaxDstLen { + h.Reset() + _, _ = h.Write(OversizeDstSalt) + _, _ = h.Write(domain) + out = h.Sum(nil) + } else { + out = domain + } + return out +} + +func getDomainXof(h sha3.ShakeHash, domain []byte) []byte { + var out []byte + if len(domain) > MaxDstLen { + h.Reset() + _, _ = h.Write(OversizeDstSalt) + _, _ = h.Write(domain) + var tv [64]byte + _, _ = h.Read(tv[:]) + out = tv[:] + } else { + out = domain + } + return out +} + +// ExpandMsgXmd expands the msg with the domain to output a byte array +// with outLen in size using a fixed size hash. +// See https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.1 +func ExpandMsgXmd(h *EllipticPointHasher, msg, domain []byte, outLen int) []byte { + domain = getDomainXmd(h.xmd, domain) + domainLen := byte(len(domain)) + h.xmd.Reset() + // DST_prime = DST || I2OSP(len(DST), 1) + // b_0 = H(Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime) + _, _ = h.xmd.Write(make([]byte, h.xmd.BlockSize())) + _, _ = h.xmd.Write(msg) + _, _ = h.xmd.Write([]byte{uint8(outLen >> 8), uint8(outLen)}) + _, _ = h.xmd.Write([]byte{0}) + _, _ = h.xmd.Write(domain) + _, _ = h.xmd.Write([]byte{domainLen}) + b0 := h.xmd.Sum(nil) + + // b_1 = H(b_0 || I2OSP(1, 1) || DST_prime) + h.xmd.Reset() + _, _ = h.xmd.Write(b0) + _, _ = h.xmd.Write([]byte{1}) + _, _ = h.xmd.Write(domain) + _, _ = h.xmd.Write([]byte{domainLen}) + b1 := h.xmd.Sum(nil) + + // b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime) + ell := (outLen + h.xmd.Size() - 1) / h.xmd.Size() + bi := b1 + out := make([]byte, outLen) + for i := 1; i < ell; i++ { + h.xmd.Reset() + // b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime) + tmp := make([]byte, h.xmd.Size()) + for j := 0; j < h.xmd.Size(); j++ { + tmp[j] = b0[j] ^ bi[j] + } + _, _ = h.xmd.Write(tmp) + _, _ = h.xmd.Write([]byte{1 + uint8(i)}) + _, _ = h.xmd.Write(domain) + _, _ = h.xmd.Write([]byte{domainLen}) + + // b_1 || ... || b_(ell - 1) + copy(out[(i-1)*h.xmd.Size():i*h.xmd.Size()], bi[:]) + bi = h.xmd.Sum(nil) + } + // b_ell + copy(out[(ell-1)*h.xmd.Size():], bi[:]) + return out[:outLen] +} + +// ExpandMsgXof expands the msg with the domain to output a byte array +// with outLen in size using a xof hash +// See https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.2 +func ExpandMsgXof(h *EllipticPointHasher, msg, domain []byte, outLen int) []byte { + domain = getDomainXof(h.xof, domain) + domainLen := byte(len(domain)) + h.xof.Reset() + _, _ = h.xof.Write(msg) + _, _ = h.xof.Write([]byte{uint8(outLen >> 8), uint8(outLen)}) + _, _ = h.xof.Write(domain) + _, _ = h.xof.Write([]byte{domainLen}) + out := make([]byte, outLen) + _, _ = h.xof.Read(out) + return out +} diff --git a/pkg/crypto/core/curves/native/isogeny.go b/pkg/crypto/core/curves/native/isogeny.go new file mode 100755 index 000000000..b4addb3dc --- /dev/null +++ b/pkg/crypto/core/curves/native/isogeny.go @@ -0,0 +1,62 @@ +package native + +// IsogenyParams are the parameters needed to map from an isogeny to the main curve +type IsogenyParams struct { + XNum [][FieldLimbs]uint64 + XDen [][FieldLimbs]uint64 + YNum [][FieldLimbs]uint64 + YDen [][FieldLimbs]uint64 +} + +// Map from the isogeny curve to the main curve using the parameters +func (p *IsogenyParams) Map(xIn, yIn *Field) (x, y *Field) { + var xNum, xDen, yNum, yDen, tv [FieldLimbs]uint64 + var wasInverted int + + xnumL := len(p.XNum) + xdenL := len(p.XDen) + ynumL := len(p.YNum) + ydenL := len(p.YDen) + + degree := 0 + for _, i := range []int{xnumL, xdenL, ynumL, ydenL} { + if degree < i { + degree = i + } + } + + xs := make([][FieldLimbs]uint64, degree) + xs[0] = xIn.Params.R // x[0] = x^0 + xs[1] = xIn.Value // x[1] = x^1 + xIn.Arithmetic.Square(&xs[2], &xIn.Value) // x[2] = x^2 + for i := 3; i < degree; i++ { + // x[i] = x^i + xIn.Arithmetic.Mul(&xs[i], &xs[i-1], &xIn.Value) + } + + computeIsoK(&xNum, &xs, &p.XNum, xIn.Arithmetic) + computeIsoK(&xDen, &xs, &p.XDen, xIn.Arithmetic) + computeIsoK(&yNum, &xs, &p.YNum, xIn.Arithmetic) + computeIsoK(&yDen, &xs, &p.YDen, xIn.Arithmetic) + + xIn.Arithmetic.Invert(&wasInverted, &xDen, &xDen) + x = new(Field).Set(xIn) + xIn.Arithmetic.Mul(&tv, &xNum, &xDen) + xIn.Arithmetic.Selectznz(&x.Value, &x.Value, &tv, wasInverted) + + yIn.Arithmetic.Invert(&wasInverted, &yDen, &yDen) + y = new(Field).Set(yIn) + yIn.Arithmetic.Mul(&tv, &yNum, &yDen) + yIn.Arithmetic.Selectznz(&y.Value, &y.Value, &tv, wasInverted) + yIn.Arithmetic.Mul(&y.Value, &y.Value, &yIn.Value) + return +} + +func computeIsoK(out *[FieldLimbs]uint64, xxs, k *[][FieldLimbs]uint64, f FieldArithmetic) { + var tv [FieldLimbs]uint64 + + for i := range *k { + f.Mul(&tv, &(*xxs)[i], &(*k)[i]) + f.Add(out, out, &tv) + } +} diff --git a/pkg/crypto/core/curves/native/k256/fp/fp.go b/pkg/crypto/core/curves/native/k256/fp/fp.go new file mode 100755 index 000000000..8d70837de --- /dev/null +++ b/pkg/crypto/core/curves/native/k256/fp/fp.go @@ -0,0 +1,175 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fp + +import ( + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +var ( + k256FpInitonce sync.Once + k256FpParams native.FieldParams +) + +func K256FpNew() *native.Field { + return &native.Field{ + Value: [native.FieldLimbs]uint64{}, + Params: getK256FpParams(), + Arithmetic: k256FpArithmetic{}, + } +} + +func k256FpParamsInit() { + k256FpParams = native.FieldParams{ + R: [native.FieldLimbs]uint64{0x00000001000003d1, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + R2: [native.FieldLimbs]uint64{0x000007a2000e90a1, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000}, + R3: [native.FieldLimbs]uint64{0x002bb1e33795f671, 0x0000000100000b73, 0x0000000000000000, 0x0000000000000000}, + Modulus: [native.FieldLimbs]uint64{0xfffffffefffffc2f, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}, + BiModulus: new(big.Int).SetBytes([]byte{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, + }), + } +} + +func getK256FpParams() *native.FieldParams { + k256FpInitonce.Do(k256FpParamsInit) + return &k256FpParams +} + +// k256FpArithmetic is a struct with all the methods needed for working +// in mod p +type k256FpArithmetic struct{} + +// ToMontgomery converts this field to montgomery form +func (f k256FpArithmetic) ToMontgomery(out, arg *[native.FieldLimbs]uint64) { + ToMontgomery((*MontgomeryDomainFieldElement)(out), (*NonMontgomeryDomainFieldElement)(arg)) +} + +// FromMontgomery converts this field from montgomery form +func (f k256FpArithmetic) FromMontgomery(out, arg *[native.FieldLimbs]uint64) { + FromMontgomery((*NonMontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Neg performs modular negation +func (f k256FpArithmetic) Neg(out, arg *[native.FieldLimbs]uint64) { + Opp((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Square performs modular square +func (f k256FpArithmetic) Square(out, arg *[native.FieldLimbs]uint64) { + Square((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Mul performs modular multiplication +func (f k256FpArithmetic) Mul(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Mul((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Add performs modular addition +func (f k256FpArithmetic) Add(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Add((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Sub performs modular subtraction +func (f k256FpArithmetic) Sub(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Sub((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Sqrt performs modular square root +func (f k256FpArithmetic) Sqrt(wasSquare *int, out, arg *[native.FieldLimbs]uint64) { + // p is congruent to 3 mod 4 we can compute + // sqrt using elem^(p+1)/4 mod p + // 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c + var s, t [native.FieldLimbs]uint64 + params := getK256FpParams() + native.Pow(&s, arg, &[native.FieldLimbs]uint64{ + 0xffffffffbfffff0c, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0x3fffffffffffffff, + }, params, f) + f.Square(&t, &s) + tv1 := &native.Field{Value: t, Params: params, Arithmetic: f} + tv2 := &native.Field{Value: *arg, Params: params, Arithmetic: f} + *wasSquare = tv1.Equal(tv2) + f.Selectznz(out, out, &s, *wasSquare) +} + +// Invert performs modular inverse +func (f k256FpArithmetic) Invert(wasInverted *int, out, arg *[native.FieldLimbs]uint64) { + // The binary representation of (p - 2) has 5 groups of 1s, with lengths in + // { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each group: + // [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] + var s, x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223 [native.FieldLimbs]uint64 + + native.Pow2k(&x2, arg, 1, f) + f.Mul(&x2, &x2, arg) + + native.Pow2k(&x3, &x2, 1, f) + f.Mul(&x3, &x3, arg) + + native.Pow2k(&x6, &x3, 3, f) + f.Mul(&x6, &x6, &x3) + + native.Pow2k(&x9, &x6, 3, f) + f.Mul(&x9, &x9, &x3) + + native.Pow2k(&x11, &x9, 2, f) + f.Mul(&x11, &x11, &x2) + + native.Pow2k(&x22, &x11, 11, f) + f.Mul(&x22, &x22, &x11) + + native.Pow2k(&x44, &x22, 22, f) + f.Mul(&x44, &x44, &x22) + + native.Pow2k(&x88, &x44, 44, f) + f.Mul(&x88, &x88, &x44) + + native.Pow2k(&x176, &x88, 88, f) + f.Mul(&x176, &x176, &x88) + + native.Pow2k(&x220, &x176, 44, f) + f.Mul(&x220, &x220, &x44) + + native.Pow2k(&x223, &x220, 3, f) + f.Mul(&x223, &x223, &x3) + + // Use sliding window over the group + native.Pow2k(&s, &x223, 23, f) + f.Mul(&s, &s, &x22) + native.Pow2k(&s, &s, 5, f) + f.Mul(&s, &s, arg) + native.Pow2k(&s, &s, 3, f) + f.Mul(&s, &s, &x2) + native.Pow2k(&s, &s, 2, f) + f.Mul(&s, &s, arg) + + tv := &native.Field{Value: *arg, Params: getK256FpParams(), Arithmetic: f} + + *wasInverted = tv.IsNonZero() + f.Selectznz(out, out, &s, *wasInverted) +} + +// FromBytes converts a little endian byte array into a field element +func (f k256FpArithmetic) FromBytes(out *[native.FieldLimbs]uint64, arg *[native.FieldBytes]byte) { + FromBytes(out, arg) +} + +// ToBytes converts a field element to a little endian byte array +func (f k256FpArithmetic) ToBytes(out *[native.FieldBytes]byte, arg *[native.FieldLimbs]uint64) { + ToBytes(out, arg) +} + +// Selectznz performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f k256FpArithmetic) Selectznz(out, arg1, arg2 *[native.FieldLimbs]uint64, choice int) { + Selectznz(out, uint1(choice), arg1, arg2) +} diff --git a/pkg/crypto/core/curves/native/k256/fp/fp_test.go b/pkg/crypto/core/curves/native/k256/fp/fp_test.go new file mode 100755 index 000000000..701e706f2 --- /dev/null +++ b/pkg/crypto/core/curves/native/k256/fp/fp_test.go @@ -0,0 +1,328 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fp + +import ( + crand "crypto/rand" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func TestFpSetOne(t *testing.T) { + fp := K256FpNew().SetOne() + require.NotNil(t, fp) + require.Equal(t, fp.Value, getK256FpParams().R) +} + +func TestFpSetUint64(t *testing.T) { + act := K256FpNew().SetUint64(1 << 60) + require.NotNil(t, act) + // Remember it will be in montgomery form + require.Equal(t, act.Value[0], uint64(0x1000000000000000)) +} + +func TestFpAdd(t *testing.T) { + lhs := K256FpNew().SetOne() + rhs := K256FpNew().SetOne() + exp := K256FpNew().SetUint64(2) + res := K256FpNew().Add(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, res.Equal(exp), 1) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + e := l + r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := K256FpNew().Add(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpSub(t *testing.T) { + lhs := K256FpNew().SetOne() + rhs := K256FpNew().SetOne() + exp := K256FpNew().SetZero() + res := K256FpNew().Sub(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + if l < r { + l, r = r, l + } + e := l - r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := K256FpNew().Sub(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpMul(t *testing.T) { + lhs := K256FpNew().SetOne() + rhs := K256FpNew().SetOne() + exp := K256FpNew().SetOne() + res := K256FpNew().Mul(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint32() + r := rand.Uint32() + e := uint64(l) * uint64(r) + lhs.SetUint64(uint64(l)) + rhs.SetUint64(uint64(r)) + exp.SetUint64(e) + + a := K256FpNew().Mul(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpDouble(t *testing.T) { + a := K256FpNew().SetUint64(2) + e := K256FpNew().SetUint64(4) + require.Equal(t, e, K256FpNew().Double(a)) + + for i := 0; i < 25; i++ { + tv := rand.Uint32() + ttv := uint64(tv) * 2 + a = K256FpNew().SetUint64(uint64(tv)) + e = K256FpNew().SetUint64(ttv) + require.Equal(t, e, K256FpNew().Double(a)) + } +} + +func TestFpSquare(t *testing.T) { + a := K256FpNew().SetUint64(4) + e := K256FpNew().SetUint64(16) + require.Equal(t, e, a.Square(a)) + + for i := 0; i < 25; i++ { + j := rand.Uint32() + exp := uint64(j) * uint64(j) + e.SetUint64(exp) + a.SetUint64(uint64(j)) + require.Equal(t, e, a.Square(a)) + } +} + +func TestFpNeg(t *testing.T) { + a := K256FpNew().SetOne() + a.Neg(a) + e := K256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xfffffffdfffff85e, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}) + require.Equal(t, e, a) +} + +func TestFpExp(t *testing.T) { + e := K256FpNew().SetUint64(8) + a := K256FpNew().SetUint64(2) + by := K256FpNew().SetUint64(3) + require.Equal(t, e, a.Exp(a, by)) +} + +func TestFpSqrt(t *testing.T) { + t1 := K256FpNew().SetUint64(2) + t2 := K256FpNew().Neg(t1) + t3 := K256FpNew().Square(t1) + _, wasSquare := t3.Sqrt(t3) + require.True(t, wasSquare) + require.Equal(t, 1, t1.Equal(t3)|t2.Equal(t3)) + t1.SetUint64(5) + _, wasSquare = K256FpNew().Sqrt(t1) + require.False(t, wasSquare) +} + +func TestFpInvert(t *testing.T) { + twoInv := K256FpNew().SetLimbs(&[native.FieldLimbs]uint64{ + 0xffffffff7ffffe18, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0x7fffffffffffffff, + }) + two := K256FpNew().SetUint64(2) + a, inverted := K256FpNew().Invert(two) + require.True(t, inverted) + require.Equal(t, a, twoInv) + + seven := K256FpNew().SetUint64(7) + sevenInv := K256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xdb6db6dab6db6afd, 0x6db6db6db6db6db6, 0xb6db6db6db6db6db, 0xdb6db6db6db6db6d}) + a, inverted = K256FpNew().Invert(seven) + require.True(t, inverted) + require.Equal(t, a, sevenInv) + + lhs := K256FpNew().SetUint64(9) + rhs := K256FpNew().SetUint64(3) + rhsInv, inverted := K256FpNew().Invert(rhs) + require.True(t, inverted) + require.Equal(t, rhs, K256FpNew().Mul(lhs, rhsInv)) + + rhs.SetZero() + _, inverted = K256FpNew().Invert(rhs) + require.False(t, inverted) +} + +func TestFpCMove(t *testing.T) { + t1 := K256FpNew().SetUint64(5) + t2 := K256FpNew().SetUint64(10) + require.Equal(t, t1, K256FpNew().CMove(t1, t2, 0)) + require.Equal(t, t2, K256FpNew().CMove(t1, t2, 1)) +} + +func TestFpBytes(t *testing.T) { + t1 := K256FpNew().SetUint64(99) + seq := t1.Bytes() + t2, err := K256FpNew().SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + + for i := 0; i < 25; i++ { + t1.SetUint64(rand.Uint64()) + seq = t1.Bytes() + _, err = t2.SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + } +} + +func TestFpCmp(t *testing.T) { + tests := []struct { + a *native.Field + b *native.Field + e int + }{ + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{2731658267414164836, 14655288906067898431, 6537465423330262322, 8306191141697566219}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{6472764012681988529, 10848812988401906064, 2961825807536828898, 4282183981941645679}), + e: 1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{8023004109510539223, 4652004072850285717, 1877219145646046927, 383214385093921911}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{10099384440823804262, 16139476942229308465, 8636966320777393798, 5435928725024696785}), + e: -1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{3741840066202388211, 12165774400417314871, 16619312580230515379, 16195032234110087705}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{3905865991286066744, 543690822309071825, 17963103015950210055, 3745476720756119742}), + e: 1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{16660853697936147788, 7799793619412111108, 13515141085171033220, 2641079731236069032}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{17790588295388238399, 571847801379669440, 14537208974498222469, 12792570372087452754}), + e: -1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{3912839285384959186, 2701177075110484070, 6453856448115499033, 6475797457962597458}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{1282566391665688512, 13503640416992806563, 2962240104675990153, 3374904770947067689}), + e: 1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{5716631803409360103, 7859567470082614154, 12747956220853330146, 18434584096087315020}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{16317076441459028418, 12854146980376319601, 2258436689269031143, 9531877130792223752}), + e: 1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{17955191469941083403, 10350326247207200880, 17263512235150705075, 12700328451238078022}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{6767595547459644695, 7146403825494928147, 12269344038346710612, 9122477829383225603}), + e: 1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{17099388671847024438, 6426264987820696548, 10641143464957227405, 7709745403700754098}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{10799154372990268556, 17178492485719929374, 5705777922258988797, 8051037767683567782}), + e: -1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{4567139260680454325, 1629385880182139061, 16607020832317899145, 1261011562621553200}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{13487234491304534488, 17872642955936089265, 17651026784972590233, 9468934643333871559}), + e: -1, + }, + { + a: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{18071070103467571798, 11787850505799426140, 10631355976141928593, 4867785203635092610}), + b: K256FpNew().SetRaw(&[native.FieldLimbs]uint64{12596443599426461624, 10176122686151524591, 17075755296887483439, 6726169532695070719}), + e: -1, + }, + } + + for _, test := range tests { + require.Equal(t, test.e, test.a.Cmp(test.b)) + require.Equal(t, -test.e, test.b.Cmp(test.a)) + require.Equal(t, 0, test.a.Cmp(test.a)) + require.Equal(t, 0, test.b.Cmp(test.b)) + } +} + +func TestFpBigInt(t *testing.T) { + t1 := K256FpNew().SetBigInt(big.NewInt(9999)) + t2 := K256FpNew().SetBigInt(t1.BigInt()) + require.Equal(t, t1, t2) + + e := K256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xc6c6c6c63939371d, 0xc6c6c6c6c6c6c6c6, 0x8d8d8dd28485081d, 0x8484848484848484}) + b := new(big.Int).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}) + t1.SetBigInt(b) + require.Equal(t, e, t1) + e.Value[0] = 0x39393938c6c6c512 + e.Value[1] = 0x3939393939393939 + e.Value[2] = 0x7272722d7b7af7e2 + e.Value[3] = 0x7b7b7b7b7b7b7b7b + b.Neg(b) + t1.SetBigInt(b) + require.Equal(t, e, t1) +} + +func TestFpSetBytesWide(t *testing.T) { + e := K256FpNew().SetRaw(&[native.FieldLimbs]uint64{0x6aa784623e2d641e, 0x7c40617d755bae27, 0x206b7be66ed7b71b, 0x6d1e4fc581e19dc2}) + + a := K256FpNew().SetBytesWide(&[64]byte{ + 0x69, 0x23, 0x5a, 0x0b, 0xce, 0x0c, 0xa8, 0x64, + 0x3c, 0x78, 0xbc, 0x01, 0x05, 0xef, 0xf2, 0x84, + 0xde, 0xbb, 0x6b, 0xc8, 0x63, 0x5e, 0x6e, 0x69, + 0x62, 0xcc, 0xc6, 0x2d, 0xf5, 0x72, 0x40, 0x92, + 0x28, 0x11, 0xd6, 0xc8, 0x07, 0xa5, 0x88, 0x82, + 0xfe, 0xe3, 0x97, 0xf6, 0x1e, 0xfb, 0x2e, 0x3b, + 0x27, 0x5f, 0x85, 0x06, 0x8d, 0x99, 0xa4, 0x75, + 0xc0, 0x2c, 0x71, 0x69, 0x9e, 0x58, 0xea, 0x52, + }) + require.Equal(t, e, a) +} + +func TestFpSetBytesWideBigInt(t *testing.T) { + params := getK256FpParams() + var tv2 [64]byte + for i := 0; i < 25; i++ { + _, _ = crand.Read(tv2[:]) + e := new(big.Int).SetBytes(tv2[:]) + e.Mod(e, params.BiModulus) + + tv := internal.ReverseScalarBytes(tv2[:]) + copy(tv2[:], tv) + a := K256FpNew().SetBytesWide(&tv2) + require.Equal(t, 0, e.Cmp(a.BigInt())) + } +} diff --git a/pkg/crypto/core/curves/native/k256/fp/secp256k1_fp.go b/pkg/crypto/core/curves/native/k256/fp/secp256k1_fp.go new file mode 100755 index 000000000..f38225d9c --- /dev/null +++ b/pkg/crypto/core/curves/native/k256/fp/secp256k1_fp.go @@ -0,0 +1,1894 @@ +// Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --lang Go --no-wide-int --relax-primitive-carry-to-bitwidth 32,64 --cmovznz-by-mul --internal-static --package-case flatcase --public-function-case UpperCamelCase --private-function-case camelCase --public-type-case UpperCamelCase --private-type-case camelCase --no-prefix-fiat --doc-newline-in-typedef-bounds --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' --doc-text-before-function-name ” --doc-text-before-type-name ” --package-name secp256k1 ” 64 '2^256 - 2^32 - 977' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp +// +// curve description (via package name): secp256k1 +// +// machine_wordsize = 64 (from "64") +// +// requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp +// +// m = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f (from "2^256 - 2^32 - 977") +// +// NOTE: In addition to the bounds specified above each function, all +// +// functions synthesized for this Montgomery arithmetic require the +// +// input to be strictly less than the prime modulus (m), and also +// +// require the input to be in the unique saturated representation. +// +// All functions also ensure that these two properties are true of +// +// return values. +// +// Computed values: +// +// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) +// +// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) +// +// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in +// +// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 +package fp + +import "math/bits" + +type uint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 +type int1 int64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 + +// MontgomeryDomainFieldElement is a field element in the Montgomery domain. +// +// Bounds: +// +// [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type MontgomeryDomainFieldElement [4]uint64 + +// NonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain. +// +// Bounds: +// +// [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type NonMontgomeryDomainFieldElement [4]uint64 + +// cmovznzU64 is a single-word conditional move. +// +// Postconditions: +// +// out1 = (if arg1 = 0 then arg2 else arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [0x0 ~> 0xffffffffffffffff] +// arg3: [0x0 ~> 0xffffffffffffffff] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func cmovznzU64(out1 *uint64, arg1 uint1, arg2 uint64, arg3 uint64) { + x1 := (uint64(arg1) * 0xffffffffffffffff) + x2 := ((x1 & arg3) | ((^x1) & arg2)) + *out1 = x2 +} + +// Mul multiplies two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Mul(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg2[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg2[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg2[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg2[0]) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + x19 := (uint64(uint1(x18)) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0xd838091dd2253531) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0xffffffffffffffff) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0xffffffffffffffff) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0xffffffffffffffff) + var x28 uint64 + var x29 uint64 + x29, x28 = bits.Mul64(x20, 0xfffffffefffffc2f) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x29, x26, uint64(0x0)) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x27, x24, uint64(uint1(x31))) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x25, x22, uint64(uint1(x33))) + x36 := (uint64(uint1(x35)) + x23) + var x38 uint64 + _, x38 = bits.Add64(x11, x28, uint64(0x0)) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x13, x30, uint64(uint1(x38))) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x15, x32, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64(x17, x34, uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Add64(x19, x36, uint64(uint1(x44))) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg2[3]) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x1, arg2[2]) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x1, arg2[1]) + var x53 uint64 + var x54 uint64 + x54, x53 = bits.Mul64(x1, arg2[0]) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x54, x51, uint64(0x0)) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x52, x49, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x50, x47, uint64(uint1(x58))) + x61 := (uint64(uint1(x60)) + x48) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x39, x53, uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x41, x55, uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x43, x57, uint64(uint1(x65))) + var x68 uint64 + var x69 uint64 + x68, x69 = bits.Add64(x45, x59, uint64(uint1(x67))) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(uint64(uint1(x46)), x61, uint64(uint1(x69))) + var x72 uint64 + _, x72 = bits.Mul64(x62, 0xd838091dd2253531) + var x74 uint64 + var x75 uint64 + x75, x74 = bits.Mul64(x72, 0xffffffffffffffff) + var x76 uint64 + var x77 uint64 + x77, x76 = bits.Mul64(x72, 0xffffffffffffffff) + var x78 uint64 + var x79 uint64 + x79, x78 = bits.Mul64(x72, 0xffffffffffffffff) + var x80 uint64 + var x81 uint64 + x81, x80 = bits.Mul64(x72, 0xfffffffefffffc2f) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x81, x78, uint64(0x0)) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x79, x76, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x77, x74, uint64(uint1(x85))) + x88 := (uint64(uint1(x87)) + x75) + var x90 uint64 + _, x90 = bits.Add64(x62, x80, uint64(0x0)) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(x64, x82, uint64(uint1(x90))) + var x93 uint64 + var x94 uint64 + x93, x94 = bits.Add64(x66, x84, uint64(uint1(x92))) + var x95 uint64 + var x96 uint64 + x95, x96 = bits.Add64(x68, x86, uint64(uint1(x94))) + var x97 uint64 + var x98 uint64 + x97, x98 = bits.Add64(x70, x88, uint64(uint1(x96))) + x99 := (uint64(uint1(x98)) + uint64(uint1(x71))) + var x100 uint64 + var x101 uint64 + x101, x100 = bits.Mul64(x2, arg2[3]) + var x102 uint64 + var x103 uint64 + x103, x102 = bits.Mul64(x2, arg2[2]) + var x104 uint64 + var x105 uint64 + x105, x104 = bits.Mul64(x2, arg2[1]) + var x106 uint64 + var x107 uint64 + x107, x106 = bits.Mul64(x2, arg2[0]) + var x108 uint64 + var x109 uint64 + x108, x109 = bits.Add64(x107, x104, uint64(0x0)) + var x110 uint64 + var x111 uint64 + x110, x111 = bits.Add64(x105, x102, uint64(uint1(x109))) + var x112 uint64 + var x113 uint64 + x112, x113 = bits.Add64(x103, x100, uint64(uint1(x111))) + x114 := (uint64(uint1(x113)) + x101) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x91, x106, uint64(0x0)) + var x117 uint64 + var x118 uint64 + x117, x118 = bits.Add64(x93, x108, uint64(uint1(x116))) + var x119 uint64 + var x120 uint64 + x119, x120 = bits.Add64(x95, x110, uint64(uint1(x118))) + var x121 uint64 + var x122 uint64 + x121, x122 = bits.Add64(x97, x112, uint64(uint1(x120))) + var x123 uint64 + var x124 uint64 + x123, x124 = bits.Add64(x99, x114, uint64(uint1(x122))) + var x125 uint64 + _, x125 = bits.Mul64(x115, 0xd838091dd2253531) + var x127 uint64 + var x128 uint64 + x128, x127 = bits.Mul64(x125, 0xffffffffffffffff) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x125, 0xffffffffffffffff) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x125, 0xffffffffffffffff) + var x133 uint64 + var x134 uint64 + x134, x133 = bits.Mul64(x125, 0xfffffffefffffc2f) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x134, x131, uint64(0x0)) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x132, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(x130, x127, uint64(uint1(x138))) + x141 := (uint64(uint1(x140)) + x128) + var x143 uint64 + _, x143 = bits.Add64(x115, x133, uint64(0x0)) + var x144 uint64 + var x145 uint64 + x144, x145 = bits.Add64(x117, x135, uint64(uint1(x143))) + var x146 uint64 + var x147 uint64 + x146, x147 = bits.Add64(x119, x137, uint64(uint1(x145))) + var x148 uint64 + var x149 uint64 + x148, x149 = bits.Add64(x121, x139, uint64(uint1(x147))) + var x150 uint64 + var x151 uint64 + x150, x151 = bits.Add64(x123, x141, uint64(uint1(x149))) + x152 := (uint64(uint1(x151)) + uint64(uint1(x124))) + var x153 uint64 + var x154 uint64 + x154, x153 = bits.Mul64(x3, arg2[3]) + var x155 uint64 + var x156 uint64 + x156, x155 = bits.Mul64(x3, arg2[2]) + var x157 uint64 + var x158 uint64 + x158, x157 = bits.Mul64(x3, arg2[1]) + var x159 uint64 + var x160 uint64 + x160, x159 = bits.Mul64(x3, arg2[0]) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Add64(x160, x157, uint64(0x0)) + var x163 uint64 + var x164 uint64 + x163, x164 = bits.Add64(x158, x155, uint64(uint1(x162))) + var x165 uint64 + var x166 uint64 + x165, x166 = bits.Add64(x156, x153, uint64(uint1(x164))) + x167 := (uint64(uint1(x166)) + x154) + var x168 uint64 + var x169 uint64 + x168, x169 = bits.Add64(x144, x159, uint64(0x0)) + var x170 uint64 + var x171 uint64 + x170, x171 = bits.Add64(x146, x161, uint64(uint1(x169))) + var x172 uint64 + var x173 uint64 + x172, x173 = bits.Add64(x148, x163, uint64(uint1(x171))) + var x174 uint64 + var x175 uint64 + x174, x175 = bits.Add64(x150, x165, uint64(uint1(x173))) + var x176 uint64 + var x177 uint64 + x176, x177 = bits.Add64(x152, x167, uint64(uint1(x175))) + var x178 uint64 + _, x178 = bits.Mul64(x168, 0xd838091dd2253531) + var x180 uint64 + var x181 uint64 + x181, x180 = bits.Mul64(x178, 0xffffffffffffffff) + var x182 uint64 + var x183 uint64 + x183, x182 = bits.Mul64(x178, 0xffffffffffffffff) + var x184 uint64 + var x185 uint64 + x185, x184 = bits.Mul64(x178, 0xffffffffffffffff) + var x186 uint64 + var x187 uint64 + x187, x186 = bits.Mul64(x178, 0xfffffffefffffc2f) + var x188 uint64 + var x189 uint64 + x188, x189 = bits.Add64(x187, x184, uint64(0x0)) + var x190 uint64 + var x191 uint64 + x190, x191 = bits.Add64(x185, x182, uint64(uint1(x189))) + var x192 uint64 + var x193 uint64 + x192, x193 = bits.Add64(x183, x180, uint64(uint1(x191))) + x194 := (uint64(uint1(x193)) + x181) + var x196 uint64 + _, x196 = bits.Add64(x168, x186, uint64(0x0)) + var x197 uint64 + var x198 uint64 + x197, x198 = bits.Add64(x170, x188, uint64(uint1(x196))) + var x199 uint64 + var x200 uint64 + x199, x200 = bits.Add64(x172, x190, uint64(uint1(x198))) + var x201 uint64 + var x202 uint64 + x201, x202 = bits.Add64(x174, x192, uint64(uint1(x200))) + var x203 uint64 + var x204 uint64 + x203, x204 = bits.Add64(x176, x194, uint64(uint1(x202))) + x205 := (uint64(uint1(x204)) + uint64(uint1(x177))) + var x206 uint64 + var x207 uint64 + x206, x207 = bits.Sub64(x197, 0xfffffffefffffc2f, uint64(0x0)) + var x208 uint64 + var x209 uint64 + x208, x209 = bits.Sub64(x199, 0xffffffffffffffff, uint64(uint1(x207))) + var x210 uint64 + var x211 uint64 + x210, x211 = bits.Sub64(x201, 0xffffffffffffffff, uint64(uint1(x209))) + var x212 uint64 + var x213 uint64 + x212, x213 = bits.Sub64(x203, 0xffffffffffffffff, uint64(uint1(x211))) + var x215 uint64 + _, x215 = bits.Sub64(x205, uint64(0x0), uint64(uint1(x213))) + var x216 uint64 + cmovznzU64(&x216, uint1(x215), x206, x197) + var x217 uint64 + cmovznzU64(&x217, uint1(x215), x208, x199) + var x218 uint64 + cmovznzU64(&x218, uint1(x215), x210, x201) + var x219 uint64 + cmovznzU64(&x219, uint1(x215), x212, x203) + out1[0] = x216 + out1[1] = x217 + out1[2] = x218 + out1[3] = x219 +} + +// Square squares a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m +// 0 ≤ eval out1 < m +func Square(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg1[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg1[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg1[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg1[0]) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + x19 := (uint64(uint1(x18)) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0xd838091dd2253531) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0xffffffffffffffff) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0xffffffffffffffff) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0xffffffffffffffff) + var x28 uint64 + var x29 uint64 + x29, x28 = bits.Mul64(x20, 0xfffffffefffffc2f) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x29, x26, uint64(0x0)) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x27, x24, uint64(uint1(x31))) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x25, x22, uint64(uint1(x33))) + x36 := (uint64(uint1(x35)) + x23) + var x38 uint64 + _, x38 = bits.Add64(x11, x28, uint64(0x0)) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x13, x30, uint64(uint1(x38))) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x15, x32, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64(x17, x34, uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Add64(x19, x36, uint64(uint1(x44))) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg1[3]) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x1, arg1[2]) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x1, arg1[1]) + var x53 uint64 + var x54 uint64 + x54, x53 = bits.Mul64(x1, arg1[0]) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x54, x51, uint64(0x0)) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x52, x49, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x50, x47, uint64(uint1(x58))) + x61 := (uint64(uint1(x60)) + x48) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x39, x53, uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x41, x55, uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x43, x57, uint64(uint1(x65))) + var x68 uint64 + var x69 uint64 + x68, x69 = bits.Add64(x45, x59, uint64(uint1(x67))) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(uint64(uint1(x46)), x61, uint64(uint1(x69))) + var x72 uint64 + _, x72 = bits.Mul64(x62, 0xd838091dd2253531) + var x74 uint64 + var x75 uint64 + x75, x74 = bits.Mul64(x72, 0xffffffffffffffff) + var x76 uint64 + var x77 uint64 + x77, x76 = bits.Mul64(x72, 0xffffffffffffffff) + var x78 uint64 + var x79 uint64 + x79, x78 = bits.Mul64(x72, 0xffffffffffffffff) + var x80 uint64 + var x81 uint64 + x81, x80 = bits.Mul64(x72, 0xfffffffefffffc2f) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x81, x78, uint64(0x0)) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x79, x76, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x77, x74, uint64(uint1(x85))) + x88 := (uint64(uint1(x87)) + x75) + var x90 uint64 + _, x90 = bits.Add64(x62, x80, uint64(0x0)) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(x64, x82, uint64(uint1(x90))) + var x93 uint64 + var x94 uint64 + x93, x94 = bits.Add64(x66, x84, uint64(uint1(x92))) + var x95 uint64 + var x96 uint64 + x95, x96 = bits.Add64(x68, x86, uint64(uint1(x94))) + var x97 uint64 + var x98 uint64 + x97, x98 = bits.Add64(x70, x88, uint64(uint1(x96))) + x99 := (uint64(uint1(x98)) + uint64(uint1(x71))) + var x100 uint64 + var x101 uint64 + x101, x100 = bits.Mul64(x2, arg1[3]) + var x102 uint64 + var x103 uint64 + x103, x102 = bits.Mul64(x2, arg1[2]) + var x104 uint64 + var x105 uint64 + x105, x104 = bits.Mul64(x2, arg1[1]) + var x106 uint64 + var x107 uint64 + x107, x106 = bits.Mul64(x2, arg1[0]) + var x108 uint64 + var x109 uint64 + x108, x109 = bits.Add64(x107, x104, uint64(0x0)) + var x110 uint64 + var x111 uint64 + x110, x111 = bits.Add64(x105, x102, uint64(uint1(x109))) + var x112 uint64 + var x113 uint64 + x112, x113 = bits.Add64(x103, x100, uint64(uint1(x111))) + x114 := (uint64(uint1(x113)) + x101) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x91, x106, uint64(0x0)) + var x117 uint64 + var x118 uint64 + x117, x118 = bits.Add64(x93, x108, uint64(uint1(x116))) + var x119 uint64 + var x120 uint64 + x119, x120 = bits.Add64(x95, x110, uint64(uint1(x118))) + var x121 uint64 + var x122 uint64 + x121, x122 = bits.Add64(x97, x112, uint64(uint1(x120))) + var x123 uint64 + var x124 uint64 + x123, x124 = bits.Add64(x99, x114, uint64(uint1(x122))) + var x125 uint64 + _, x125 = bits.Mul64(x115, 0xd838091dd2253531) + var x127 uint64 + var x128 uint64 + x128, x127 = bits.Mul64(x125, 0xffffffffffffffff) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x125, 0xffffffffffffffff) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x125, 0xffffffffffffffff) + var x133 uint64 + var x134 uint64 + x134, x133 = bits.Mul64(x125, 0xfffffffefffffc2f) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x134, x131, uint64(0x0)) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x132, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(x130, x127, uint64(uint1(x138))) + x141 := (uint64(uint1(x140)) + x128) + var x143 uint64 + _, x143 = bits.Add64(x115, x133, uint64(0x0)) + var x144 uint64 + var x145 uint64 + x144, x145 = bits.Add64(x117, x135, uint64(uint1(x143))) + var x146 uint64 + var x147 uint64 + x146, x147 = bits.Add64(x119, x137, uint64(uint1(x145))) + var x148 uint64 + var x149 uint64 + x148, x149 = bits.Add64(x121, x139, uint64(uint1(x147))) + var x150 uint64 + var x151 uint64 + x150, x151 = bits.Add64(x123, x141, uint64(uint1(x149))) + x152 := (uint64(uint1(x151)) + uint64(uint1(x124))) + var x153 uint64 + var x154 uint64 + x154, x153 = bits.Mul64(x3, arg1[3]) + var x155 uint64 + var x156 uint64 + x156, x155 = bits.Mul64(x3, arg1[2]) + var x157 uint64 + var x158 uint64 + x158, x157 = bits.Mul64(x3, arg1[1]) + var x159 uint64 + var x160 uint64 + x160, x159 = bits.Mul64(x3, arg1[0]) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Add64(x160, x157, uint64(0x0)) + var x163 uint64 + var x164 uint64 + x163, x164 = bits.Add64(x158, x155, uint64(uint1(x162))) + var x165 uint64 + var x166 uint64 + x165, x166 = bits.Add64(x156, x153, uint64(uint1(x164))) + x167 := (uint64(uint1(x166)) + x154) + var x168 uint64 + var x169 uint64 + x168, x169 = bits.Add64(x144, x159, uint64(0x0)) + var x170 uint64 + var x171 uint64 + x170, x171 = bits.Add64(x146, x161, uint64(uint1(x169))) + var x172 uint64 + var x173 uint64 + x172, x173 = bits.Add64(x148, x163, uint64(uint1(x171))) + var x174 uint64 + var x175 uint64 + x174, x175 = bits.Add64(x150, x165, uint64(uint1(x173))) + var x176 uint64 + var x177 uint64 + x176, x177 = bits.Add64(x152, x167, uint64(uint1(x175))) + var x178 uint64 + _, x178 = bits.Mul64(x168, 0xd838091dd2253531) + var x180 uint64 + var x181 uint64 + x181, x180 = bits.Mul64(x178, 0xffffffffffffffff) + var x182 uint64 + var x183 uint64 + x183, x182 = bits.Mul64(x178, 0xffffffffffffffff) + var x184 uint64 + var x185 uint64 + x185, x184 = bits.Mul64(x178, 0xffffffffffffffff) + var x186 uint64 + var x187 uint64 + x187, x186 = bits.Mul64(x178, 0xfffffffefffffc2f) + var x188 uint64 + var x189 uint64 + x188, x189 = bits.Add64(x187, x184, uint64(0x0)) + var x190 uint64 + var x191 uint64 + x190, x191 = bits.Add64(x185, x182, uint64(uint1(x189))) + var x192 uint64 + var x193 uint64 + x192, x193 = bits.Add64(x183, x180, uint64(uint1(x191))) + x194 := (uint64(uint1(x193)) + x181) + var x196 uint64 + _, x196 = bits.Add64(x168, x186, uint64(0x0)) + var x197 uint64 + var x198 uint64 + x197, x198 = bits.Add64(x170, x188, uint64(uint1(x196))) + var x199 uint64 + var x200 uint64 + x199, x200 = bits.Add64(x172, x190, uint64(uint1(x198))) + var x201 uint64 + var x202 uint64 + x201, x202 = bits.Add64(x174, x192, uint64(uint1(x200))) + var x203 uint64 + var x204 uint64 + x203, x204 = bits.Add64(x176, x194, uint64(uint1(x202))) + x205 := (uint64(uint1(x204)) + uint64(uint1(x177))) + var x206 uint64 + var x207 uint64 + x206, x207 = bits.Sub64(x197, 0xfffffffefffffc2f, uint64(0x0)) + var x208 uint64 + var x209 uint64 + x208, x209 = bits.Sub64(x199, 0xffffffffffffffff, uint64(uint1(x207))) + var x210 uint64 + var x211 uint64 + x210, x211 = bits.Sub64(x201, 0xffffffffffffffff, uint64(uint1(x209))) + var x212 uint64 + var x213 uint64 + x212, x213 = bits.Sub64(x203, 0xffffffffffffffff, uint64(uint1(x211))) + var x215 uint64 + _, x215 = bits.Sub64(x205, uint64(0x0), uint64(uint1(x213))) + var x216 uint64 + cmovznzU64(&x216, uint1(x215), x206, x197) + var x217 uint64 + cmovznzU64(&x217, uint1(x215), x208, x199) + var x218 uint64 + cmovznzU64(&x218, uint1(x215), x210, x201) + var x219 uint64 + cmovznzU64(&x219, uint1(x215), x212, x203) + out1[0] = x216 + out1[1] = x217 + out1[2] = x218 + out1[3] = x219 +} + +// Add adds two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Add(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Add64(arg1[0], arg2[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Add64(arg1[1], arg2[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Add64(arg1[2], arg2[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Add64(arg1[3], arg2[3], uint64(uint1(x6))) + var x9 uint64 + var x10 uint64 + x9, x10 = bits.Sub64(x1, 0xfffffffefffffc2f, uint64(0x0)) + var x11 uint64 + var x12 uint64 + x11, x12 = bits.Sub64(x3, 0xffffffffffffffff, uint64(uint1(x10))) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Sub64(x5, 0xffffffffffffffff, uint64(uint1(x12))) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Sub64(x7, 0xffffffffffffffff, uint64(uint1(x14))) + var x18 uint64 + _, x18 = bits.Sub64(uint64(uint1(x8)), uint64(0x0), uint64(uint1(x16))) + var x19 uint64 + cmovznzU64(&x19, uint1(x18), x9, x1) + var x20 uint64 + cmovznzU64(&x20, uint1(x18), x11, x3) + var x21 uint64 + cmovznzU64(&x21, uint1(x18), x13, x5) + var x22 uint64 + cmovznzU64(&x22, uint1(x18), x15, x7) + out1[0] = x19 + out1[1] = x20 + out1[2] = x21 + out1[3] = x22 +} + +// Sub subtracts two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Sub(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Sub64(arg1[0], arg2[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Sub64(arg1[1], arg2[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Sub64(arg1[2], arg2[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Sub64(arg1[3], arg2[3], uint64(uint1(x6))) + var x9 uint64 + cmovznzU64(&x9, uint1(x8), uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x10, x11 = bits.Add64(x1, (x9 & 0xfffffffefffffc2f), uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x3, x9, uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x5, x9, uint64(uint1(x13))) + var x16 uint64 + x16, _ = bits.Add64(x7, x9, uint64(uint1(x15))) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// Opp negates a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m +// 0 ≤ eval out1 < m +func Opp(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Sub64(uint64(0x0), arg1[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Sub64(uint64(0x0), arg1[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Sub64(uint64(0x0), arg1[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Sub64(uint64(0x0), arg1[3], uint64(uint1(x6))) + var x9 uint64 + cmovznzU64(&x9, uint1(x8), uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x10, x11 = bits.Add64(x1, (x9 & 0xfffffffefffffc2f), uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x3, x9, uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x5, x9, uint64(uint1(x13))) + var x16 uint64 + x16, _ = bits.Add64(x7, x9, uint64(uint1(x15))) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// FromMontgomery translates a field element out of the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m +// 0 ≤ eval out1 < m +func FromMontgomery(out1 *NonMontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + x1 := arg1[0] + var x2 uint64 + _, x2 = bits.Mul64(x1, 0xd838091dd2253531) + var x4 uint64 + var x5 uint64 + x5, x4 = bits.Mul64(x2, 0xffffffffffffffff) + var x6 uint64 + var x7 uint64 + x7, x6 = bits.Mul64(x2, 0xffffffffffffffff) + var x8 uint64 + var x9 uint64 + x9, x8 = bits.Mul64(x2, 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x11, x10 = bits.Mul64(x2, 0xfffffffefffffc2f) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x11, x8, uint64(0x0)) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x9, x6, uint64(uint1(x13))) + var x16 uint64 + var x17 uint64 + x16, x17 = bits.Add64(x7, x4, uint64(uint1(x15))) + var x19 uint64 + _, x19 = bits.Add64(x1, x10, uint64(0x0)) + var x20 uint64 + var x21 uint64 + x20, x21 = bits.Add64(uint64(0x0), x12, uint64(uint1(x19))) + var x22 uint64 + var x23 uint64 + x22, x23 = bits.Add64(uint64(0x0), x14, uint64(uint1(x21))) + var x24 uint64 + var x25 uint64 + x24, x25 = bits.Add64(uint64(0x0), x16, uint64(uint1(x23))) + var x26 uint64 + var x27 uint64 + x26, x27 = bits.Add64(uint64(0x0), (uint64(uint1(x17)) + x5), uint64(uint1(x25))) + var x28 uint64 + var x29 uint64 + x28, x29 = bits.Add64(x20, arg1[1], uint64(0x0)) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x22, uint64(0x0), uint64(uint1(x29))) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x24, uint64(0x0), uint64(uint1(x31))) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x26, uint64(0x0), uint64(uint1(x33))) + var x36 uint64 + _, x36 = bits.Mul64(x28, 0xd838091dd2253531) + var x38 uint64 + var x39 uint64 + x39, x38 = bits.Mul64(x36, 0xffffffffffffffff) + var x40 uint64 + var x41 uint64 + x41, x40 = bits.Mul64(x36, 0xffffffffffffffff) + var x42 uint64 + var x43 uint64 + x43, x42 = bits.Mul64(x36, 0xffffffffffffffff) + var x44 uint64 + var x45 uint64 + x45, x44 = bits.Mul64(x36, 0xfffffffefffffc2f) + var x46 uint64 + var x47 uint64 + x46, x47 = bits.Add64(x45, x42, uint64(0x0)) + var x48 uint64 + var x49 uint64 + x48, x49 = bits.Add64(x43, x40, uint64(uint1(x47))) + var x50 uint64 + var x51 uint64 + x50, x51 = bits.Add64(x41, x38, uint64(uint1(x49))) + var x53 uint64 + _, x53 = bits.Add64(x28, x44, uint64(0x0)) + var x54 uint64 + var x55 uint64 + x54, x55 = bits.Add64(x30, x46, uint64(uint1(x53))) + var x56 uint64 + var x57 uint64 + x56, x57 = bits.Add64(x32, x48, uint64(uint1(x55))) + var x58 uint64 + var x59 uint64 + x58, x59 = bits.Add64(x34, x50, uint64(uint1(x57))) + var x60 uint64 + var x61 uint64 + x60, x61 = bits.Add64((uint64(uint1(x35)) + uint64(uint1(x27))), (uint64(uint1(x51)) + x39), uint64(uint1(x59))) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x54, arg1[2], uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x56, uint64(0x0), uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x58, uint64(0x0), uint64(uint1(x65))) + var x68 uint64 + var x69 uint64 + x68, x69 = bits.Add64(x60, uint64(0x0), uint64(uint1(x67))) + var x70 uint64 + _, x70 = bits.Mul64(x62, 0xd838091dd2253531) + var x72 uint64 + var x73 uint64 + x73, x72 = bits.Mul64(x70, 0xffffffffffffffff) + var x74 uint64 + var x75 uint64 + x75, x74 = bits.Mul64(x70, 0xffffffffffffffff) + var x76 uint64 + var x77 uint64 + x77, x76 = bits.Mul64(x70, 0xffffffffffffffff) + var x78 uint64 + var x79 uint64 + x79, x78 = bits.Mul64(x70, 0xfffffffefffffc2f) + var x80 uint64 + var x81 uint64 + x80, x81 = bits.Add64(x79, x76, uint64(0x0)) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x77, x74, uint64(uint1(x81))) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x75, x72, uint64(uint1(x83))) + var x87 uint64 + _, x87 = bits.Add64(x62, x78, uint64(0x0)) + var x88 uint64 + var x89 uint64 + x88, x89 = bits.Add64(x64, x80, uint64(uint1(x87))) + var x90 uint64 + var x91 uint64 + x90, x91 = bits.Add64(x66, x82, uint64(uint1(x89))) + var x92 uint64 + var x93 uint64 + x92, x93 = bits.Add64(x68, x84, uint64(uint1(x91))) + var x94 uint64 + var x95 uint64 + x94, x95 = bits.Add64((uint64(uint1(x69)) + uint64(uint1(x61))), (uint64(uint1(x85)) + x73), uint64(uint1(x93))) + var x96 uint64 + var x97 uint64 + x96, x97 = bits.Add64(x88, arg1[3], uint64(0x0)) + var x98 uint64 + var x99 uint64 + x98, x99 = bits.Add64(x90, uint64(0x0), uint64(uint1(x97))) + var x100 uint64 + var x101 uint64 + x100, x101 = bits.Add64(x92, uint64(0x0), uint64(uint1(x99))) + var x102 uint64 + var x103 uint64 + x102, x103 = bits.Add64(x94, uint64(0x0), uint64(uint1(x101))) + var x104 uint64 + _, x104 = bits.Mul64(x96, 0xd838091dd2253531) + var x106 uint64 + var x107 uint64 + x107, x106 = bits.Mul64(x104, 0xffffffffffffffff) + var x108 uint64 + var x109 uint64 + x109, x108 = bits.Mul64(x104, 0xffffffffffffffff) + var x110 uint64 + var x111 uint64 + x111, x110 = bits.Mul64(x104, 0xffffffffffffffff) + var x112 uint64 + var x113 uint64 + x113, x112 = bits.Mul64(x104, 0xfffffffefffffc2f) + var x114 uint64 + var x115 uint64 + x114, x115 = bits.Add64(x113, x110, uint64(0x0)) + var x116 uint64 + var x117 uint64 + x116, x117 = bits.Add64(x111, x108, uint64(uint1(x115))) + var x118 uint64 + var x119 uint64 + x118, x119 = bits.Add64(x109, x106, uint64(uint1(x117))) + var x121 uint64 + _, x121 = bits.Add64(x96, x112, uint64(0x0)) + var x122 uint64 + var x123 uint64 + x122, x123 = bits.Add64(x98, x114, uint64(uint1(x121))) + var x124 uint64 + var x125 uint64 + x124, x125 = bits.Add64(x100, x116, uint64(uint1(x123))) + var x126 uint64 + var x127 uint64 + x126, x127 = bits.Add64(x102, x118, uint64(uint1(x125))) + var x128 uint64 + var x129 uint64 + x128, x129 = bits.Add64((uint64(uint1(x103)) + uint64(uint1(x95))), (uint64(uint1(x119)) + x107), uint64(uint1(x127))) + var x130 uint64 + var x131 uint64 + x130, x131 = bits.Sub64(x122, 0xfffffffefffffc2f, uint64(0x0)) + var x132 uint64 + var x133 uint64 + x132, x133 = bits.Sub64(x124, 0xffffffffffffffff, uint64(uint1(x131))) + var x134 uint64 + var x135 uint64 + x134, x135 = bits.Sub64(x126, 0xffffffffffffffff, uint64(uint1(x133))) + var x136 uint64 + var x137 uint64 + x136, x137 = bits.Sub64(x128, 0xffffffffffffffff, uint64(uint1(x135))) + var x139 uint64 + _, x139 = bits.Sub64(uint64(uint1(x129)), uint64(0x0), uint64(uint1(x137))) + var x140 uint64 + cmovznzU64(&x140, uint1(x139), x130, x122) + var x141 uint64 + cmovznzU64(&x141, uint1(x139), x132, x124) + var x142 uint64 + cmovznzU64(&x142, uint1(x139), x134, x126) + var x143 uint64 + cmovznzU64(&x143, uint1(x139), x136, x128) + out1[0] = x140 + out1[1] = x141 + out1[2] = x142 + out1[3] = x143 +} + +// ToMontgomery translates a field element into the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = eval arg1 mod m +// 0 ≤ eval out1 < m +func ToMontgomery(out1 *MontgomeryDomainFieldElement, arg1 *NonMontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, 0x7a2000e90a1) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Add64(x6, x4, uint64(0x0)) + var x9 uint64 + _, x9 = bits.Mul64(x5, 0xd838091dd2253531) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x9, 0xffffffffffffffff) + var x13 uint64 + var x14 uint64 + x14, x13 = bits.Mul64(x9, 0xffffffffffffffff) + var x15 uint64 + var x16 uint64 + x16, x15 = bits.Mul64(x9, 0xffffffffffffffff) + var x17 uint64 + var x18 uint64 + x18, x17 = bits.Mul64(x9, 0xfffffffefffffc2f) + var x19 uint64 + var x20 uint64 + x19, x20 = bits.Add64(x18, x15, uint64(0x0)) + var x21 uint64 + var x22 uint64 + x21, x22 = bits.Add64(x16, x13, uint64(uint1(x20))) + var x23 uint64 + var x24 uint64 + x23, x24 = bits.Add64(x14, x11, uint64(uint1(x22))) + var x26 uint64 + _, x26 = bits.Add64(x5, x17, uint64(0x0)) + var x27 uint64 + var x28 uint64 + x27, x28 = bits.Add64(x7, x19, uint64(uint1(x26))) + var x29 uint64 + var x30 uint64 + x29, x30 = bits.Add64(uint64(uint1(x8)), x21, uint64(uint1(x28))) + var x31 uint64 + var x32 uint64 + x31, x32 = bits.Add64(uint64(0x0), x23, uint64(uint1(x30))) + var x33 uint64 + var x34 uint64 + x33, x34 = bits.Add64(uint64(0x0), (uint64(uint1(x24)) + x12), uint64(uint1(x32))) + var x35 uint64 + var x36 uint64 + x36, x35 = bits.Mul64(x1, 0x7a2000e90a1) + var x37 uint64 + var x38 uint64 + x37, x38 = bits.Add64(x36, x1, uint64(0x0)) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x27, x35, uint64(0x0)) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x29, x37, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64(x31, uint64(uint1(x38)), uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Add64(x33, uint64(0x0), uint64(uint1(x44))) + var x47 uint64 + _, x47 = bits.Mul64(x39, 0xd838091dd2253531) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x47, 0xffffffffffffffff) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x47, 0xffffffffffffffff) + var x53 uint64 + var x54 uint64 + x54, x53 = bits.Mul64(x47, 0xffffffffffffffff) + var x55 uint64 + var x56 uint64 + x56, x55 = bits.Mul64(x47, 0xfffffffefffffc2f) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x56, x53, uint64(0x0)) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x54, x51, uint64(uint1(x58))) + var x61 uint64 + var x62 uint64 + x61, x62 = bits.Add64(x52, x49, uint64(uint1(x60))) + var x64 uint64 + _, x64 = bits.Add64(x39, x55, uint64(0x0)) + var x65 uint64 + var x66 uint64 + x65, x66 = bits.Add64(x41, x57, uint64(uint1(x64))) + var x67 uint64 + var x68 uint64 + x67, x68 = bits.Add64(x43, x59, uint64(uint1(x66))) + var x69 uint64 + var x70 uint64 + x69, x70 = bits.Add64(x45, x61, uint64(uint1(x68))) + var x71 uint64 + var x72 uint64 + x71, x72 = bits.Add64((uint64(uint1(x46)) + uint64(uint1(x34))), (uint64(uint1(x62)) + x50), uint64(uint1(x70))) + var x73 uint64 + var x74 uint64 + x74, x73 = bits.Mul64(x2, 0x7a2000e90a1) + var x75 uint64 + var x76 uint64 + x75, x76 = bits.Add64(x74, x2, uint64(0x0)) + var x77 uint64 + var x78 uint64 + x77, x78 = bits.Add64(x65, x73, uint64(0x0)) + var x79 uint64 + var x80 uint64 + x79, x80 = bits.Add64(x67, x75, uint64(uint1(x78))) + var x81 uint64 + var x82 uint64 + x81, x82 = bits.Add64(x69, uint64(uint1(x76)), uint64(uint1(x80))) + var x83 uint64 + var x84 uint64 + x83, x84 = bits.Add64(x71, uint64(0x0), uint64(uint1(x82))) + var x85 uint64 + _, x85 = bits.Mul64(x77, 0xd838091dd2253531) + var x87 uint64 + var x88 uint64 + x88, x87 = bits.Mul64(x85, 0xffffffffffffffff) + var x89 uint64 + var x90 uint64 + x90, x89 = bits.Mul64(x85, 0xffffffffffffffff) + var x91 uint64 + var x92 uint64 + x92, x91 = bits.Mul64(x85, 0xffffffffffffffff) + var x93 uint64 + var x94 uint64 + x94, x93 = bits.Mul64(x85, 0xfffffffefffffc2f) + var x95 uint64 + var x96 uint64 + x95, x96 = bits.Add64(x94, x91, uint64(0x0)) + var x97 uint64 + var x98 uint64 + x97, x98 = bits.Add64(x92, x89, uint64(uint1(x96))) + var x99 uint64 + var x100 uint64 + x99, x100 = bits.Add64(x90, x87, uint64(uint1(x98))) + var x102 uint64 + _, x102 = bits.Add64(x77, x93, uint64(0x0)) + var x103 uint64 + var x104 uint64 + x103, x104 = bits.Add64(x79, x95, uint64(uint1(x102))) + var x105 uint64 + var x106 uint64 + x105, x106 = bits.Add64(x81, x97, uint64(uint1(x104))) + var x107 uint64 + var x108 uint64 + x107, x108 = bits.Add64(x83, x99, uint64(uint1(x106))) + var x109 uint64 + var x110 uint64 + x109, x110 = bits.Add64((uint64(uint1(x84)) + uint64(uint1(x72))), (uint64(uint1(x100)) + x88), uint64(uint1(x108))) + var x111 uint64 + var x112 uint64 + x112, x111 = bits.Mul64(x3, 0x7a2000e90a1) + var x113 uint64 + var x114 uint64 + x113, x114 = bits.Add64(x112, x3, uint64(0x0)) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x103, x111, uint64(0x0)) + var x117 uint64 + var x118 uint64 + x117, x118 = bits.Add64(x105, x113, uint64(uint1(x116))) + var x119 uint64 + var x120 uint64 + x119, x120 = bits.Add64(x107, uint64(uint1(x114)), uint64(uint1(x118))) + var x121 uint64 + var x122 uint64 + x121, x122 = bits.Add64(x109, uint64(0x0), uint64(uint1(x120))) + var x123 uint64 + _, x123 = bits.Mul64(x115, 0xd838091dd2253531) + var x125 uint64 + var x126 uint64 + x126, x125 = bits.Mul64(x123, 0xffffffffffffffff) + var x127 uint64 + var x128 uint64 + x128, x127 = bits.Mul64(x123, 0xffffffffffffffff) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x123, 0xffffffffffffffff) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x123, 0xfffffffefffffc2f) + var x133 uint64 + var x134 uint64 + x133, x134 = bits.Add64(x132, x129, uint64(0x0)) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x130, x127, uint64(uint1(x134))) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x128, x125, uint64(uint1(x136))) + var x140 uint64 + _, x140 = bits.Add64(x115, x131, uint64(0x0)) + var x141 uint64 + var x142 uint64 + x141, x142 = bits.Add64(x117, x133, uint64(uint1(x140))) + var x143 uint64 + var x144 uint64 + x143, x144 = bits.Add64(x119, x135, uint64(uint1(x142))) + var x145 uint64 + var x146 uint64 + x145, x146 = bits.Add64(x121, x137, uint64(uint1(x144))) + var x147 uint64 + var x148 uint64 + x147, x148 = bits.Add64((uint64(uint1(x122)) + uint64(uint1(x110))), (uint64(uint1(x138)) + x126), uint64(uint1(x146))) + var x149 uint64 + var x150 uint64 + x149, x150 = bits.Sub64(x141, 0xfffffffefffffc2f, uint64(0x0)) + var x151 uint64 + var x152 uint64 + x151, x152 = bits.Sub64(x143, 0xffffffffffffffff, uint64(uint1(x150))) + var x153 uint64 + var x154 uint64 + x153, x154 = bits.Sub64(x145, 0xffffffffffffffff, uint64(uint1(x152))) + var x155 uint64 + var x156 uint64 + x155, x156 = bits.Sub64(x147, 0xffffffffffffffff, uint64(uint1(x154))) + var x158 uint64 + _, x158 = bits.Sub64(uint64(uint1(x148)), uint64(0x0), uint64(uint1(x156))) + var x159 uint64 + cmovznzU64(&x159, uint1(x158), x149, x141) + var x160 uint64 + cmovznzU64(&x160, uint1(x158), x151, x143) + var x161 uint64 + cmovznzU64(&x161, uint1(x158), x153, x145) + var x162 uint64 + cmovznzU64(&x162, uint1(x158), x155, x147) + out1[0] = x159 + out1[1] = x160 + out1[2] = x161 + out1[3] = x162 +} + +// Nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0 +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func Nonzero(out1 *uint64, arg1 *[4]uint64) { + x1 := (arg1[0] | (arg1[1] | (arg1[2] | arg1[3]))) + *out1 = x1 +} + +// Selectznz is a multi-limb conditional select. +// +// Postconditions: +// +// eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func Selectznz(out1 *[4]uint64, arg1 uint1, arg2 *[4]uint64, arg3 *[4]uint64) { + var x1 uint64 + cmovznzU64(&x1, arg1, arg2[0], arg3[0]) + var x2 uint64 + cmovznzU64(&x2, arg1, arg2[1], arg3[1]) + var x3 uint64 + cmovznzU64(&x3, arg1, arg2[2], arg3[2]) + var x4 uint64 + cmovznzU64(&x4, arg1, arg2[3], arg3[3]) + out1[0] = x1 + out1[1] = x2 + out1[2] = x3 + out1[3] = x4 +} + +// ToBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] +func ToBytes(out1 *[32]uint8, arg1 *[4]uint64) { + x1 := arg1[3] + x2 := arg1[2] + x3 := arg1[1] + x4 := arg1[0] + x5 := (uint8(x4) & 0xff) + x6 := (x4 >> 8) + x7 := (uint8(x6) & 0xff) + x8 := (x6 >> 8) + x9 := (uint8(x8) & 0xff) + x10 := (x8 >> 8) + x11 := (uint8(x10) & 0xff) + x12 := (x10 >> 8) + x13 := (uint8(x12) & 0xff) + x14 := (x12 >> 8) + x15 := (uint8(x14) & 0xff) + x16 := (x14 >> 8) + x17 := (uint8(x16) & 0xff) + x18 := uint8((x16 >> 8)) + x19 := (uint8(x3) & 0xff) + x20 := (x3 >> 8) + x21 := (uint8(x20) & 0xff) + x22 := (x20 >> 8) + x23 := (uint8(x22) & 0xff) + x24 := (x22 >> 8) + x25 := (uint8(x24) & 0xff) + x26 := (x24 >> 8) + x27 := (uint8(x26) & 0xff) + x28 := (x26 >> 8) + x29 := (uint8(x28) & 0xff) + x30 := (x28 >> 8) + x31 := (uint8(x30) & 0xff) + x32 := uint8((x30 >> 8)) + x33 := (uint8(x2) & 0xff) + x34 := (x2 >> 8) + x35 := (uint8(x34) & 0xff) + x36 := (x34 >> 8) + x37 := (uint8(x36) & 0xff) + x38 := (x36 >> 8) + x39 := (uint8(x38) & 0xff) + x40 := (x38 >> 8) + x41 := (uint8(x40) & 0xff) + x42 := (x40 >> 8) + x43 := (uint8(x42) & 0xff) + x44 := (x42 >> 8) + x45 := (uint8(x44) & 0xff) + x46 := uint8((x44 >> 8)) + x47 := (uint8(x1) & 0xff) + x48 := (x1 >> 8) + x49 := (uint8(x48) & 0xff) + x50 := (x48 >> 8) + x51 := (uint8(x50) & 0xff) + x52 := (x50 >> 8) + x53 := (uint8(x52) & 0xff) + x54 := (x52 >> 8) + x55 := (uint8(x54) & 0xff) + x56 := (x54 >> 8) + x57 := (uint8(x56) & 0xff) + x58 := (x56 >> 8) + x59 := (uint8(x58) & 0xff) + x60 := uint8((x58 >> 8)) + out1[0] = x5 + out1[1] = x7 + out1[2] = x9 + out1[3] = x11 + out1[4] = x13 + out1[5] = x15 + out1[6] = x17 + out1[7] = x18 + out1[8] = x19 + out1[9] = x21 + out1[10] = x23 + out1[11] = x25 + out1[12] = x27 + out1[13] = x29 + out1[14] = x31 + out1[15] = x32 + out1[16] = x33 + out1[17] = x35 + out1[18] = x37 + out1[19] = x39 + out1[20] = x41 + out1[21] = x43 + out1[22] = x45 + out1[23] = x46 + out1[24] = x47 + out1[25] = x49 + out1[26] = x51 + out1[27] = x53 + out1[28] = x55 + out1[29] = x57 + out1[30] = x59 + out1[31] = x60 +} + +// FromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ bytes_eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = bytes_eval arg1 mod m +// 0 ≤ eval out1 < m +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func FromBytes(out1 *[4]uint64, arg1 *[32]uint8) { + x1 := (uint64(arg1[31]) << 56) + x2 := (uint64(arg1[30]) << 48) + x3 := (uint64(arg1[29]) << 40) + x4 := (uint64(arg1[28]) << 32) + x5 := (uint64(arg1[27]) << 24) + x6 := (uint64(arg1[26]) << 16) + x7 := (uint64(arg1[25]) << 8) + x8 := arg1[24] + x9 := (uint64(arg1[23]) << 56) + x10 := (uint64(arg1[22]) << 48) + x11 := (uint64(arg1[21]) << 40) + x12 := (uint64(arg1[20]) << 32) + x13 := (uint64(arg1[19]) << 24) + x14 := (uint64(arg1[18]) << 16) + x15 := (uint64(arg1[17]) << 8) + x16 := arg1[16] + x17 := (uint64(arg1[15]) << 56) + x18 := (uint64(arg1[14]) << 48) + x19 := (uint64(arg1[13]) << 40) + x20 := (uint64(arg1[12]) << 32) + x21 := (uint64(arg1[11]) << 24) + x22 := (uint64(arg1[10]) << 16) + x23 := (uint64(arg1[9]) << 8) + x24 := arg1[8] + x25 := (uint64(arg1[7]) << 56) + x26 := (uint64(arg1[6]) << 48) + x27 := (uint64(arg1[5]) << 40) + x28 := (uint64(arg1[4]) << 32) + x29 := (uint64(arg1[3]) << 24) + x30 := (uint64(arg1[2]) << 16) + x31 := (uint64(arg1[1]) << 8) + x32 := arg1[0] + x33 := (x31 + uint64(x32)) + x34 := (x30 + x33) + x35 := (x29 + x34) + x36 := (x28 + x35) + x37 := (x27 + x36) + x38 := (x26 + x37) + x39 := (x25 + x38) + x40 := (x23 + uint64(x24)) + x41 := (x22 + x40) + x42 := (x21 + x41) + x43 := (x20 + x42) + x44 := (x19 + x43) + x45 := (x18 + x44) + x46 := (x17 + x45) + x47 := (x15 + uint64(x16)) + x48 := (x14 + x47) + x49 := (x13 + x48) + x50 := (x12 + x49) + x51 := (x11 + x50) + x52 := (x10 + x51) + x53 := (x9 + x52) + x54 := (x7 + uint64(x8)) + x55 := (x6 + x54) + x56 := (x5 + x55) + x57 := (x4 + x56) + x58 := (x3 + x57) + x59 := (x2 + x58) + x60 := (x1 + x59) + out1[0] = x39 + out1[1] = x46 + out1[2] = x53 + out1[3] = x60 +} + +// SetOne returns the field element one in the Montgomery domain. +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = 1 mod m +// 0 ≤ eval out1 < m +func SetOne(out1 *MontgomeryDomainFieldElement) { + out1[0] = 0x1000003d1 + out1[1] = uint64(0x0) + out1[2] = uint64(0x0) + out1[3] = uint64(0x0) +} + +// Msat returns the saturated representation of the prime modulus. +// +// Postconditions: +// +// twos_complement_eval out1 = m +// 0 ≤ eval out1 < m +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func Msat(out1 *[5]uint64) { + out1[0] = 0xfffffffefffffc2f + out1[1] = 0xffffffffffffffff + out1[2] = 0xffffffffffffffff + out1[3] = 0xffffffffffffffff + out1[4] = uint64(0x0) +} + +// Divstep computes a divstep. +// +// Preconditions: +// +// 0 ≤ eval arg4 < m +// 0 ≤ eval arg5 < m +// +// Postconditions: +// +// out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1) +// twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2) +// twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋) +// eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m) +// eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m) +// 0 ≤ eval out5 < m +// 0 ≤ eval out5 < m +// 0 ≤ eval out2 < m +// 0 ≤ eval out3 < m +// +// Input Bounds: +// +// arg1: [0x0 ~> 0xffffffffffffffff] +// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +// out2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// out3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func Divstep(out1 *uint64, out2 *[5]uint64, out3 *[5]uint64, out4 *[4]uint64, out5 *[4]uint64, arg1 uint64, arg2 *[5]uint64, arg3 *[5]uint64, arg4 *[4]uint64, arg5 *[4]uint64) { + var x1 uint64 + x1, _ = bits.Add64((^arg1), uint64(0x1), uint64(0x0)) + x3 := (uint1((x1 >> 63)) & (uint1(arg3[0]) & 0x1)) + var x4 uint64 + x4, _ = bits.Add64((^arg1), uint64(0x1), uint64(0x0)) + var x6 uint64 + cmovznzU64(&x6, x3, arg1, x4) + var x7 uint64 + cmovznzU64(&x7, x3, arg2[0], arg3[0]) + var x8 uint64 + cmovznzU64(&x8, x3, arg2[1], arg3[1]) + var x9 uint64 + cmovznzU64(&x9, x3, arg2[2], arg3[2]) + var x10 uint64 + cmovznzU64(&x10, x3, arg2[3], arg3[3]) + var x11 uint64 + cmovznzU64(&x11, x3, arg2[4], arg3[4]) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(uint64(0x1), (^arg2[0]), uint64(0x0)) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(uint64(0x0), (^arg2[1]), uint64(uint1(x13))) + var x16 uint64 + var x17 uint64 + x16, x17 = bits.Add64(uint64(0x0), (^arg2[2]), uint64(uint1(x15))) + var x18 uint64 + var x19 uint64 + x18, x19 = bits.Add64(uint64(0x0), (^arg2[3]), uint64(uint1(x17))) + var x20 uint64 + x20, _ = bits.Add64(uint64(0x0), (^arg2[4]), uint64(uint1(x19))) + var x22 uint64 + cmovznzU64(&x22, x3, arg3[0], x12) + var x23 uint64 + cmovznzU64(&x23, x3, arg3[1], x14) + var x24 uint64 + cmovznzU64(&x24, x3, arg3[2], x16) + var x25 uint64 + cmovznzU64(&x25, x3, arg3[3], x18) + var x26 uint64 + cmovznzU64(&x26, x3, arg3[4], x20) + var x27 uint64 + cmovznzU64(&x27, x3, arg4[0], arg5[0]) + var x28 uint64 + cmovznzU64(&x28, x3, arg4[1], arg5[1]) + var x29 uint64 + cmovznzU64(&x29, x3, arg4[2], arg5[2]) + var x30 uint64 + cmovznzU64(&x30, x3, arg4[3], arg5[3]) + var x31 uint64 + var x32 uint64 + x31, x32 = bits.Add64(x27, x27, uint64(0x0)) + var x33 uint64 + var x34 uint64 + x33, x34 = bits.Add64(x28, x28, uint64(uint1(x32))) + var x35 uint64 + var x36 uint64 + x35, x36 = bits.Add64(x29, x29, uint64(uint1(x34))) + var x37 uint64 + var x38 uint64 + x37, x38 = bits.Add64(x30, x30, uint64(uint1(x36))) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Sub64(x31, 0xfffffffefffffc2f, uint64(0x0)) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Sub64(x33, 0xffffffffffffffff, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Sub64(x35, 0xffffffffffffffff, uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Sub64(x37, 0xffffffffffffffff, uint64(uint1(x44))) + var x48 uint64 + _, x48 = bits.Sub64(uint64(uint1(x38)), uint64(0x0), uint64(uint1(x46))) + x49 := arg4[3] + x50 := arg4[2] + x51 := arg4[1] + x52 := arg4[0] + var x53 uint64 + var x54 uint64 + x53, x54 = bits.Sub64(uint64(0x0), x52, uint64(0x0)) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Sub64(uint64(0x0), x51, uint64(uint1(x54))) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Sub64(uint64(0x0), x50, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Sub64(uint64(0x0), x49, uint64(uint1(x58))) + var x61 uint64 + cmovznzU64(&x61, uint1(x60), uint64(0x0), 0xffffffffffffffff) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x53, (x61 & 0xfffffffefffffc2f), uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x55, x61, uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x57, x61, uint64(uint1(x65))) + var x68 uint64 + x68, _ = bits.Add64(x59, x61, uint64(uint1(x67))) + var x70 uint64 + cmovznzU64(&x70, x3, arg5[0], x62) + var x71 uint64 + cmovznzU64(&x71, x3, arg5[1], x64) + var x72 uint64 + cmovznzU64(&x72, x3, arg5[2], x66) + var x73 uint64 + cmovznzU64(&x73, x3, arg5[3], x68) + x74 := (uint1(x22) & 0x1) + var x75 uint64 + cmovznzU64(&x75, x74, uint64(0x0), x7) + var x76 uint64 + cmovznzU64(&x76, x74, uint64(0x0), x8) + var x77 uint64 + cmovznzU64(&x77, x74, uint64(0x0), x9) + var x78 uint64 + cmovznzU64(&x78, x74, uint64(0x0), x10) + var x79 uint64 + cmovznzU64(&x79, x74, uint64(0x0), x11) + var x80 uint64 + var x81 uint64 + x80, x81 = bits.Add64(x22, x75, uint64(0x0)) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x23, x76, uint64(uint1(x81))) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x24, x77, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x25, x78, uint64(uint1(x85))) + var x88 uint64 + x88, _ = bits.Add64(x26, x79, uint64(uint1(x87))) + var x90 uint64 + cmovznzU64(&x90, x74, uint64(0x0), x27) + var x91 uint64 + cmovznzU64(&x91, x74, uint64(0x0), x28) + var x92 uint64 + cmovznzU64(&x92, x74, uint64(0x0), x29) + var x93 uint64 + cmovznzU64(&x93, x74, uint64(0x0), x30) + var x94 uint64 + var x95 uint64 + x94, x95 = bits.Add64(x70, x90, uint64(0x0)) + var x96 uint64 + var x97 uint64 + x96, x97 = bits.Add64(x71, x91, uint64(uint1(x95))) + var x98 uint64 + var x99 uint64 + x98, x99 = bits.Add64(x72, x92, uint64(uint1(x97))) + var x100 uint64 + var x101 uint64 + x100, x101 = bits.Add64(x73, x93, uint64(uint1(x99))) + var x102 uint64 + var x103 uint64 + x102, x103 = bits.Sub64(x94, 0xfffffffefffffc2f, uint64(0x0)) + var x104 uint64 + var x105 uint64 + x104, x105 = bits.Sub64(x96, 0xffffffffffffffff, uint64(uint1(x103))) + var x106 uint64 + var x107 uint64 + x106, x107 = bits.Sub64(x98, 0xffffffffffffffff, uint64(uint1(x105))) + var x108 uint64 + var x109 uint64 + x108, x109 = bits.Sub64(x100, 0xffffffffffffffff, uint64(uint1(x107))) + var x111 uint64 + _, x111 = bits.Sub64(uint64(uint1(x101)), uint64(0x0), uint64(uint1(x109))) + var x112 uint64 + x112, _ = bits.Add64(x6, uint64(0x1), uint64(0x0)) + x114 := ((x80 >> 1) | ((x82 << 63) & 0xffffffffffffffff)) + x115 := ((x82 >> 1) | ((x84 << 63) & 0xffffffffffffffff)) + x116 := ((x84 >> 1) | ((x86 << 63) & 0xffffffffffffffff)) + x117 := ((x86 >> 1) | ((x88 << 63) & 0xffffffffffffffff)) + x118 := ((x88 & 0x8000000000000000) | (x88 >> 1)) + var x119 uint64 + cmovznzU64(&x119, uint1(x48), x39, x31) + var x120 uint64 + cmovznzU64(&x120, uint1(x48), x41, x33) + var x121 uint64 + cmovznzU64(&x121, uint1(x48), x43, x35) + var x122 uint64 + cmovznzU64(&x122, uint1(x48), x45, x37) + var x123 uint64 + cmovznzU64(&x123, uint1(x111), x102, x94) + var x124 uint64 + cmovznzU64(&x124, uint1(x111), x104, x96) + var x125 uint64 + cmovznzU64(&x125, uint1(x111), x106, x98) + var x126 uint64 + cmovznzU64(&x126, uint1(x111), x108, x100) + *out1 = x112 + out2[0] = x7 + out2[1] = x8 + out2[2] = x9 + out2[3] = x10 + out2[4] = x11 + out3[0] = x114 + out3[1] = x115 + out3[2] = x116 + out3[3] = x117 + out3[4] = x118 + out4[0] = x119 + out4[1] = x120 + out4[2] = x121 + out4[3] = x122 + out5[0] = x123 + out5[1] = x124 + out5[2] = x125 + out5[3] = x126 +} + +// DivstepPrecomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form). +// +// Postconditions: +// +// eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋) +// 0 ≤ eval out1 < m +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func DivstepPrecomp(out1 *[4]uint64) { + out1[0] = 0xf201a41831525e0a + out1[1] = 0x9953f9ddcd648d85 + out1[2] = 0xe86029463db210a9 + out1[3] = 0x24fb8a3104b03709 +} diff --git a/pkg/crypto/core/curves/native/k256/fq/fq.go b/pkg/crypto/core/curves/native/k256/fq/fq.go new file mode 100755 index 000000000..da8196c9f --- /dev/null +++ b/pkg/crypto/core/curves/native/k256/fq/fq.go @@ -0,0 +1,287 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fq + +import ( + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +var ( + k256FqInitonce sync.Once + k256FqParams native.FieldParams +) + +func K256FqNew() *native.Field { + return &native.Field{ + Value: [native.FieldLimbs]uint64{}, + Params: getK256FqParams(), + Arithmetic: k256FqArithmetic{}, + } +} + +func k256FqParamsInit() { + k256FqParams = native.FieldParams{ + R: [native.FieldLimbs]uint64{0x402da1732fc9bebf, 0x4551231950b75fc4, 0x0000000000000001, 0x0000000000000000}, + R2: [native.FieldLimbs]uint64{0x896cf21467d7d140, 0x741496c20e7cf878, 0xe697f5e45bcd07c6, 0x9d671cd581c69bc5}, + R3: [native.FieldLimbs]uint64{0x7bc0cfe0e9ff41ed, 0x0017648444d4322c, 0xb1b31347f1d0b2da, 0x555d800c18ef116d}, + Modulus: [native.FieldLimbs]uint64{0xbfd25e8cd0364141, 0xbaaedce6af48a03b, 0xfffffffffffffffe, 0xffffffffffffffff}, + BiModulus: new(big.Int).SetBytes([]byte{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, + }, + ), + } +} + +func getK256FqParams() *native.FieldParams { + k256FqInitonce.Do(k256FqParamsInit) + return &k256FqParams +} + +// k256FqArithmetic is a struct with all the methods needed for working +// in mod q +type k256FqArithmetic struct{} + +// ToMontgomery converts this field to montgomery form +func (f k256FqArithmetic) ToMontgomery(out, arg *[native.FieldLimbs]uint64) { + ToMontgomery((*MontgomeryDomainFieldElement)(out), (*NonMontgomeryDomainFieldElement)(arg)) +} + +// FromMontgomery converts this field from montgomery form +func (f k256FqArithmetic) FromMontgomery(out, arg *[native.FieldLimbs]uint64) { + FromMontgomery((*NonMontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Neg performs modular negation +func (f k256FqArithmetic) Neg(out, arg *[native.FieldLimbs]uint64) { + Opp((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Square performs modular square +func (f k256FqArithmetic) Square(out, arg *[native.FieldLimbs]uint64) { + Square((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Mul performs modular multiplication +func (f k256FqArithmetic) Mul(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Mul((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Add performs modular addition +func (f k256FqArithmetic) Add(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Add((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Sub performs modular subtraction +func (f k256FqArithmetic) Sub(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Sub((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Sqrt performs modular square root +func (f k256FqArithmetic) Sqrt(wasSquare *int, out, arg *[native.FieldLimbs]uint64) { + // See sqrt_ts_ct at + // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-I.4 + // c1 := 6 + // c2 := (q - 1) / (2^c1) + // c2 := [4]uint64{ + // 0xeeff497a3340d905, + // 0xfaeabb739abd2280, + // 0xffffffffffffffff, + // 0x03ffffffffffffff, + //} + // c3 := (c2 - 1) / 2 + c3 := [native.FieldLimbs]uint64{ + 0x777fa4bd19a06c82, + 0xfd755db9cd5e9140, + 0xffffffffffffffff, + 0x01ffffffffffffff, + } + // c4 := generator + // c5 := new(Fq).pow(generator, c2) + c5 := [native.FieldLimbs]uint64{0x944cf2a220910e04, 0x815c829c780589f4, 0x55980b07bc222113, 0xc702b0d248825b36} + var z, t, b, c, tv [native.FieldLimbs]uint64 + + native.Pow(&z, arg, &c3, getK256FqParams(), f) + Square((*MontgomeryDomainFieldElement)(&t), (*MontgomeryDomainFieldElement)(&z)) + Mul((*MontgomeryDomainFieldElement)(&t), (*MontgomeryDomainFieldElement)(&t), (*MontgomeryDomainFieldElement)(arg)) + Mul((*MontgomeryDomainFieldElement)(&z), (*MontgomeryDomainFieldElement)(&z), (*MontgomeryDomainFieldElement)(arg)) + + copy(b[:], t[:]) + copy(c[:], c5[:]) + + for i := s; i >= 2; i-- { + for j := 1; j <= i-2; j++ { + Square((*MontgomeryDomainFieldElement)(&b), (*MontgomeryDomainFieldElement)(&b)) + } + // if b == 1 flag = 0 else flag = 1 + flag := -(&native.Field{ + Value: b, + Params: getK256FqParams(), + Arithmetic: f, + }).IsOne() + 1 + Mul((*MontgomeryDomainFieldElement)(&tv), (*MontgomeryDomainFieldElement)(&z), (*MontgomeryDomainFieldElement)(&c)) + Selectznz(&z, uint1(flag), &z, &tv) + Square((*MontgomeryDomainFieldElement)(&c), (*MontgomeryDomainFieldElement)(&c)) + Mul((*MontgomeryDomainFieldElement)(&tv), (*MontgomeryDomainFieldElement)(&t), (*MontgomeryDomainFieldElement)(&c)) + Selectznz(&t, uint1(flag), &t, &tv) + copy(b[:], t[:]) + } + Square((*MontgomeryDomainFieldElement)(&c), (*MontgomeryDomainFieldElement)(&z)) + *wasSquare = (&native.Field{ + Value: c, + Params: getK256FqParams(), + Arithmetic: f, + }).Equal(&native.Field{ + Value: *arg, + Params: getK256FqParams(), + Arithmetic: f, + }) + Selectznz(out, uint1(*wasSquare), out, &z) +} + +// Invert performs modular inverse +func (f k256FqArithmetic) Invert(wasInverted *int, out, arg *[native.FieldLimbs]uint64) { + // Using an addition chain from + // https://briansmith.org/ecc-inversion-addition-chains-01#secp256k1_scalar_inversion + var x1, x10, x11, x101, x111, x1001, x1011, x1101 [native.FieldLimbs]uint64 + var x6, x8, x14, x28, x56, tmp [native.FieldLimbs]uint64 + + copy(x1[:], arg[:]) + native.Pow2k(&x10, arg, 1, f) + Mul((*MontgomeryDomainFieldElement)(&x11), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x1)) + Mul((*MontgomeryDomainFieldElement)(&x101), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x11)) + Mul((*MontgomeryDomainFieldElement)(&x111), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x101)) + Mul((*MontgomeryDomainFieldElement)(&x1001), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x111)) + Mul((*MontgomeryDomainFieldElement)(&x1011), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x1001)) + Mul((*MontgomeryDomainFieldElement)(&x1101), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x1011)) + + native.Pow2k(&x6, &x1101, 2, f) + Mul((*MontgomeryDomainFieldElement)(&x6), (*MontgomeryDomainFieldElement)(&x6), (*MontgomeryDomainFieldElement)(&x1011)) + + native.Pow2k(&x8, &x6, 2, f) + Mul((*MontgomeryDomainFieldElement)(&x8), (*MontgomeryDomainFieldElement)(&x8), (*MontgomeryDomainFieldElement)(&x11)) + + native.Pow2k(&x14, &x8, 6, f) + Mul((*MontgomeryDomainFieldElement)(&x14), (*MontgomeryDomainFieldElement)(&x14), (*MontgomeryDomainFieldElement)(&x6)) + + native.Pow2k(&x28, &x14, 14, f) + Mul((*MontgomeryDomainFieldElement)(&x28), (*MontgomeryDomainFieldElement)(&x28), (*MontgomeryDomainFieldElement)(&x14)) + + native.Pow2k(&x56, &x28, 28, f) + Mul((*MontgomeryDomainFieldElement)(&x56), (*MontgomeryDomainFieldElement)(&x56), (*MontgomeryDomainFieldElement)(&x28)) + + native.Pow2k(&tmp, &x56, 56, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x56)) + + native.Pow2k(&tmp, &tmp, 14, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x14)) + + native.Pow2k(&tmp, &tmp, 3, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1011)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1011)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1101)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101)) + + native.Pow2k(&tmp, &tmp, 3, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1001)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101)) + + native.Pow2k(&tmp, &tmp, 10, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 9, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x8)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1001)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1011)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1101)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x11)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1101)) + + native.Pow2k(&tmp, &tmp, 10, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1101)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1001)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1)) + + native.Pow2k(&tmp, &tmp, 8, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x6)) + + *wasInverted = (&native.Field{ + Value: *arg, + Params: getK256FqParams(), + Arithmetic: f, + }).IsNonZero() + Selectznz(out, uint1(*wasInverted), out, &tmp) +} + +// FromBytes converts a little endian byte array into a field element +func (f k256FqArithmetic) FromBytes(out *[native.FieldLimbs]uint64, arg *[native.FieldBytes]byte) { + FromBytes(out, arg) +} + +// ToBytes converts a field element to a little endian byte array +func (f k256FqArithmetic) ToBytes(out *[native.FieldBytes]byte, arg *[native.FieldLimbs]uint64) { + ToBytes(out, arg) +} + +// Selectznz performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f k256FqArithmetic) Selectznz(out, arg1, arg2 *[native.FieldLimbs]uint64, choice int) { + Selectznz(out, uint1(choice), arg1, arg2) +} + +// generator = 7 mod q is a generator of the `q - 1` order multiplicative +// subgroup, or in other words a primitive element of the field. +// generator^t where t * 2^s + 1 = q +var generator = &[native.FieldLimbs]uint64{0xc13f6a264e843739, 0xe537f5b135039e5d, 0x0000000000000008, 0x0000000000000000} + +// s satisfies the equation 2^s * t = q - 1 with t odd. +var s = 6 diff --git a/pkg/crypto/core/curves/native/k256/fq/fq_test.go b/pkg/crypto/core/curves/native/k256/fq/fq_test.go new file mode 100755 index 000000000..deff77bc1 --- /dev/null +++ b/pkg/crypto/core/curves/native/k256/fq/fq_test.go @@ -0,0 +1,328 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fq + +import ( + crand "crypto/rand" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func TestFqSetOne(t *testing.T) { + fq := K256FqNew().SetOne() + require.NotNil(t, fq) + require.Equal(t, fq.Value, getK256FqParams().R) +} + +func TestFqSetUint64(t *testing.T) { + act := K256FqNew().SetUint64(1 << 60) + require.NotNil(t, act) + // Remember it will be in montgomery form + require.Equal(t, act.Value[0], uint64(0xF000000000000000)) +} + +func TestFqAdd(t *testing.T) { + lhs := K256FqNew().SetOne() + rhs := K256FqNew().SetOne() + exp := K256FqNew().SetUint64(2) + res := K256FqNew().Add(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + e := l + r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := K256FqNew().Add(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqSub(t *testing.T) { + lhs := K256FqNew().SetOne() + rhs := K256FqNew().SetOne() + exp := K256FqNew().SetZero() + res := K256FqNew().Sub(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + if l < r { + l, r = r, l + } + e := l - r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := K256FqNew().Sub(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqMul(t *testing.T) { + lhs := K256FqNew().SetOne() + rhs := K256FqNew().SetOne() + exp := K256FqNew().SetOne() + res := K256FqNew().Mul(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint32() + r := rand.Uint32() + e := uint64(l) * uint64(r) + lhs.SetUint64(uint64(l)) + rhs.SetUint64(uint64(r)) + exp.SetUint64(e) + + a := K256FqNew().Mul(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqDouble(t *testing.T) { + a := K256FqNew().SetUint64(2) + e := K256FqNew().SetUint64(4) + require.Equal(t, e, K256FqNew().Double(a)) + + for i := 0; i < 25; i++ { + tv := rand.Uint32() + ttv := uint64(tv) * 2 + a = K256FqNew().SetUint64(uint64(tv)) + e = K256FqNew().SetUint64(ttv) + require.Equal(t, e, K256FqNew().Double(a)) + } +} + +func TestFqSquare(t *testing.T) { + a := K256FqNew().SetUint64(4) + e := K256FqNew().SetUint64(16) + require.Equal(t, e, a.Square(a)) + + for i := 0; i < 25; i++ { + j := rand.Uint32() + exp := uint64(j) * uint64(j) + e.SetUint64(exp) + a.SetUint64(uint64(j)) + require.Equal(t, e, a.Square(a)) + } +} + +func TestFqNeg(t *testing.T) { + g := K256FqNew().SetRaw(generator) + a := K256FqNew().SetOne() + a.Neg(a) + e := K256FqNew().SetRaw(&[native.FieldLimbs]uint64{0x7fa4bd19a06c8282, 0x755db9cd5e914077, 0xfffffffffffffffd, 0xffffffffffffffff}) + require.Equal(t, e, a) + a.Neg(g) + e = K256FqNew().SetRaw(&[native.FieldLimbs]uint64{0xfe92f46681b20a08, 0xd576e7357a4501dd, 0xfffffffffffffff5, 0xffffffffffffffff}) + require.Equal(t, e, a) +} + +func TestFqExp(t *testing.T) { + e := K256FqNew().SetUint64(8) + a := K256FqNew().SetUint64(2) + by := K256FqNew().SetUint64(3) + require.Equal(t, e, a.Exp(a, by)) +} + +func TestFqSqrt(t *testing.T) { + t1 := K256FqNew().SetUint64(2) + t2 := K256FqNew().Neg(t1) + t3 := K256FqNew().Square(t1) + _, wasSquare := t3.Sqrt(t3) + + require.True(t, wasSquare) + require.Equal(t, 1, t1.Equal(t3)|t2.Equal(t3)) + t1.SetUint64(5) + _, wasSquare = K256FqNew().Sqrt(t1) + require.False(t, wasSquare) +} + +func TestFqInvert(t *testing.T) { + twoInv := K256FqNew().SetLimbs(&[native.FieldLimbs]uint64{0xdfe92f46681b20a1, 0x5d576e7357a4501d, 0xffffffffffffffff, 0x7fffffffffffffff}) + two := K256FqNew().SetUint64(2) + a, inverted := K256FqNew().Invert(two) + require.True(t, inverted) + require.Equal(t, a, twoInv) + + rootOfUnity := K256FqNew().SetLimbs(&[native.FieldLimbs]uint64{0x8619a9e760c01d0c, 0xa883c4fba37998df, 0x45607580b6eabd98, 0xf252b002544b2f99}) + rootOfUnityInv := K256FqNew().SetRaw(&[native.FieldLimbs]uint64{0x7d99f8e21447e314, 0x5b60c477e7728d4c, 0xd78befc191f58654, 0x6897e5ff7824360f}) + a, inverted = K256FqNew().Invert(rootOfUnity) + require.True(t, inverted) + require.Equal(t, a, rootOfUnityInv) + + lhs := K256FqNew().SetUint64(9) + rhs := K256FqNew().SetUint64(3) + rhsInv, inverted := K256FqNew().Invert(rhs) + require.True(t, inverted) + require.Equal(t, rhs, K256FqNew().Mul(lhs, rhsInv)) + + rhs.SetZero() + _, inverted = K256FqNew().Invert(rhs) + require.False(t, inverted) +} + +func TestFqCMove(t *testing.T) { + t1 := K256FqNew().SetUint64(5) + t2 := K256FqNew().SetUint64(10) + require.Equal(t, t1, K256FqNew().CMove(t1, t2, 0)) + require.Equal(t, t2, K256FqNew().CMove(t1, t2, 1)) +} + +func TestFqBytes(t *testing.T) { + t1 := K256FqNew().SetUint64(99) + seq := t1.Bytes() + t2, err := K256FqNew().SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + + for i := 0; i < 25; i++ { + t1.SetUint64(rand.Uint64()) + seq = t1.Bytes() + _, err = t2.SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + } +} + +func TestFqCmp(t *testing.T) { + tests := []struct { + a *native.Field + b *native.Field + e int + }{ + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{2731658267414164836, 14655288906067898431, 6537465423330262322, 8306191141697566219}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{6472764012681988529, 10848812988401906064, 2961825807536828898, 4282183981941645679}), + e: 1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{8023004109510539223, 4652004072850285717, 1877219145646046927, 383214385093921911}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{10099384440823804262, 16139476942229308465, 8636966320777393798, 5435928725024696785}), + e: -1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{3741840066202388211, 12165774400417314871, 16619312580230515379, 16195032234110087705}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{3905865991286066744, 543690822309071825, 17963103015950210055, 3745476720756119742}), + e: 1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{16660853697936147788, 7799793619412111108, 13515141085171033220, 2641079731236069032}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{17790588295388238399, 571847801379669440, 14537208974498222469, 12792570372087452754}), + e: -1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{3912839285384959186, 2701177075110484070, 6453856448115499033, 6475797457962597458}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{1282566391665688512, 13503640416992806563, 2962240104675990153, 3374904770947067689}), + e: 1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{5716631803409360103, 7859567470082614154, 12747956220853330146, 18434584096087315020}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{16317076441459028418, 12854146980376319601, 2258436689269031143, 9531877130792223752}), + e: 1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{17955191469941083403, 10350326247207200880, 17263512235150705075, 12700328451238078022}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{6767595547459644695, 7146403825494928147, 12269344038346710612, 9122477829383225603}), + e: 1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{17099388671847024438, 6426264987820696548, 10641143464957227405, 7709745403700754098}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{10799154372990268556, 17178492485719929374, 5705777922258988797, 8051037767683567782}), + e: -1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{4567139260680454325, 1629385880182139061, 16607020832317899145, 1261011562621553200}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{13487234491304534488, 17872642955936089265, 17651026784972590233, 9468934643333871559}), + e: -1, + }, + { + a: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{18071070103467571798, 11787850505799426140, 10631355976141928593, 4867785203635092610}), + b: K256FqNew().SetRaw(&[native.FieldLimbs]uint64{12596443599426461624, 10176122686151524591, 17075755296887483439, 6726169532695070719}), + e: -1, + }, + } + + for _, test := range tests { + require.Equal(t, test.e, test.a.Cmp(test.b)) + require.Equal(t, -test.e, test.b.Cmp(test.a)) + require.Equal(t, 0, test.a.Cmp(test.a)) + require.Equal(t, 0, test.b.Cmp(test.b)) + } +} + +func TestFqBigInt(t *testing.T) { + t1 := K256FqNew().SetBigInt(big.NewInt(9999)) + t2 := K256FqNew().SetBigInt(t1.BigInt()) + require.Equal(t, t1, t2) + + e := K256FqNew().SetRaw(&[native.FieldLimbs]uint64{0xa764d3f6f152f222, 0x3b5dc8aacb9297b7, 0xb015fa9d2b3efdc6, 0x567360cef000f24a}) + b := new(big.Int).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}) + t1.SetBigInt(b) + require.Equal(t, e, t1) + e.Value[0] = 0x186d8a95dee34f1f + e.Value[1] = 0x7f51143be3b60884 + e.Value[2] = 0x4fea0562d4c10238 + e.Value[3] = 0xa98c9f310fff0db5 + b.Neg(b) + t1.SetBigInt(b) + require.Equal(t, e, t1) +} + +func TestFqSetBytesWide(t *testing.T) { + e := K256FqNew().SetRaw(&[native.FieldLimbs]uint64{0x70620a92b4f2eb7a, 0xd04588eb9c228a3a, 0xccb71ae40a10491c, 0x61cf39d70a8b33b7}) + + a := K256FqNew().SetBytesWide(&[64]byte{ + 0x69, 0x23, 0x5a, 0x0b, 0xce, 0x0c, 0xa8, 0x64, + 0x3c, 0x78, 0xbc, 0x01, 0x05, 0xef, 0xf2, 0x84, + 0xde, 0xbb, 0x6b, 0xc8, 0x63, 0x5e, 0x6e, 0x69, + 0x62, 0xcc, 0xc6, 0x2d, 0xf5, 0x72, 0x40, 0x92, + 0x28, 0x11, 0xd6, 0xc8, 0x07, 0xa5, 0x88, 0x82, + 0xfe, 0xe3, 0x97, 0xf6, 0x1e, 0xfb, 0x2e, 0x3b, + 0x27, 0x5f, 0x85, 0x06, 0x8d, 0x99, 0xa4, 0x75, + 0xc0, 0x2c, 0x71, 0x69, 0x9e, 0x58, 0xea, 0x52, + }) + require.Equal(t, e, a) +} + +func TestFpSetBytesWideBigInt(t *testing.T) { + params := getK256FqParams() + var tv2 [64]byte + for i := 0; i < 25; i++ { + _, _ = crand.Read(tv2[:]) + e := new(big.Int).SetBytes(tv2[:]) + e.Mod(e, params.BiModulus) + + tv := internal.ReverseScalarBytes(tv2[:]) + copy(tv2[:], tv) + a := K256FqNew().SetBytesWide(&tv2) + require.Equal(t, 0, e.Cmp(a.BigInt())) + } +} diff --git a/pkg/crypto/core/curves/native/k256/fq/secp256k1_fq.go b/pkg/crypto/core/curves/native/k256/fq/secp256k1_fq.go new file mode 100755 index 000000000..0c78d4178 --- /dev/null +++ b/pkg/crypto/core/curves/native/k256/fq/secp256k1_fq.go @@ -0,0 +1,1954 @@ +// Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --lang Go --no-wide-int --relax-primitive-carry-to-bitwidth 32,64 --cmovznz-by-mul --internal-static --package-case flatcase --public-function-case UpperCamelCase --private-function-case camelCase --public-type-case UpperCamelCase --private-type-case camelCase --no-prefix-fiat --doc-newline-in-typedef-bounds --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' --doc-text-before-function-name ” --doc-text-before-type-name ” --package-name secp256k1_q ” 64 '2^256 - 432420386565659656852420866394968145599' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp +// +// curve description (via package name): secp256k1_q +// +// machine_wordsize = 64 (from "64") +// +// requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp +// +// m = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 (from "2^256 - 432420386565659656852420866394968145599") +// +// NOTE: In addition to the bounds specified above each function, all +// +// functions synthesized for this Montgomery arithmetic require the +// +// input to be strictly less than the prime modulus (m), and also +// +// require the input to be in the unique saturated representation. +// +// All functions also ensure that these two properties are true of +// +// return values. +// +// Computed values: +// +// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) +// +// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) +// +// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in +// +// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 +package fq + +import "math/bits" + +type uint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 +type int1 int64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 + +// MontgomeryDomainFieldElement is a field element in the Montgomery domain. +// +// Bounds: +// +// [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type MontgomeryDomainFieldElement [4]uint64 + +// NonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain. +// +// Bounds: +// +// [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type NonMontgomeryDomainFieldElement [4]uint64 + +// cmovznzU64 is a single-word conditional move. +// +// Postconditions: +// +// out1 = (if arg1 = 0 then arg2 else arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [0x0 ~> 0xffffffffffffffff] +// arg3: [0x0 ~> 0xffffffffffffffff] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func cmovznzU64(out1 *uint64, arg1 uint1, arg2 uint64, arg3 uint64) { + x1 := (uint64(arg1) * 0xffffffffffffffff) + x2 := ((x1 & arg3) | ((^x1) & arg2)) + *out1 = x2 +} + +// Mul multiplies two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Mul(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg2[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg2[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg2[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg2[0]) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + x19 := (uint64(uint1(x18)) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0x4b0dff665588b13f) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0xffffffffffffffff) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0xfffffffffffffffe) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0xbaaedce6af48a03b) + var x28 uint64 + var x29 uint64 + x29, x28 = bits.Mul64(x20, 0xbfd25e8cd0364141) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x29, x26, uint64(0x0)) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x27, x24, uint64(uint1(x31))) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x25, x22, uint64(uint1(x33))) + x36 := (uint64(uint1(x35)) + x23) + var x38 uint64 + _, x38 = bits.Add64(x11, x28, uint64(0x0)) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x13, x30, uint64(uint1(x38))) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x15, x32, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64(x17, x34, uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Add64(x19, x36, uint64(uint1(x44))) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg2[3]) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x1, arg2[2]) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x1, arg2[1]) + var x53 uint64 + var x54 uint64 + x54, x53 = bits.Mul64(x1, arg2[0]) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x54, x51, uint64(0x0)) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x52, x49, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x50, x47, uint64(uint1(x58))) + x61 := (uint64(uint1(x60)) + x48) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x39, x53, uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x41, x55, uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x43, x57, uint64(uint1(x65))) + var x68 uint64 + var x69 uint64 + x68, x69 = bits.Add64(x45, x59, uint64(uint1(x67))) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(uint64(uint1(x46)), x61, uint64(uint1(x69))) + var x72 uint64 + _, x72 = bits.Mul64(x62, 0x4b0dff665588b13f) + var x74 uint64 + var x75 uint64 + x75, x74 = bits.Mul64(x72, 0xffffffffffffffff) + var x76 uint64 + var x77 uint64 + x77, x76 = bits.Mul64(x72, 0xfffffffffffffffe) + var x78 uint64 + var x79 uint64 + x79, x78 = bits.Mul64(x72, 0xbaaedce6af48a03b) + var x80 uint64 + var x81 uint64 + x81, x80 = bits.Mul64(x72, 0xbfd25e8cd0364141) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x81, x78, uint64(0x0)) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x79, x76, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x77, x74, uint64(uint1(x85))) + x88 := (uint64(uint1(x87)) + x75) + var x90 uint64 + _, x90 = bits.Add64(x62, x80, uint64(0x0)) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(x64, x82, uint64(uint1(x90))) + var x93 uint64 + var x94 uint64 + x93, x94 = bits.Add64(x66, x84, uint64(uint1(x92))) + var x95 uint64 + var x96 uint64 + x95, x96 = bits.Add64(x68, x86, uint64(uint1(x94))) + var x97 uint64 + var x98 uint64 + x97, x98 = bits.Add64(x70, x88, uint64(uint1(x96))) + x99 := (uint64(uint1(x98)) + uint64(uint1(x71))) + var x100 uint64 + var x101 uint64 + x101, x100 = bits.Mul64(x2, arg2[3]) + var x102 uint64 + var x103 uint64 + x103, x102 = bits.Mul64(x2, arg2[2]) + var x104 uint64 + var x105 uint64 + x105, x104 = bits.Mul64(x2, arg2[1]) + var x106 uint64 + var x107 uint64 + x107, x106 = bits.Mul64(x2, arg2[0]) + var x108 uint64 + var x109 uint64 + x108, x109 = bits.Add64(x107, x104, uint64(0x0)) + var x110 uint64 + var x111 uint64 + x110, x111 = bits.Add64(x105, x102, uint64(uint1(x109))) + var x112 uint64 + var x113 uint64 + x112, x113 = bits.Add64(x103, x100, uint64(uint1(x111))) + x114 := (uint64(uint1(x113)) + x101) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x91, x106, uint64(0x0)) + var x117 uint64 + var x118 uint64 + x117, x118 = bits.Add64(x93, x108, uint64(uint1(x116))) + var x119 uint64 + var x120 uint64 + x119, x120 = bits.Add64(x95, x110, uint64(uint1(x118))) + var x121 uint64 + var x122 uint64 + x121, x122 = bits.Add64(x97, x112, uint64(uint1(x120))) + var x123 uint64 + var x124 uint64 + x123, x124 = bits.Add64(x99, x114, uint64(uint1(x122))) + var x125 uint64 + _, x125 = bits.Mul64(x115, 0x4b0dff665588b13f) + var x127 uint64 + var x128 uint64 + x128, x127 = bits.Mul64(x125, 0xffffffffffffffff) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x125, 0xfffffffffffffffe) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x125, 0xbaaedce6af48a03b) + var x133 uint64 + var x134 uint64 + x134, x133 = bits.Mul64(x125, 0xbfd25e8cd0364141) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x134, x131, uint64(0x0)) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x132, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(x130, x127, uint64(uint1(x138))) + x141 := (uint64(uint1(x140)) + x128) + var x143 uint64 + _, x143 = bits.Add64(x115, x133, uint64(0x0)) + var x144 uint64 + var x145 uint64 + x144, x145 = bits.Add64(x117, x135, uint64(uint1(x143))) + var x146 uint64 + var x147 uint64 + x146, x147 = bits.Add64(x119, x137, uint64(uint1(x145))) + var x148 uint64 + var x149 uint64 + x148, x149 = bits.Add64(x121, x139, uint64(uint1(x147))) + var x150 uint64 + var x151 uint64 + x150, x151 = bits.Add64(x123, x141, uint64(uint1(x149))) + x152 := (uint64(uint1(x151)) + uint64(uint1(x124))) + var x153 uint64 + var x154 uint64 + x154, x153 = bits.Mul64(x3, arg2[3]) + var x155 uint64 + var x156 uint64 + x156, x155 = bits.Mul64(x3, arg2[2]) + var x157 uint64 + var x158 uint64 + x158, x157 = bits.Mul64(x3, arg2[1]) + var x159 uint64 + var x160 uint64 + x160, x159 = bits.Mul64(x3, arg2[0]) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Add64(x160, x157, uint64(0x0)) + var x163 uint64 + var x164 uint64 + x163, x164 = bits.Add64(x158, x155, uint64(uint1(x162))) + var x165 uint64 + var x166 uint64 + x165, x166 = bits.Add64(x156, x153, uint64(uint1(x164))) + x167 := (uint64(uint1(x166)) + x154) + var x168 uint64 + var x169 uint64 + x168, x169 = bits.Add64(x144, x159, uint64(0x0)) + var x170 uint64 + var x171 uint64 + x170, x171 = bits.Add64(x146, x161, uint64(uint1(x169))) + var x172 uint64 + var x173 uint64 + x172, x173 = bits.Add64(x148, x163, uint64(uint1(x171))) + var x174 uint64 + var x175 uint64 + x174, x175 = bits.Add64(x150, x165, uint64(uint1(x173))) + var x176 uint64 + var x177 uint64 + x176, x177 = bits.Add64(x152, x167, uint64(uint1(x175))) + var x178 uint64 + _, x178 = bits.Mul64(x168, 0x4b0dff665588b13f) + var x180 uint64 + var x181 uint64 + x181, x180 = bits.Mul64(x178, 0xffffffffffffffff) + var x182 uint64 + var x183 uint64 + x183, x182 = bits.Mul64(x178, 0xfffffffffffffffe) + var x184 uint64 + var x185 uint64 + x185, x184 = bits.Mul64(x178, 0xbaaedce6af48a03b) + var x186 uint64 + var x187 uint64 + x187, x186 = bits.Mul64(x178, 0xbfd25e8cd0364141) + var x188 uint64 + var x189 uint64 + x188, x189 = bits.Add64(x187, x184, uint64(0x0)) + var x190 uint64 + var x191 uint64 + x190, x191 = bits.Add64(x185, x182, uint64(uint1(x189))) + var x192 uint64 + var x193 uint64 + x192, x193 = bits.Add64(x183, x180, uint64(uint1(x191))) + x194 := (uint64(uint1(x193)) + x181) + var x196 uint64 + _, x196 = bits.Add64(x168, x186, uint64(0x0)) + var x197 uint64 + var x198 uint64 + x197, x198 = bits.Add64(x170, x188, uint64(uint1(x196))) + var x199 uint64 + var x200 uint64 + x199, x200 = bits.Add64(x172, x190, uint64(uint1(x198))) + var x201 uint64 + var x202 uint64 + x201, x202 = bits.Add64(x174, x192, uint64(uint1(x200))) + var x203 uint64 + var x204 uint64 + x203, x204 = bits.Add64(x176, x194, uint64(uint1(x202))) + x205 := (uint64(uint1(x204)) + uint64(uint1(x177))) + var x206 uint64 + var x207 uint64 + x206, x207 = bits.Sub64(x197, 0xbfd25e8cd0364141, uint64(0x0)) + var x208 uint64 + var x209 uint64 + x208, x209 = bits.Sub64(x199, 0xbaaedce6af48a03b, uint64(uint1(x207))) + var x210 uint64 + var x211 uint64 + x210, x211 = bits.Sub64(x201, 0xfffffffffffffffe, uint64(uint1(x209))) + var x212 uint64 + var x213 uint64 + x212, x213 = bits.Sub64(x203, 0xffffffffffffffff, uint64(uint1(x211))) + var x215 uint64 + _, x215 = bits.Sub64(x205, uint64(0x0), uint64(uint1(x213))) + var x216 uint64 + cmovznzU64(&x216, uint1(x215), x206, x197) + var x217 uint64 + cmovznzU64(&x217, uint1(x215), x208, x199) + var x218 uint64 + cmovznzU64(&x218, uint1(x215), x210, x201) + var x219 uint64 + cmovznzU64(&x219, uint1(x215), x212, x203) + out1[0] = x216 + out1[1] = x217 + out1[2] = x218 + out1[3] = x219 +} + +// Square squares a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m +// 0 ≤ eval out1 < m +func Square(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg1[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg1[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg1[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg1[0]) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + x19 := (uint64(uint1(x18)) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0x4b0dff665588b13f) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0xffffffffffffffff) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0xfffffffffffffffe) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0xbaaedce6af48a03b) + var x28 uint64 + var x29 uint64 + x29, x28 = bits.Mul64(x20, 0xbfd25e8cd0364141) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x29, x26, uint64(0x0)) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x27, x24, uint64(uint1(x31))) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x25, x22, uint64(uint1(x33))) + x36 := (uint64(uint1(x35)) + x23) + var x38 uint64 + _, x38 = bits.Add64(x11, x28, uint64(0x0)) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x13, x30, uint64(uint1(x38))) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x15, x32, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64(x17, x34, uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Add64(x19, x36, uint64(uint1(x44))) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg1[3]) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x1, arg1[2]) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x1, arg1[1]) + var x53 uint64 + var x54 uint64 + x54, x53 = bits.Mul64(x1, arg1[0]) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x54, x51, uint64(0x0)) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x52, x49, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x50, x47, uint64(uint1(x58))) + x61 := (uint64(uint1(x60)) + x48) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x39, x53, uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x41, x55, uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x43, x57, uint64(uint1(x65))) + var x68 uint64 + var x69 uint64 + x68, x69 = bits.Add64(x45, x59, uint64(uint1(x67))) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(uint64(uint1(x46)), x61, uint64(uint1(x69))) + var x72 uint64 + _, x72 = bits.Mul64(x62, 0x4b0dff665588b13f) + var x74 uint64 + var x75 uint64 + x75, x74 = bits.Mul64(x72, 0xffffffffffffffff) + var x76 uint64 + var x77 uint64 + x77, x76 = bits.Mul64(x72, 0xfffffffffffffffe) + var x78 uint64 + var x79 uint64 + x79, x78 = bits.Mul64(x72, 0xbaaedce6af48a03b) + var x80 uint64 + var x81 uint64 + x81, x80 = bits.Mul64(x72, 0xbfd25e8cd0364141) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x81, x78, uint64(0x0)) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x79, x76, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x77, x74, uint64(uint1(x85))) + x88 := (uint64(uint1(x87)) + x75) + var x90 uint64 + _, x90 = bits.Add64(x62, x80, uint64(0x0)) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(x64, x82, uint64(uint1(x90))) + var x93 uint64 + var x94 uint64 + x93, x94 = bits.Add64(x66, x84, uint64(uint1(x92))) + var x95 uint64 + var x96 uint64 + x95, x96 = bits.Add64(x68, x86, uint64(uint1(x94))) + var x97 uint64 + var x98 uint64 + x97, x98 = bits.Add64(x70, x88, uint64(uint1(x96))) + x99 := (uint64(uint1(x98)) + uint64(uint1(x71))) + var x100 uint64 + var x101 uint64 + x101, x100 = bits.Mul64(x2, arg1[3]) + var x102 uint64 + var x103 uint64 + x103, x102 = bits.Mul64(x2, arg1[2]) + var x104 uint64 + var x105 uint64 + x105, x104 = bits.Mul64(x2, arg1[1]) + var x106 uint64 + var x107 uint64 + x107, x106 = bits.Mul64(x2, arg1[0]) + var x108 uint64 + var x109 uint64 + x108, x109 = bits.Add64(x107, x104, uint64(0x0)) + var x110 uint64 + var x111 uint64 + x110, x111 = bits.Add64(x105, x102, uint64(uint1(x109))) + var x112 uint64 + var x113 uint64 + x112, x113 = bits.Add64(x103, x100, uint64(uint1(x111))) + x114 := (uint64(uint1(x113)) + x101) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x91, x106, uint64(0x0)) + var x117 uint64 + var x118 uint64 + x117, x118 = bits.Add64(x93, x108, uint64(uint1(x116))) + var x119 uint64 + var x120 uint64 + x119, x120 = bits.Add64(x95, x110, uint64(uint1(x118))) + var x121 uint64 + var x122 uint64 + x121, x122 = bits.Add64(x97, x112, uint64(uint1(x120))) + var x123 uint64 + var x124 uint64 + x123, x124 = bits.Add64(x99, x114, uint64(uint1(x122))) + var x125 uint64 + _, x125 = bits.Mul64(x115, 0x4b0dff665588b13f) + var x127 uint64 + var x128 uint64 + x128, x127 = bits.Mul64(x125, 0xffffffffffffffff) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x125, 0xfffffffffffffffe) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x125, 0xbaaedce6af48a03b) + var x133 uint64 + var x134 uint64 + x134, x133 = bits.Mul64(x125, 0xbfd25e8cd0364141) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x134, x131, uint64(0x0)) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x132, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(x130, x127, uint64(uint1(x138))) + x141 := (uint64(uint1(x140)) + x128) + var x143 uint64 + _, x143 = bits.Add64(x115, x133, uint64(0x0)) + var x144 uint64 + var x145 uint64 + x144, x145 = bits.Add64(x117, x135, uint64(uint1(x143))) + var x146 uint64 + var x147 uint64 + x146, x147 = bits.Add64(x119, x137, uint64(uint1(x145))) + var x148 uint64 + var x149 uint64 + x148, x149 = bits.Add64(x121, x139, uint64(uint1(x147))) + var x150 uint64 + var x151 uint64 + x150, x151 = bits.Add64(x123, x141, uint64(uint1(x149))) + x152 := (uint64(uint1(x151)) + uint64(uint1(x124))) + var x153 uint64 + var x154 uint64 + x154, x153 = bits.Mul64(x3, arg1[3]) + var x155 uint64 + var x156 uint64 + x156, x155 = bits.Mul64(x3, arg1[2]) + var x157 uint64 + var x158 uint64 + x158, x157 = bits.Mul64(x3, arg1[1]) + var x159 uint64 + var x160 uint64 + x160, x159 = bits.Mul64(x3, arg1[0]) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Add64(x160, x157, uint64(0x0)) + var x163 uint64 + var x164 uint64 + x163, x164 = bits.Add64(x158, x155, uint64(uint1(x162))) + var x165 uint64 + var x166 uint64 + x165, x166 = bits.Add64(x156, x153, uint64(uint1(x164))) + x167 := (uint64(uint1(x166)) + x154) + var x168 uint64 + var x169 uint64 + x168, x169 = bits.Add64(x144, x159, uint64(0x0)) + var x170 uint64 + var x171 uint64 + x170, x171 = bits.Add64(x146, x161, uint64(uint1(x169))) + var x172 uint64 + var x173 uint64 + x172, x173 = bits.Add64(x148, x163, uint64(uint1(x171))) + var x174 uint64 + var x175 uint64 + x174, x175 = bits.Add64(x150, x165, uint64(uint1(x173))) + var x176 uint64 + var x177 uint64 + x176, x177 = bits.Add64(x152, x167, uint64(uint1(x175))) + var x178 uint64 + _, x178 = bits.Mul64(x168, 0x4b0dff665588b13f) + var x180 uint64 + var x181 uint64 + x181, x180 = bits.Mul64(x178, 0xffffffffffffffff) + var x182 uint64 + var x183 uint64 + x183, x182 = bits.Mul64(x178, 0xfffffffffffffffe) + var x184 uint64 + var x185 uint64 + x185, x184 = bits.Mul64(x178, 0xbaaedce6af48a03b) + var x186 uint64 + var x187 uint64 + x187, x186 = bits.Mul64(x178, 0xbfd25e8cd0364141) + var x188 uint64 + var x189 uint64 + x188, x189 = bits.Add64(x187, x184, uint64(0x0)) + var x190 uint64 + var x191 uint64 + x190, x191 = bits.Add64(x185, x182, uint64(uint1(x189))) + var x192 uint64 + var x193 uint64 + x192, x193 = bits.Add64(x183, x180, uint64(uint1(x191))) + x194 := (uint64(uint1(x193)) + x181) + var x196 uint64 + _, x196 = bits.Add64(x168, x186, uint64(0x0)) + var x197 uint64 + var x198 uint64 + x197, x198 = bits.Add64(x170, x188, uint64(uint1(x196))) + var x199 uint64 + var x200 uint64 + x199, x200 = bits.Add64(x172, x190, uint64(uint1(x198))) + var x201 uint64 + var x202 uint64 + x201, x202 = bits.Add64(x174, x192, uint64(uint1(x200))) + var x203 uint64 + var x204 uint64 + x203, x204 = bits.Add64(x176, x194, uint64(uint1(x202))) + x205 := (uint64(uint1(x204)) + uint64(uint1(x177))) + var x206 uint64 + var x207 uint64 + x206, x207 = bits.Sub64(x197, 0xbfd25e8cd0364141, uint64(0x0)) + var x208 uint64 + var x209 uint64 + x208, x209 = bits.Sub64(x199, 0xbaaedce6af48a03b, uint64(uint1(x207))) + var x210 uint64 + var x211 uint64 + x210, x211 = bits.Sub64(x201, 0xfffffffffffffffe, uint64(uint1(x209))) + var x212 uint64 + var x213 uint64 + x212, x213 = bits.Sub64(x203, 0xffffffffffffffff, uint64(uint1(x211))) + var x215 uint64 + _, x215 = bits.Sub64(x205, uint64(0x0), uint64(uint1(x213))) + var x216 uint64 + cmovznzU64(&x216, uint1(x215), x206, x197) + var x217 uint64 + cmovznzU64(&x217, uint1(x215), x208, x199) + var x218 uint64 + cmovznzU64(&x218, uint1(x215), x210, x201) + var x219 uint64 + cmovznzU64(&x219, uint1(x215), x212, x203) + out1[0] = x216 + out1[1] = x217 + out1[2] = x218 + out1[3] = x219 +} + +// Add adds two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Add(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Add64(arg1[0], arg2[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Add64(arg1[1], arg2[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Add64(arg1[2], arg2[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Add64(arg1[3], arg2[3], uint64(uint1(x6))) + var x9 uint64 + var x10 uint64 + x9, x10 = bits.Sub64(x1, 0xbfd25e8cd0364141, uint64(0x0)) + var x11 uint64 + var x12 uint64 + x11, x12 = bits.Sub64(x3, 0xbaaedce6af48a03b, uint64(uint1(x10))) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Sub64(x5, 0xfffffffffffffffe, uint64(uint1(x12))) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Sub64(x7, 0xffffffffffffffff, uint64(uint1(x14))) + var x18 uint64 + _, x18 = bits.Sub64(uint64(uint1(x8)), uint64(0x0), uint64(uint1(x16))) + var x19 uint64 + cmovznzU64(&x19, uint1(x18), x9, x1) + var x20 uint64 + cmovznzU64(&x20, uint1(x18), x11, x3) + var x21 uint64 + cmovznzU64(&x21, uint1(x18), x13, x5) + var x22 uint64 + cmovznzU64(&x22, uint1(x18), x15, x7) + out1[0] = x19 + out1[1] = x20 + out1[2] = x21 + out1[3] = x22 +} + +// Sub subtracts two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Sub(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Sub64(arg1[0], arg2[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Sub64(arg1[1], arg2[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Sub64(arg1[2], arg2[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Sub64(arg1[3], arg2[3], uint64(uint1(x6))) + var x9 uint64 + cmovznzU64(&x9, uint1(x8), uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x10, x11 = bits.Add64(x1, (x9 & 0xbfd25e8cd0364141), uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x3, (x9 & 0xbaaedce6af48a03b), uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x5, (x9 & 0xfffffffffffffffe), uint64(uint1(x13))) + var x16 uint64 + x16, _ = bits.Add64(x7, x9, uint64(uint1(x15))) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// Opp negates a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m +// 0 ≤ eval out1 < m +func Opp(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Sub64(uint64(0x0), arg1[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Sub64(uint64(0x0), arg1[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Sub64(uint64(0x0), arg1[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Sub64(uint64(0x0), arg1[3], uint64(uint1(x6))) + var x9 uint64 + cmovznzU64(&x9, uint1(x8), uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x10, x11 = bits.Add64(x1, (x9 & 0xbfd25e8cd0364141), uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x3, (x9 & 0xbaaedce6af48a03b), uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x5, (x9 & 0xfffffffffffffffe), uint64(uint1(x13))) + var x16 uint64 + x16, _ = bits.Add64(x7, x9, uint64(uint1(x15))) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// FromMontgomery translates a field element out of the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m +// 0 ≤ eval out1 < m +func FromMontgomery(out1 *NonMontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + x1 := arg1[0] + var x2 uint64 + _, x2 = bits.Mul64(x1, 0x4b0dff665588b13f) + var x4 uint64 + var x5 uint64 + x5, x4 = bits.Mul64(x2, 0xffffffffffffffff) + var x6 uint64 + var x7 uint64 + x7, x6 = bits.Mul64(x2, 0xfffffffffffffffe) + var x8 uint64 + var x9 uint64 + x9, x8 = bits.Mul64(x2, 0xbaaedce6af48a03b) + var x10 uint64 + var x11 uint64 + x11, x10 = bits.Mul64(x2, 0xbfd25e8cd0364141) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x11, x8, uint64(0x0)) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x9, x6, uint64(uint1(x13))) + var x16 uint64 + var x17 uint64 + x16, x17 = bits.Add64(x7, x4, uint64(uint1(x15))) + var x19 uint64 + _, x19 = bits.Add64(x1, x10, uint64(0x0)) + var x20 uint64 + var x21 uint64 + x20, x21 = bits.Add64(uint64(0x0), x12, uint64(uint1(x19))) + var x22 uint64 + var x23 uint64 + x22, x23 = bits.Add64(uint64(0x0), x14, uint64(uint1(x21))) + var x24 uint64 + var x25 uint64 + x24, x25 = bits.Add64(uint64(0x0), x16, uint64(uint1(x23))) + var x26 uint64 + var x27 uint64 + x26, x27 = bits.Add64(uint64(0x0), (uint64(uint1(x17)) + x5), uint64(uint1(x25))) + var x28 uint64 + var x29 uint64 + x28, x29 = bits.Add64(x20, arg1[1], uint64(0x0)) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x22, uint64(0x0), uint64(uint1(x29))) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x24, uint64(0x0), uint64(uint1(x31))) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x26, uint64(0x0), uint64(uint1(x33))) + var x36 uint64 + _, x36 = bits.Mul64(x28, 0x4b0dff665588b13f) + var x38 uint64 + var x39 uint64 + x39, x38 = bits.Mul64(x36, 0xffffffffffffffff) + var x40 uint64 + var x41 uint64 + x41, x40 = bits.Mul64(x36, 0xfffffffffffffffe) + var x42 uint64 + var x43 uint64 + x43, x42 = bits.Mul64(x36, 0xbaaedce6af48a03b) + var x44 uint64 + var x45 uint64 + x45, x44 = bits.Mul64(x36, 0xbfd25e8cd0364141) + var x46 uint64 + var x47 uint64 + x46, x47 = bits.Add64(x45, x42, uint64(0x0)) + var x48 uint64 + var x49 uint64 + x48, x49 = bits.Add64(x43, x40, uint64(uint1(x47))) + var x50 uint64 + var x51 uint64 + x50, x51 = bits.Add64(x41, x38, uint64(uint1(x49))) + var x53 uint64 + _, x53 = bits.Add64(x28, x44, uint64(0x0)) + var x54 uint64 + var x55 uint64 + x54, x55 = bits.Add64(x30, x46, uint64(uint1(x53))) + var x56 uint64 + var x57 uint64 + x56, x57 = bits.Add64(x32, x48, uint64(uint1(x55))) + var x58 uint64 + var x59 uint64 + x58, x59 = bits.Add64(x34, x50, uint64(uint1(x57))) + var x60 uint64 + var x61 uint64 + x60, x61 = bits.Add64((uint64(uint1(x35)) + uint64(uint1(x27))), (uint64(uint1(x51)) + x39), uint64(uint1(x59))) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x54, arg1[2], uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x56, uint64(0x0), uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x58, uint64(0x0), uint64(uint1(x65))) + var x68 uint64 + var x69 uint64 + x68, x69 = bits.Add64(x60, uint64(0x0), uint64(uint1(x67))) + var x70 uint64 + _, x70 = bits.Mul64(x62, 0x4b0dff665588b13f) + var x72 uint64 + var x73 uint64 + x73, x72 = bits.Mul64(x70, 0xffffffffffffffff) + var x74 uint64 + var x75 uint64 + x75, x74 = bits.Mul64(x70, 0xfffffffffffffffe) + var x76 uint64 + var x77 uint64 + x77, x76 = bits.Mul64(x70, 0xbaaedce6af48a03b) + var x78 uint64 + var x79 uint64 + x79, x78 = bits.Mul64(x70, 0xbfd25e8cd0364141) + var x80 uint64 + var x81 uint64 + x80, x81 = bits.Add64(x79, x76, uint64(0x0)) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x77, x74, uint64(uint1(x81))) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x75, x72, uint64(uint1(x83))) + var x87 uint64 + _, x87 = bits.Add64(x62, x78, uint64(0x0)) + var x88 uint64 + var x89 uint64 + x88, x89 = bits.Add64(x64, x80, uint64(uint1(x87))) + var x90 uint64 + var x91 uint64 + x90, x91 = bits.Add64(x66, x82, uint64(uint1(x89))) + var x92 uint64 + var x93 uint64 + x92, x93 = bits.Add64(x68, x84, uint64(uint1(x91))) + var x94 uint64 + var x95 uint64 + x94, x95 = bits.Add64((uint64(uint1(x69)) + uint64(uint1(x61))), (uint64(uint1(x85)) + x73), uint64(uint1(x93))) + var x96 uint64 + var x97 uint64 + x96, x97 = bits.Add64(x88, arg1[3], uint64(0x0)) + var x98 uint64 + var x99 uint64 + x98, x99 = bits.Add64(x90, uint64(0x0), uint64(uint1(x97))) + var x100 uint64 + var x101 uint64 + x100, x101 = bits.Add64(x92, uint64(0x0), uint64(uint1(x99))) + var x102 uint64 + var x103 uint64 + x102, x103 = bits.Add64(x94, uint64(0x0), uint64(uint1(x101))) + var x104 uint64 + _, x104 = bits.Mul64(x96, 0x4b0dff665588b13f) + var x106 uint64 + var x107 uint64 + x107, x106 = bits.Mul64(x104, 0xffffffffffffffff) + var x108 uint64 + var x109 uint64 + x109, x108 = bits.Mul64(x104, 0xfffffffffffffffe) + var x110 uint64 + var x111 uint64 + x111, x110 = bits.Mul64(x104, 0xbaaedce6af48a03b) + var x112 uint64 + var x113 uint64 + x113, x112 = bits.Mul64(x104, 0xbfd25e8cd0364141) + var x114 uint64 + var x115 uint64 + x114, x115 = bits.Add64(x113, x110, uint64(0x0)) + var x116 uint64 + var x117 uint64 + x116, x117 = bits.Add64(x111, x108, uint64(uint1(x115))) + var x118 uint64 + var x119 uint64 + x118, x119 = bits.Add64(x109, x106, uint64(uint1(x117))) + var x121 uint64 + _, x121 = bits.Add64(x96, x112, uint64(0x0)) + var x122 uint64 + var x123 uint64 + x122, x123 = bits.Add64(x98, x114, uint64(uint1(x121))) + var x124 uint64 + var x125 uint64 + x124, x125 = bits.Add64(x100, x116, uint64(uint1(x123))) + var x126 uint64 + var x127 uint64 + x126, x127 = bits.Add64(x102, x118, uint64(uint1(x125))) + var x128 uint64 + var x129 uint64 + x128, x129 = bits.Add64((uint64(uint1(x103)) + uint64(uint1(x95))), (uint64(uint1(x119)) + x107), uint64(uint1(x127))) + var x130 uint64 + var x131 uint64 + x130, x131 = bits.Sub64(x122, 0xbfd25e8cd0364141, uint64(0x0)) + var x132 uint64 + var x133 uint64 + x132, x133 = bits.Sub64(x124, 0xbaaedce6af48a03b, uint64(uint1(x131))) + var x134 uint64 + var x135 uint64 + x134, x135 = bits.Sub64(x126, 0xfffffffffffffffe, uint64(uint1(x133))) + var x136 uint64 + var x137 uint64 + x136, x137 = bits.Sub64(x128, 0xffffffffffffffff, uint64(uint1(x135))) + var x139 uint64 + _, x139 = bits.Sub64(uint64(uint1(x129)), uint64(0x0), uint64(uint1(x137))) + var x140 uint64 + cmovznzU64(&x140, uint1(x139), x130, x122) + var x141 uint64 + cmovznzU64(&x141, uint1(x139), x132, x124) + var x142 uint64 + cmovznzU64(&x142, uint1(x139), x134, x126) + var x143 uint64 + cmovznzU64(&x143, uint1(x139), x136, x128) + out1[0] = x140 + out1[1] = x141 + out1[2] = x142 + out1[3] = x143 +} + +// ToMontgomery translates a field element into the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = eval arg1 mod m +// 0 ≤ eval out1 < m +func ToMontgomery(out1 *MontgomeryDomainFieldElement, arg1 *NonMontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, 0x9d671cd581c69bc5) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, 0xe697f5e45bcd07c6) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, 0x741496c20e7cf878) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, 0x896cf21467d7d140) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + var x19 uint64 + _, x19 = bits.Mul64(x11, 0x4b0dff665588b13f) + var x21 uint64 + var x22 uint64 + x22, x21 = bits.Mul64(x19, 0xffffffffffffffff) + var x23 uint64 + var x24 uint64 + x24, x23 = bits.Mul64(x19, 0xfffffffffffffffe) + var x25 uint64 + var x26 uint64 + x26, x25 = bits.Mul64(x19, 0xbaaedce6af48a03b) + var x27 uint64 + var x28 uint64 + x28, x27 = bits.Mul64(x19, 0xbfd25e8cd0364141) + var x29 uint64 + var x30 uint64 + x29, x30 = bits.Add64(x28, x25, uint64(0x0)) + var x31 uint64 + var x32 uint64 + x31, x32 = bits.Add64(x26, x23, uint64(uint1(x30))) + var x33 uint64 + var x34 uint64 + x33, x34 = bits.Add64(x24, x21, uint64(uint1(x32))) + var x36 uint64 + _, x36 = bits.Add64(x11, x27, uint64(0x0)) + var x37 uint64 + var x38 uint64 + x37, x38 = bits.Add64(x13, x29, uint64(uint1(x36))) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x15, x31, uint64(uint1(x38))) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x17, x33, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64((uint64(uint1(x18)) + x6), (uint64(uint1(x34)) + x22), uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x46, x45 = bits.Mul64(x1, 0x9d671cd581c69bc5) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, 0xe697f5e45bcd07c6) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x1, 0x741496c20e7cf878) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x1, 0x896cf21467d7d140) + var x53 uint64 + var x54 uint64 + x53, x54 = bits.Add64(x52, x49, uint64(0x0)) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x50, x47, uint64(uint1(x54))) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x48, x45, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x37, x51, uint64(0x0)) + var x61 uint64 + var x62 uint64 + x61, x62 = bits.Add64(x39, x53, uint64(uint1(x60))) + var x63 uint64 + var x64 uint64 + x63, x64 = bits.Add64(x41, x55, uint64(uint1(x62))) + var x65 uint64 + var x66 uint64 + x65, x66 = bits.Add64(x43, x57, uint64(uint1(x64))) + var x67 uint64 + _, x67 = bits.Mul64(x59, 0x4b0dff665588b13f) + var x69 uint64 + var x70 uint64 + x70, x69 = bits.Mul64(x67, 0xffffffffffffffff) + var x71 uint64 + var x72 uint64 + x72, x71 = bits.Mul64(x67, 0xfffffffffffffffe) + var x73 uint64 + var x74 uint64 + x74, x73 = bits.Mul64(x67, 0xbaaedce6af48a03b) + var x75 uint64 + var x76 uint64 + x76, x75 = bits.Mul64(x67, 0xbfd25e8cd0364141) + var x77 uint64 + var x78 uint64 + x77, x78 = bits.Add64(x76, x73, uint64(0x0)) + var x79 uint64 + var x80 uint64 + x79, x80 = bits.Add64(x74, x71, uint64(uint1(x78))) + var x81 uint64 + var x82 uint64 + x81, x82 = bits.Add64(x72, x69, uint64(uint1(x80))) + var x84 uint64 + _, x84 = bits.Add64(x59, x75, uint64(0x0)) + var x85 uint64 + var x86 uint64 + x85, x86 = bits.Add64(x61, x77, uint64(uint1(x84))) + var x87 uint64 + var x88 uint64 + x87, x88 = bits.Add64(x63, x79, uint64(uint1(x86))) + var x89 uint64 + var x90 uint64 + x89, x90 = bits.Add64(x65, x81, uint64(uint1(x88))) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(((uint64(uint1(x66)) + uint64(uint1(x44))) + (uint64(uint1(x58)) + x46)), (uint64(uint1(x82)) + x70), uint64(uint1(x90))) + var x93 uint64 + var x94 uint64 + x94, x93 = bits.Mul64(x2, 0x9d671cd581c69bc5) + var x95 uint64 + var x96 uint64 + x96, x95 = bits.Mul64(x2, 0xe697f5e45bcd07c6) + var x97 uint64 + var x98 uint64 + x98, x97 = bits.Mul64(x2, 0x741496c20e7cf878) + var x99 uint64 + var x100 uint64 + x100, x99 = bits.Mul64(x2, 0x896cf21467d7d140) + var x101 uint64 + var x102 uint64 + x101, x102 = bits.Add64(x100, x97, uint64(0x0)) + var x103 uint64 + var x104 uint64 + x103, x104 = bits.Add64(x98, x95, uint64(uint1(x102))) + var x105 uint64 + var x106 uint64 + x105, x106 = bits.Add64(x96, x93, uint64(uint1(x104))) + var x107 uint64 + var x108 uint64 + x107, x108 = bits.Add64(x85, x99, uint64(0x0)) + var x109 uint64 + var x110 uint64 + x109, x110 = bits.Add64(x87, x101, uint64(uint1(x108))) + var x111 uint64 + var x112 uint64 + x111, x112 = bits.Add64(x89, x103, uint64(uint1(x110))) + var x113 uint64 + var x114 uint64 + x113, x114 = bits.Add64(x91, x105, uint64(uint1(x112))) + var x115 uint64 + _, x115 = bits.Mul64(x107, 0x4b0dff665588b13f) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x115, 0xffffffffffffffff) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x115, 0xfffffffffffffffe) + var x121 uint64 + var x122 uint64 + x122, x121 = bits.Mul64(x115, 0xbaaedce6af48a03b) + var x123 uint64 + var x124 uint64 + x124, x123 = bits.Mul64(x115, 0xbfd25e8cd0364141) + var x125 uint64 + var x126 uint64 + x125, x126 = bits.Add64(x124, x121, uint64(0x0)) + var x127 uint64 + var x128 uint64 + x127, x128 = bits.Add64(x122, x119, uint64(uint1(x126))) + var x129 uint64 + var x130 uint64 + x129, x130 = bits.Add64(x120, x117, uint64(uint1(x128))) + var x132 uint64 + _, x132 = bits.Add64(x107, x123, uint64(0x0)) + var x133 uint64 + var x134 uint64 + x133, x134 = bits.Add64(x109, x125, uint64(uint1(x132))) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x111, x127, uint64(uint1(x134))) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x113, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(((uint64(uint1(x114)) + uint64(uint1(x92))) + (uint64(uint1(x106)) + x94)), (uint64(uint1(x130)) + x118), uint64(uint1(x138))) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x3, 0x9d671cd581c69bc5) + var x143 uint64 + var x144 uint64 + x144, x143 = bits.Mul64(x3, 0xe697f5e45bcd07c6) + var x145 uint64 + var x146 uint64 + x146, x145 = bits.Mul64(x3, 0x741496c20e7cf878) + var x147 uint64 + var x148 uint64 + x148, x147 = bits.Mul64(x3, 0x896cf21467d7d140) + var x149 uint64 + var x150 uint64 + x149, x150 = bits.Add64(x148, x145, uint64(0x0)) + var x151 uint64 + var x152 uint64 + x151, x152 = bits.Add64(x146, x143, uint64(uint1(x150))) + var x153 uint64 + var x154 uint64 + x153, x154 = bits.Add64(x144, x141, uint64(uint1(x152))) + var x155 uint64 + var x156 uint64 + x155, x156 = bits.Add64(x133, x147, uint64(0x0)) + var x157 uint64 + var x158 uint64 + x157, x158 = bits.Add64(x135, x149, uint64(uint1(x156))) + var x159 uint64 + var x160 uint64 + x159, x160 = bits.Add64(x137, x151, uint64(uint1(x158))) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Add64(x139, x153, uint64(uint1(x160))) + var x163 uint64 + _, x163 = bits.Mul64(x155, 0x4b0dff665588b13f) + var x165 uint64 + var x166 uint64 + x166, x165 = bits.Mul64(x163, 0xffffffffffffffff) + var x167 uint64 + var x168 uint64 + x168, x167 = bits.Mul64(x163, 0xfffffffffffffffe) + var x169 uint64 + var x170 uint64 + x170, x169 = bits.Mul64(x163, 0xbaaedce6af48a03b) + var x171 uint64 + var x172 uint64 + x172, x171 = bits.Mul64(x163, 0xbfd25e8cd0364141) + var x173 uint64 + var x174 uint64 + x173, x174 = bits.Add64(x172, x169, uint64(0x0)) + var x175 uint64 + var x176 uint64 + x175, x176 = bits.Add64(x170, x167, uint64(uint1(x174))) + var x177 uint64 + var x178 uint64 + x177, x178 = bits.Add64(x168, x165, uint64(uint1(x176))) + var x180 uint64 + _, x180 = bits.Add64(x155, x171, uint64(0x0)) + var x181 uint64 + var x182 uint64 + x181, x182 = bits.Add64(x157, x173, uint64(uint1(x180))) + var x183 uint64 + var x184 uint64 + x183, x184 = bits.Add64(x159, x175, uint64(uint1(x182))) + var x185 uint64 + var x186 uint64 + x185, x186 = bits.Add64(x161, x177, uint64(uint1(x184))) + var x187 uint64 + var x188 uint64 + x187, x188 = bits.Add64(((uint64(uint1(x162)) + uint64(uint1(x140))) + (uint64(uint1(x154)) + x142)), (uint64(uint1(x178)) + x166), uint64(uint1(x186))) + var x189 uint64 + var x190 uint64 + x189, x190 = bits.Sub64(x181, 0xbfd25e8cd0364141, uint64(0x0)) + var x191 uint64 + var x192 uint64 + x191, x192 = bits.Sub64(x183, 0xbaaedce6af48a03b, uint64(uint1(x190))) + var x193 uint64 + var x194 uint64 + x193, x194 = bits.Sub64(x185, 0xfffffffffffffffe, uint64(uint1(x192))) + var x195 uint64 + var x196 uint64 + x195, x196 = bits.Sub64(x187, 0xffffffffffffffff, uint64(uint1(x194))) + var x198 uint64 + _, x198 = bits.Sub64(uint64(uint1(x188)), uint64(0x0), uint64(uint1(x196))) + var x199 uint64 + cmovznzU64(&x199, uint1(x198), x189, x181) + var x200 uint64 + cmovznzU64(&x200, uint1(x198), x191, x183) + var x201 uint64 + cmovznzU64(&x201, uint1(x198), x193, x185) + var x202 uint64 + cmovznzU64(&x202, uint1(x198), x195, x187) + out1[0] = x199 + out1[1] = x200 + out1[2] = x201 + out1[3] = x202 +} + +// Nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0 +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func Nonzero(out1 *uint64, arg1 *[4]uint64) { + x1 := (arg1[0] | (arg1[1] | (arg1[2] | arg1[3]))) + *out1 = x1 +} + +// Selectznz is a multi-limb conditional select. +// +// Postconditions: +// +// eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func Selectznz(out1 *[4]uint64, arg1 uint1, arg2 *[4]uint64, arg3 *[4]uint64) { + var x1 uint64 + cmovznzU64(&x1, arg1, arg2[0], arg3[0]) + var x2 uint64 + cmovznzU64(&x2, arg1, arg2[1], arg3[1]) + var x3 uint64 + cmovznzU64(&x3, arg1, arg2[2], arg3[2]) + var x4 uint64 + cmovznzU64(&x4, arg1, arg2[3], arg3[3]) + out1[0] = x1 + out1[1] = x2 + out1[2] = x3 + out1[3] = x4 +} + +// ToBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] +func ToBytes(out1 *[32]uint8, arg1 *[4]uint64) { + x1 := arg1[3] + x2 := arg1[2] + x3 := arg1[1] + x4 := arg1[0] + x5 := (uint8(x4) & 0xff) + x6 := (x4 >> 8) + x7 := (uint8(x6) & 0xff) + x8 := (x6 >> 8) + x9 := (uint8(x8) & 0xff) + x10 := (x8 >> 8) + x11 := (uint8(x10) & 0xff) + x12 := (x10 >> 8) + x13 := (uint8(x12) & 0xff) + x14 := (x12 >> 8) + x15 := (uint8(x14) & 0xff) + x16 := (x14 >> 8) + x17 := (uint8(x16) & 0xff) + x18 := uint8((x16 >> 8)) + x19 := (uint8(x3) & 0xff) + x20 := (x3 >> 8) + x21 := (uint8(x20) & 0xff) + x22 := (x20 >> 8) + x23 := (uint8(x22) & 0xff) + x24 := (x22 >> 8) + x25 := (uint8(x24) & 0xff) + x26 := (x24 >> 8) + x27 := (uint8(x26) & 0xff) + x28 := (x26 >> 8) + x29 := (uint8(x28) & 0xff) + x30 := (x28 >> 8) + x31 := (uint8(x30) & 0xff) + x32 := uint8((x30 >> 8)) + x33 := (uint8(x2) & 0xff) + x34 := (x2 >> 8) + x35 := (uint8(x34) & 0xff) + x36 := (x34 >> 8) + x37 := (uint8(x36) & 0xff) + x38 := (x36 >> 8) + x39 := (uint8(x38) & 0xff) + x40 := (x38 >> 8) + x41 := (uint8(x40) & 0xff) + x42 := (x40 >> 8) + x43 := (uint8(x42) & 0xff) + x44 := (x42 >> 8) + x45 := (uint8(x44) & 0xff) + x46 := uint8((x44 >> 8)) + x47 := (uint8(x1) & 0xff) + x48 := (x1 >> 8) + x49 := (uint8(x48) & 0xff) + x50 := (x48 >> 8) + x51 := (uint8(x50) & 0xff) + x52 := (x50 >> 8) + x53 := (uint8(x52) & 0xff) + x54 := (x52 >> 8) + x55 := (uint8(x54) & 0xff) + x56 := (x54 >> 8) + x57 := (uint8(x56) & 0xff) + x58 := (x56 >> 8) + x59 := (uint8(x58) & 0xff) + x60 := uint8((x58 >> 8)) + out1[0] = x5 + out1[1] = x7 + out1[2] = x9 + out1[3] = x11 + out1[4] = x13 + out1[5] = x15 + out1[6] = x17 + out1[7] = x18 + out1[8] = x19 + out1[9] = x21 + out1[10] = x23 + out1[11] = x25 + out1[12] = x27 + out1[13] = x29 + out1[14] = x31 + out1[15] = x32 + out1[16] = x33 + out1[17] = x35 + out1[18] = x37 + out1[19] = x39 + out1[20] = x41 + out1[21] = x43 + out1[22] = x45 + out1[23] = x46 + out1[24] = x47 + out1[25] = x49 + out1[26] = x51 + out1[27] = x53 + out1[28] = x55 + out1[29] = x57 + out1[30] = x59 + out1[31] = x60 +} + +// FromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ bytes_eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = bytes_eval arg1 mod m +// 0 ≤ eval out1 < m +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func FromBytes(out1 *[4]uint64, arg1 *[32]uint8) { + x1 := (uint64(arg1[31]) << 56) + x2 := (uint64(arg1[30]) << 48) + x3 := (uint64(arg1[29]) << 40) + x4 := (uint64(arg1[28]) << 32) + x5 := (uint64(arg1[27]) << 24) + x6 := (uint64(arg1[26]) << 16) + x7 := (uint64(arg1[25]) << 8) + x8 := arg1[24] + x9 := (uint64(arg1[23]) << 56) + x10 := (uint64(arg1[22]) << 48) + x11 := (uint64(arg1[21]) << 40) + x12 := (uint64(arg1[20]) << 32) + x13 := (uint64(arg1[19]) << 24) + x14 := (uint64(arg1[18]) << 16) + x15 := (uint64(arg1[17]) << 8) + x16 := arg1[16] + x17 := (uint64(arg1[15]) << 56) + x18 := (uint64(arg1[14]) << 48) + x19 := (uint64(arg1[13]) << 40) + x20 := (uint64(arg1[12]) << 32) + x21 := (uint64(arg1[11]) << 24) + x22 := (uint64(arg1[10]) << 16) + x23 := (uint64(arg1[9]) << 8) + x24 := arg1[8] + x25 := (uint64(arg1[7]) << 56) + x26 := (uint64(arg1[6]) << 48) + x27 := (uint64(arg1[5]) << 40) + x28 := (uint64(arg1[4]) << 32) + x29 := (uint64(arg1[3]) << 24) + x30 := (uint64(arg1[2]) << 16) + x31 := (uint64(arg1[1]) << 8) + x32 := arg1[0] + x33 := (x31 + uint64(x32)) + x34 := (x30 + x33) + x35 := (x29 + x34) + x36 := (x28 + x35) + x37 := (x27 + x36) + x38 := (x26 + x37) + x39 := (x25 + x38) + x40 := (x23 + uint64(x24)) + x41 := (x22 + x40) + x42 := (x21 + x41) + x43 := (x20 + x42) + x44 := (x19 + x43) + x45 := (x18 + x44) + x46 := (x17 + x45) + x47 := (x15 + uint64(x16)) + x48 := (x14 + x47) + x49 := (x13 + x48) + x50 := (x12 + x49) + x51 := (x11 + x50) + x52 := (x10 + x51) + x53 := (x9 + x52) + x54 := (x7 + uint64(x8)) + x55 := (x6 + x54) + x56 := (x5 + x55) + x57 := (x4 + x56) + x58 := (x3 + x57) + x59 := (x2 + x58) + x60 := (x1 + x59) + out1[0] = x39 + out1[1] = x46 + out1[2] = x53 + out1[3] = x60 +} + +// SetOne returns the field element one in the Montgomery domain. +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = 1 mod m +// 0 ≤ eval out1 < m +func SetOne(out1 *MontgomeryDomainFieldElement) { + out1[0] = 0x402da1732fc9bebf + out1[1] = 0x4551231950b75fc4 + out1[2] = uint64(0x1) + out1[3] = uint64(0x0) +} + +// Msat returns the saturated representation of the prime modulus. +// +// Postconditions: +// +// twos_complement_eval out1 = m +// 0 ≤ eval out1 < m +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func Msat(out1 *[5]uint64) { + out1[0] = 0xbfd25e8cd0364141 + out1[1] = 0xbaaedce6af48a03b + out1[2] = 0xfffffffffffffffe + out1[3] = 0xffffffffffffffff + out1[4] = uint64(0x0) +} + +// Divstep computes a divstep. +// +// Preconditions: +// +// 0 ≤ eval arg4 < m +// 0 ≤ eval arg5 < m +// +// Postconditions: +// +// out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1) +// twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2) +// twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋) +// eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m) +// eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m) +// 0 ≤ eval out5 < m +// 0 ≤ eval out5 < m +// 0 ≤ eval out2 < m +// 0 ≤ eval out3 < m +// +// Input Bounds: +// +// arg1: [0x0 ~> 0xffffffffffffffff] +// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +// out2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// out3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func Divstep(out1 *uint64, out2 *[5]uint64, out3 *[5]uint64, out4 *[4]uint64, out5 *[4]uint64, arg1 uint64, arg2 *[5]uint64, arg3 *[5]uint64, arg4 *[4]uint64, arg5 *[4]uint64) { + var x1 uint64 + x1, _ = bits.Add64((^arg1), uint64(0x1), uint64(0x0)) + x3 := (uint1((x1 >> 63)) & (uint1(arg3[0]) & 0x1)) + var x4 uint64 + x4, _ = bits.Add64((^arg1), uint64(0x1), uint64(0x0)) + var x6 uint64 + cmovznzU64(&x6, x3, arg1, x4) + var x7 uint64 + cmovznzU64(&x7, x3, arg2[0], arg3[0]) + var x8 uint64 + cmovznzU64(&x8, x3, arg2[1], arg3[1]) + var x9 uint64 + cmovznzU64(&x9, x3, arg2[2], arg3[2]) + var x10 uint64 + cmovznzU64(&x10, x3, arg2[3], arg3[3]) + var x11 uint64 + cmovznzU64(&x11, x3, arg2[4], arg3[4]) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(uint64(0x1), (^arg2[0]), uint64(0x0)) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(uint64(0x0), (^arg2[1]), uint64(uint1(x13))) + var x16 uint64 + var x17 uint64 + x16, x17 = bits.Add64(uint64(0x0), (^arg2[2]), uint64(uint1(x15))) + var x18 uint64 + var x19 uint64 + x18, x19 = bits.Add64(uint64(0x0), (^arg2[3]), uint64(uint1(x17))) + var x20 uint64 + x20, _ = bits.Add64(uint64(0x0), (^arg2[4]), uint64(uint1(x19))) + var x22 uint64 + cmovznzU64(&x22, x3, arg3[0], x12) + var x23 uint64 + cmovznzU64(&x23, x3, arg3[1], x14) + var x24 uint64 + cmovznzU64(&x24, x3, arg3[2], x16) + var x25 uint64 + cmovznzU64(&x25, x3, arg3[3], x18) + var x26 uint64 + cmovznzU64(&x26, x3, arg3[4], x20) + var x27 uint64 + cmovznzU64(&x27, x3, arg4[0], arg5[0]) + var x28 uint64 + cmovznzU64(&x28, x3, arg4[1], arg5[1]) + var x29 uint64 + cmovznzU64(&x29, x3, arg4[2], arg5[2]) + var x30 uint64 + cmovznzU64(&x30, x3, arg4[3], arg5[3]) + var x31 uint64 + var x32 uint64 + x31, x32 = bits.Add64(x27, x27, uint64(0x0)) + var x33 uint64 + var x34 uint64 + x33, x34 = bits.Add64(x28, x28, uint64(uint1(x32))) + var x35 uint64 + var x36 uint64 + x35, x36 = bits.Add64(x29, x29, uint64(uint1(x34))) + var x37 uint64 + var x38 uint64 + x37, x38 = bits.Add64(x30, x30, uint64(uint1(x36))) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Sub64(x31, 0xbfd25e8cd0364141, uint64(0x0)) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Sub64(x33, 0xbaaedce6af48a03b, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Sub64(x35, 0xfffffffffffffffe, uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Sub64(x37, 0xffffffffffffffff, uint64(uint1(x44))) + var x48 uint64 + _, x48 = bits.Sub64(uint64(uint1(x38)), uint64(0x0), uint64(uint1(x46))) + x49 := arg4[3] + x50 := arg4[2] + x51 := arg4[1] + x52 := arg4[0] + var x53 uint64 + var x54 uint64 + x53, x54 = bits.Sub64(uint64(0x0), x52, uint64(0x0)) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Sub64(uint64(0x0), x51, uint64(uint1(x54))) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Sub64(uint64(0x0), x50, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Sub64(uint64(0x0), x49, uint64(uint1(x58))) + var x61 uint64 + cmovznzU64(&x61, uint1(x60), uint64(0x0), 0xffffffffffffffff) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x53, (x61 & 0xbfd25e8cd0364141), uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x55, (x61 & 0xbaaedce6af48a03b), uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x57, (x61 & 0xfffffffffffffffe), uint64(uint1(x65))) + var x68 uint64 + x68, _ = bits.Add64(x59, x61, uint64(uint1(x67))) + var x70 uint64 + cmovznzU64(&x70, x3, arg5[0], x62) + var x71 uint64 + cmovznzU64(&x71, x3, arg5[1], x64) + var x72 uint64 + cmovznzU64(&x72, x3, arg5[2], x66) + var x73 uint64 + cmovznzU64(&x73, x3, arg5[3], x68) + x74 := (uint1(x22) & 0x1) + var x75 uint64 + cmovznzU64(&x75, x74, uint64(0x0), x7) + var x76 uint64 + cmovznzU64(&x76, x74, uint64(0x0), x8) + var x77 uint64 + cmovznzU64(&x77, x74, uint64(0x0), x9) + var x78 uint64 + cmovznzU64(&x78, x74, uint64(0x0), x10) + var x79 uint64 + cmovznzU64(&x79, x74, uint64(0x0), x11) + var x80 uint64 + var x81 uint64 + x80, x81 = bits.Add64(x22, x75, uint64(0x0)) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x23, x76, uint64(uint1(x81))) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x24, x77, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x25, x78, uint64(uint1(x85))) + var x88 uint64 + x88, _ = bits.Add64(x26, x79, uint64(uint1(x87))) + var x90 uint64 + cmovznzU64(&x90, x74, uint64(0x0), x27) + var x91 uint64 + cmovznzU64(&x91, x74, uint64(0x0), x28) + var x92 uint64 + cmovznzU64(&x92, x74, uint64(0x0), x29) + var x93 uint64 + cmovznzU64(&x93, x74, uint64(0x0), x30) + var x94 uint64 + var x95 uint64 + x94, x95 = bits.Add64(x70, x90, uint64(0x0)) + var x96 uint64 + var x97 uint64 + x96, x97 = bits.Add64(x71, x91, uint64(uint1(x95))) + var x98 uint64 + var x99 uint64 + x98, x99 = bits.Add64(x72, x92, uint64(uint1(x97))) + var x100 uint64 + var x101 uint64 + x100, x101 = bits.Add64(x73, x93, uint64(uint1(x99))) + var x102 uint64 + var x103 uint64 + x102, x103 = bits.Sub64(x94, 0xbfd25e8cd0364141, uint64(0x0)) + var x104 uint64 + var x105 uint64 + x104, x105 = bits.Sub64(x96, 0xbaaedce6af48a03b, uint64(uint1(x103))) + var x106 uint64 + var x107 uint64 + x106, x107 = bits.Sub64(x98, 0xfffffffffffffffe, uint64(uint1(x105))) + var x108 uint64 + var x109 uint64 + x108, x109 = bits.Sub64(x100, 0xffffffffffffffff, uint64(uint1(x107))) + var x111 uint64 + _, x111 = bits.Sub64(uint64(uint1(x101)), uint64(0x0), uint64(uint1(x109))) + var x112 uint64 + x112, _ = bits.Add64(x6, uint64(0x1), uint64(0x0)) + x114 := ((x80 >> 1) | ((x82 << 63) & 0xffffffffffffffff)) + x115 := ((x82 >> 1) | ((x84 << 63) & 0xffffffffffffffff)) + x116 := ((x84 >> 1) | ((x86 << 63) & 0xffffffffffffffff)) + x117 := ((x86 >> 1) | ((x88 << 63) & 0xffffffffffffffff)) + x118 := ((x88 & 0x8000000000000000) | (x88 >> 1)) + var x119 uint64 + cmovznzU64(&x119, uint1(x48), x39, x31) + var x120 uint64 + cmovznzU64(&x120, uint1(x48), x41, x33) + var x121 uint64 + cmovznzU64(&x121, uint1(x48), x43, x35) + var x122 uint64 + cmovznzU64(&x122, uint1(x48), x45, x37) + var x123 uint64 + cmovznzU64(&x123, uint1(x111), x102, x94) + var x124 uint64 + cmovznzU64(&x124, uint1(x111), x104, x96) + var x125 uint64 + cmovznzU64(&x125, uint1(x111), x106, x98) + var x126 uint64 + cmovznzU64(&x126, uint1(x111), x108, x100) + *out1 = x112 + out2[0] = x7 + out2[1] = x8 + out2[2] = x9 + out2[3] = x10 + out2[4] = x11 + out3[0] = x114 + out3[1] = x115 + out3[2] = x116 + out3[3] = x117 + out3[4] = x118 + out4[0] = x119 + out4[1] = x120 + out4[2] = x121 + out4[3] = x122 + out5[0] = x123 + out5[1] = x124 + out5[2] = x125 + out5[3] = x126 +} + +// DivstepPrecomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form). +// +// Postconditions: +// +// eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋) +// 0 ≤ eval out1 < m +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func DivstepPrecomp(out1 *[4]uint64) { + out1[0] = 0xd7431a4d2b9cb4e9 + out1[1] = 0xab67d35a32d9c503 + out1[2] = 0xadf6c7e5859ce35f + out1[3] = 0x615441451df6c379 +} diff --git a/pkg/crypto/core/curves/native/k256/point.go b/pkg/crypto/core/curves/native/k256/point.go new file mode 100755 index 000000000..0958eff93 --- /dev/null +++ b/pkg/crypto/core/curves/native/k256/point.go @@ -0,0 +1,446 @@ +package k256 + +import ( + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/k256/fp" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + k256PointInitonce sync.Once + k256PointParams native.EllipticPointParams + k256PointSswuInitOnce sync.Once + k256PointSswuParams native.SswuParams + k256PointIsogenyInitOnce sync.Once + k256PointIsogenyParams native.IsogenyParams +) + +func K256PointNew() *native.EllipticPoint { + return &native.EllipticPoint{ + X: fp.K256FpNew(), + Y: fp.K256FpNew(), + Z: fp.K256FpNew(), + Params: getK256PointParams(), + Arithmetic: &k256PointArithmetic{}, + } +} + +func k256PointParamsInit() { + k256PointParams = native.EllipticPointParams{ + A: fp.K256FpNew(), + B: fp.K256FpNew().SetUint64(7), + Gx: fp.K256FpNew().SetLimbs(&[native.FieldLimbs]uint64{ + 0x59f2815b16f81798, + 0x029bfcdb2dce28d9, + 0x55a06295ce870b07, + 0x79be667ef9dcbbac, + }), + Gy: fp.K256FpNew().SetLimbs(&[native.FieldLimbs]uint64{ + 0x9c47d08ffb10d4b8, + 0xfd17b448a6855419, + 0x5da4fbfc0e1108a8, + 0x483ada7726a3c465, + }), + BitSize: 256, + Name: "secp256k1", + } +} + +func getK256PointParams() *native.EllipticPointParams { + k256PointInitonce.Do(k256PointParamsInit) + return &k256PointParams +} + +func getK256PointSswuParams() *native.SswuParams { + k256PointSswuInitOnce.Do(k256PointSswuParamsInit) + return &k256PointSswuParams +} + +func k256PointSswuParamsInit() { + // Taken from https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-8.7 + //params := btcec.S256().Params() + // + //// c1 = (q - 3) / 4 + //c1 := new(big.Int).Set(params.P) + //c1.Sub(c1, big.NewInt(3)) + //c1.Rsh(c1, 2) + // + //a, _ := new(big.Int).SetString("3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533", 16) + //b := big.NewInt(1771) + //z := big.NewInt(-11) + //z.Mod(z, params.P) + //// sqrt(-z^3) + //zTmp := new(big.Int).Exp(z, big.NewInt(3), nil) + //zTmp = zTmp.Neg(zTmp) + //zTmp.Mod(zTmp, params.P) + //c2 := new(big.Int).ModSqrt(zTmp, params.P) + // + //var tBytes [32]byte + //c1.FillBytes(tBytes[:]) + //newC1 := [native.FieldLimbs]uint64{ + // binary.BigEndian.Uint64(tBytes[24:32]), + // binary.BigEndian.Uint64(tBytes[16:24]), + // binary.BigEndian.Uint64(tBytes[8:16]), + // binary.BigEndian.Uint64(tBytes[:8]), + //} + //fp.K256FpNew().Arithmetic.ToMontgomery(&newC1, &newC1) + //c2.FillBytes(tBytes[:]) + //newC2 := [native.FieldLimbs]uint64{ + // binary.BigEndian.Uint64(tBytes[24:32]), + // binary.BigEndian.Uint64(tBytes[16:24]), + // binary.BigEndian.Uint64(tBytes[8:16]), + // binary.BigEndian.Uint64(tBytes[:8]), + //} + //fp.K256FpNew().Arithmetic.ToMontgomery(&newC2, &newC2) + //a.FillBytes(tBytes[:]) + //newA := [native.FieldLimbs]uint64{ + // binary.BigEndian.Uint64(tBytes[24:32]), + // binary.BigEndian.Uint64(tBytes[16:24]), + // binary.BigEndian.Uint64(tBytes[8:16]), + // binary.BigEndian.Uint64(tBytes[:8]), + //} + //fp.K256FpNew().Arithmetic.ToMontgomery(&newA, &newA) + //b.FillBytes(tBytes[:]) + //newB := [native.FieldLimbs]uint64{ + // binary.BigEndian.Uint64(tBytes[24:32]), + // binary.BigEndian.Uint64(tBytes[16:24]), + // binary.BigEndian.Uint64(tBytes[8:16]), + // binary.BigEndian.Uint64(tBytes[:8]), + //} + //fp.K256FpNew().Arithmetic.ToMontgomery(&newB, &newB) + //z.FillBytes(tBytes[:]) + //newZ := [native.FieldLimbs]uint64{ + // binary.BigEndian.Uint64(tBytes[24:32]), + // binary.BigEndian.Uint64(tBytes[16:24]), + // binary.BigEndian.Uint64(tBytes[8:16]), + // binary.BigEndian.Uint64(tBytes[:8]), + //} + //fp.K256FpNew().Arithmetic.ToMontgomery(&newZ, &newZ) + + k256PointSswuParams = native.SswuParams{ + // (q -3) // 4 + C1: [native.FieldLimbs]uint64{0xffffffffbfffff0b, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffffffff}, + // sqrt(-z^3) + C2: [native.FieldLimbs]uint64{0x5b57ba53a30d1520, 0x908f7cef34a762eb, 0x190b0ffe068460c8, 0x98a9828e8f00ff62}, + // 0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533 + A: [native.FieldLimbs]uint64{0xdb714ce7b18444a1, 0x4458ce38a32a19a2, 0xa0e58ae2837bfbf0, 0x505aabc49336d959}, + // 1771 + B: [native.FieldLimbs]uint64{0x000006eb001a66db, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000}, + // -11 + Z: [native.FieldLimbs]uint64{0xfffffff3ffffd234, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}, + } +} + +func k256PointIsogenyInit() { + k256PointIsogenyParams = native.IsogenyParams{ + XNum: [][native.FieldLimbs]uint64{ + { + 0x0000003b1c72a8b4, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + { + 0xd5bd51a17b2edf46, + 0x2cc06f7c86b86bcd, + 0x50b37e74f3294a00, + 0xeb32314a9da73679, + }, + { + 0x48c18b1b0d2191bd, + 0x5a3f74c29bfccce3, + 0xbe55a02e5e8bd357, + 0x09bf218d11fff905, + }, + { + 0x000000001c71c789, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + }, + XDen: [][native.FieldLimbs]uint64{ + { + 0x8af79c1ffdf1e7fa, + 0xb84bc22235735eb5, + 0x82ee5655a55ace04, + 0xce4b32dea0a2becb, + }, + { + 0x8ecde3f3762e1fa5, + 0x2c3b1ad77be333fd, + 0xb102a1a152ea6e12, + 0x57b82df5a1ffc133, + }, + { + 0x00000001000003d1, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + }, + YNum: [][native.FieldLimbs]uint64{ + { + 0xffffffce425e12c3, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + }, + { + 0xba60d5fd6e56922e, + 0x4ec198c898a435f2, + 0x27e77a577b9764ab, + 0xb3b80a1197651d12, + }, + { + 0xa460c58d0690c6f6, + 0xad1fba614dfe6671, + 0xdf2ad0172f45e9ab, + 0x84df90c688fffc82, + }, + { + 0x00000000097b4283, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + }, + YDen: [][native.FieldLimbs]uint64{ + { + 0xfffffd0afff4b6fb, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + }, + { + 0xa0e6d461f9d5bf90, + 0x28e34666a05a1c20, + 0x88cb0300f0106a0e, + 0x6ae1989be1e83c62, + }, + { + 0x5634d5edb1453160, + 0x4258a84339d4cdfc, + 0x8983f271fc5fa51b, + 0x039444f072ffa1cd, + }, + { + 0x00000001000003d1, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + }, + }, + } +} + +func getK256PointIsogenyParams() *native.IsogenyParams { + k256PointIsogenyInitOnce.Do(k256PointIsogenyInit) + return &k256PointIsogenyParams +} + +type k256PointArithmetic struct{} + +func (k k256PointArithmetic) Hash(out *native.EllipticPoint, hash *native.EllipticPointHasher, msg, dst []byte) error { + var u []byte + sswuParams := getK256PointSswuParams() + isoParams := getK256PointIsogenyParams() + + switch hash.Type() { + case native.XMD: + u = native.ExpandMsgXmd(hash, msg, dst, 96) + case native.XOF: + u = native.ExpandMsgXof(hash, msg, dst, 96) + } + var buf [64]byte + copy(buf[:48], internal.ReverseScalarBytes(u[:48])) + u0 := fp.K256FpNew().SetBytesWide(&buf) + copy(buf[:48], internal.ReverseScalarBytes(u[48:])) + u1 := fp.K256FpNew().SetBytesWide(&buf) + + r0x, r0y := sswuParams.Osswu3mod4(u0) + r1x, r1y := sswuParams.Osswu3mod4(u1) + q0x, q0y := isoParams.Map(r0x, r0y) + q1x, q1y := isoParams.Map(r1x, r1y) + out.X = q0x + out.Y = q0y + out.Z.SetOne() + tv := &native.EllipticPoint{ + X: q1x, + Y: q1y, + Z: fp.K256FpNew().SetOne(), + } + k.Add(out, out, tv) + return nil +} + +func (k k256PointArithmetic) Double(out, arg *native.EllipticPoint) { + // Addition formula from Renes-Costello-Batina 2015 + // (https://eprint.iacr.org/2015/1060 Algorithm 9) + var yy, zz, xy2, bzz, bzz3, bzz9 [native.FieldLimbs]uint64 + var yyMBzz9, yyPBzz3, yyzz, yyzz8, t [native.FieldLimbs]uint64 + var x, y, z [native.FieldLimbs]uint64 + f := arg.X.Arithmetic + + f.Square(&yy, &arg.Y.Value) + f.Square(&zz, &arg.Z.Value) + f.Mul(&xy2, &arg.X.Value, &arg.Y.Value) + f.Add(&xy2, &xy2, &xy2) + f.Mul(&bzz, &zz, &arg.Params.B.Value) + f.Add(&bzz3, &bzz, &bzz) + f.Add(&bzz3, &bzz3, &bzz) + f.Add(&bzz9, &bzz3, &bzz3) + f.Add(&bzz9, &bzz9, &bzz3) + f.Neg(&yyMBzz9, &bzz9) + f.Add(&yyMBzz9, &yyMBzz9, &yy) + f.Add(&yyPBzz3, &yy, &bzz3) + f.Mul(&yyzz, &yy, &zz) + f.Add(&yyzz8, &yyzz, &yyzz) + f.Add(&yyzz8, &yyzz8, &yyzz8) + f.Add(&yyzz8, &yyzz8, &yyzz8) + f.Add(&t, &yyzz8, &yyzz8) + f.Add(&t, &t, &yyzz8) + f.Mul(&t, &t, &arg.Params.B.Value) + + f.Mul(&x, &xy2, &yyMBzz9) + + f.Mul(&y, &yyMBzz9, &yyPBzz3) + f.Add(&y, &y, &t) + + f.Mul(&z, &yy, &arg.Y.Value) + f.Mul(&z, &z, &arg.Z.Value) + f.Add(&z, &z, &z) + f.Add(&z, &z, &z) + f.Add(&z, &z, &z) + + out.X.Value = x + out.Y.Value = y + out.Z.Value = z +} + +func (k k256PointArithmetic) Add(out, arg1, arg2 *native.EllipticPoint) { + // Addition formula from Renes-Costello-Batina 2015 + // (https://eprint.iacr.org/2015/1060 Algorithm 7). + var xx, yy, zz, nXxYy, nYyZz, nXxZz [native.FieldLimbs]uint64 + var tv1, tv2, xyPairs, yzPairs, xzPairs [native.FieldLimbs]uint64 + var bzz, bzz3, yyMBzz3, yyPBzz3, byz [native.FieldLimbs]uint64 + var byz3, xx3, bxx9, x, y, z [native.FieldLimbs]uint64 + f := arg1.X.Arithmetic + + f.Mul(&xx, &arg1.X.Value, &arg2.X.Value) + f.Mul(&yy, &arg1.Y.Value, &arg2.Y.Value) + f.Mul(&zz, &arg1.Z.Value, &arg2.Z.Value) + + f.Add(&nXxYy, &xx, &yy) + f.Neg(&nXxYy, &nXxYy) + + f.Add(&nYyZz, &yy, &zz) + f.Neg(&nYyZz, &nYyZz) + + f.Add(&nXxZz, &xx, &zz) + f.Neg(&nXxZz, &nXxZz) + + f.Add(&tv1, &arg1.X.Value, &arg1.Y.Value) + f.Add(&tv2, &arg2.X.Value, &arg2.Y.Value) + f.Mul(&xyPairs, &tv1, &tv2) + f.Add(&xyPairs, &xyPairs, &nXxYy) + + f.Add(&tv1, &arg1.Y.Value, &arg1.Z.Value) + f.Add(&tv2, &arg2.Y.Value, &arg2.Z.Value) + f.Mul(&yzPairs, &tv1, &tv2) + f.Add(&yzPairs, &yzPairs, &nYyZz) + + f.Add(&tv1, &arg1.X.Value, &arg1.Z.Value) + f.Add(&tv2, &arg2.X.Value, &arg2.Z.Value) + f.Mul(&xzPairs, &tv1, &tv2) + f.Add(&xzPairs, &xzPairs, &nXxZz) + + f.Mul(&bzz, &zz, &arg1.Params.B.Value) + f.Add(&bzz3, &bzz, &bzz) + f.Add(&bzz3, &bzz3, &bzz) + + f.Neg(&yyMBzz3, &bzz3) + f.Add(&yyMBzz3, &yyMBzz3, &yy) + + f.Add(&yyPBzz3, &yy, &bzz3) + + f.Mul(&byz, &yzPairs, &arg1.Params.B.Value) + f.Add(&byz3, &byz, &byz) + f.Add(&byz3, &byz3, &byz) + + f.Add(&xx3, &xx, &xx) + f.Add(&xx3, &xx3, &xx) + + f.Add(&bxx9, &xx3, &xx3) + f.Add(&bxx9, &bxx9, &xx3) + f.Mul(&bxx9, &bxx9, &arg1.Params.B.Value) + + f.Mul(&tv1, &xyPairs, &yyMBzz3) + f.Mul(&tv2, &byz3, &xzPairs) + f.Neg(&tv2, &tv2) + f.Add(&x, &tv1, &tv2) + + f.Mul(&tv1, &yyPBzz3, &yyMBzz3) + f.Mul(&tv2, &bxx9, &xzPairs) + f.Add(&y, &tv1, &tv2) + + f.Mul(&tv1, &yzPairs, &yyPBzz3) + f.Mul(&tv2, &xx3, &xyPairs) + f.Add(&z, &tv1, &tv2) + + e1 := arg1.Z.IsZero() + e2 := arg2.Z.IsZero() + + // If arg1 is identity set it to arg2 + f.Selectznz(&z, &z, &arg2.Z.Value, e1) + f.Selectznz(&y, &y, &arg2.Y.Value, e1) + f.Selectznz(&x, &x, &arg2.X.Value, e1) + // If arg2 is identity set it to arg1 + f.Selectznz(&z, &z, &arg1.Z.Value, e2) + f.Selectznz(&y, &y, &arg1.Y.Value, e2) + f.Selectznz(&x, &x, &arg1.X.Value, e2) + + out.X.Value = x + out.Y.Value = y + out.Z.Value = z +} + +func (k k256PointArithmetic) IsOnCurve(arg *native.EllipticPoint) bool { + affine := K256PointNew() + k.ToAffine(affine, arg) + lhs := fp.K256FpNew().Square(affine.Y) + rhs := fp.K256FpNew() + k.RhsEq(rhs, affine.X) + return lhs.Equal(rhs) == 1 +} + +func (k k256PointArithmetic) ToAffine(out, arg *native.EllipticPoint) { + var wasInverted int + var zero, x, y, z [native.FieldLimbs]uint64 + f := arg.X.Arithmetic + + f.Invert(&wasInverted, &z, &arg.Z.Value) + f.Mul(&x, &arg.X.Value, &z) + f.Mul(&y, &arg.Y.Value, &z) + + out.Z.SetOne() + // If point at infinity this does nothing + f.Selectznz(&x, &zero, &x, wasInverted) + f.Selectznz(&y, &zero, &y, wasInverted) + f.Selectznz(&z, &zero, &out.Z.Value, wasInverted) + + out.X.Value = x + out.Y.Value = y + out.Z.Value = z + out.Params = arg.Params + out.Arithmetic = arg.Arithmetic +} + +func (k k256PointArithmetic) RhsEq(out, x *native.Field) { + // Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7 + out.Square(x) + out.Mul(out, x) + out.Add(out, getK256PointParams().B) +} diff --git a/pkg/crypto/core/curves/native/k256/point_test.go b/pkg/crypto/core/curves/native/k256/point_test.go new file mode 100755 index 000000000..0336bd1ba --- /dev/null +++ b/pkg/crypto/core/curves/native/k256/point_test.go @@ -0,0 +1,19 @@ +package k256_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/k256" +) + +func TestK256PointArithmetic_Hash(t *testing.T) { + var b [32]byte + sc, err := k256.K256PointNew().Hash(b[:], native.EllipticPointHasherSha256()) + + require.NoError(t, err) + require.True(t, !sc.IsIdentity()) + require.True(t, sc.IsOnCurve()) +} diff --git a/pkg/crypto/core/curves/native/osswu.go b/pkg/crypto/core/curves/native/osswu.go new file mode 100755 index 000000000..ba867f351 --- /dev/null +++ b/pkg/crypto/core/curves/native/osswu.go @@ -0,0 +1,82 @@ +package native + +// SswuParams for computing the Simplified SWU mapping +// for hash to curve implementations +type SswuParams struct { + C1, C2, A, B, Z [FieldLimbs]uint64 +} + +// Osswu3mod4 computes the simplified map optmized for 3 mod 4 primes +// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-11#appendix-G.2.1 +func (p *SswuParams) Osswu3mod4(u *Field) (x, y *Field) { + var tv1, tv2, tv3, tv4, xd, x1n, x2n, gxd, gx1, aNeg, zA, y1, y2 [FieldLimbs]uint64 + var wasInverted int + u.Arithmetic.Mul(&tv1, &u.Value, &u.Value) // tv1 = u^2 + u.Arithmetic.Mul(&tv3, &p.Z, &tv1) // tv3 = z * tv1 + u.Arithmetic.Square(&tv2, &tv3) // tv2 = tv3^2 + u.Arithmetic.Add(&xd, &tv2, &tv3) // xd = tv2 + tv3 + u.Arithmetic.Add(&x1n, &u.Params.R, &xd) // x1n = (xd + 1) + u.Arithmetic.Mul(&x1n, &x1n, &p.B) // x1n * B + u.Arithmetic.Neg(&aNeg, &p.A) + u.Arithmetic.Mul(&xd, &xd, &aNeg) // xd = -A * xd + + xdIsZero := (&Field{ + Value: xd, + }).IsZero() + u.Arithmetic.Mul(&zA, &p.Z, &p.A) + u.Arithmetic.Selectznz(&xd, &xd, &zA, xdIsZero) // xd = z * A if xd == 0 + + u.Arithmetic.Square(&tv2, &xd) // tv2 = xd^2 + u.Arithmetic.Mul(&gxd, &tv2, &xd) // gxd = tv2 * xd + u.Arithmetic.Mul(&tv2, &tv2, &p.A) // tv2 = A * tv2 + + u.Arithmetic.Square(&gx1, &x1n) // gx1 = x1n^2 + u.Arithmetic.Add(&gx1, &gx1, &tv2) // gx1 = gx1 + tv2 + u.Arithmetic.Mul(&gx1, &gx1, &x1n) // gx1 = gx1 * x1n + u.Arithmetic.Mul(&tv2, &gxd, &p.B) // tv2 = B * gxd + u.Arithmetic.Add(&gx1, &gx1, &tv2) // gx1 = gx1 + tv2 + + u.Arithmetic.Square(&tv4, &gxd) // tv4 = gxd^2 + u.Arithmetic.Mul(&tv2, &gx1, &gxd) // tv2 = gx1 * gxd + u.Arithmetic.Mul(&tv4, &tv4, &tv2) // tv4 = tv4 * tv2 + + Pow(&y1, &tv4, &p.C1, u.Params, u.Arithmetic) // y1 = tv4^C1 + u.Arithmetic.Mul(&y1, &y1, &tv2) //y1 = y1 * tv2 + u.Arithmetic.Mul(&x2n, &tv3, &x1n) // x2n = tv3 * x1n + + u.Arithmetic.Mul(&y2, &y1, &p.C2) // y2 = y1 * c2 + u.Arithmetic.Mul(&y2, &y2, &tv1) // y2 = y2 * tv1 + u.Arithmetic.Mul(&y2, &y2, &u.Value) // y2 = y2 * u + + u.Arithmetic.Square(&tv2, &y1) // tv2 = y1^2 + u.Arithmetic.Mul(&tv2, &tv2, &gxd) // tv2 = tv2 * gxd + + e2 := (&Field{Value: tv2}).Equal(&Field{Value: gx1}) + + x = new(Field).Set(u) + y = new(Field).Set(u) + + // If e2, x = x1, else x = x2 + u.Arithmetic.Selectznz(&x.Value, &x2n, &x1n, e2) + + // xn / xd + u.Arithmetic.Invert(&wasInverted, &tv1, &xd) + u.Arithmetic.Mul(&tv1, &x.Value, &tv1) + u.Arithmetic.Selectznz(&x.Value, &x.Value, &tv1, wasInverted) + + // If e2, y = y1, else y = y2 + u.Arithmetic.Selectznz(&y.Value, &y2, &y1, e2) + + uBytes := u.Bytes() + yBytes := y.Bytes() + + usign := uBytes[0] & 1 + ysign := yBytes[0] & 1 + + // Fix sign of y + if usign != ysign { + y.Neg(y) + } + + return +} diff --git a/pkg/crypto/core/curves/native/p256/fp/fp.go b/pkg/crypto/core/curves/native/p256/fp/fp.go new file mode 100755 index 000000000..c5c1b84c9 --- /dev/null +++ b/pkg/crypto/core/curves/native/p256/fp/fp.go @@ -0,0 +1,172 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fp + +import ( + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +var ( + p256FpInitonce sync.Once + p256FpParams native.FieldParams +) + +func P256FpNew() *native.Field { + return &native.Field{ + Value: [native.FieldLimbs]uint64{}, + Params: getP256FpParams(), + Arithmetic: p256FpArithmetic{}, + } +} + +func p256FpParamsInit() { + // See FIPS 186-3, section D.2.3 + p256FpParams = native.FieldParams{ + R: [native.FieldLimbs]uint64{0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe}, + R2: [native.FieldLimbs]uint64{0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd}, + R3: [native.FieldLimbs]uint64{0xfffffffd0000000a, 0xffffffedfffffff7, 0x00000005fffffffc, 0x0000001800000001}, + Modulus: [native.FieldLimbs]uint64{0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001}, + BiModulus: new(big.Int).SetBytes([]byte{ + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }), + } +} + +func getP256FpParams() *native.FieldParams { + p256FpInitonce.Do(p256FpParamsInit) + return &p256FpParams +} + +// p256FpArithmetic is a struct with all the methods needed for working +// in mod q +type p256FpArithmetic struct{} + +// ToMontgomery converts this field to montgomery form +func (f p256FpArithmetic) ToMontgomery(out, arg *[native.FieldLimbs]uint64) { + ToMontgomery((*MontgomeryDomainFieldElement)(out), (*NonMontgomeryDomainFieldElement)(arg)) +} + +// FromMontgomery converts this field from montgomery form +func (f p256FpArithmetic) FromMontgomery(out, arg *[native.FieldLimbs]uint64) { + FromMontgomery((*NonMontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Neg performs modular negation +func (f p256FpArithmetic) Neg(out, arg *[native.FieldLimbs]uint64) { + Opp((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Square performs modular square +func (f p256FpArithmetic) Square(out, arg *[native.FieldLimbs]uint64) { + Square((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Mul performs modular multiplication +func (f p256FpArithmetic) Mul(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Mul((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Add performs modular addition +func (f p256FpArithmetic) Add(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Add((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Sub performs modular subtraction +func (f p256FpArithmetic) Sub(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Sub((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Sqrt performs modular square root +func (f p256FpArithmetic) Sqrt(wasSquare *int, out, arg *[native.FieldLimbs]uint64) { + // Use p = 3 mod 4 by Euler's criterion means + // arg^((p+1)/4 mod p + var t, c [native.FieldLimbs]uint64 + c1 := [native.FieldLimbs]uint64{ + 0x0000_0000_0000_0000, + 0x0000_0000_4000_0000, + 0x4000_0000_0000_0000, + 0x3fff_ffff_c000_0000, + } + native.Pow(&t, arg, &c1, getP256FpParams(), f) + Square((*MontgomeryDomainFieldElement)(&c), (*MontgomeryDomainFieldElement)(&t)) + *wasSquare = (&native.Field{Value: c, Params: getP256FpParams(), Arithmetic: f}).Equal(&native.Field{ + Value: *arg, Params: getP256FpParams(), Arithmetic: f, + }) + Selectznz(out, uint1(*wasSquare), out, &t) +} + +// Invert performs modular inverse +func (f p256FpArithmetic) Invert(wasInverted *int, out, arg *[native.FieldLimbs]uint64) { + // Fermat's Little Theorem + // a ^ (p - 2) mod p + // + // The exponent pattern (from high to low) is: + // - 32 bits of value 1 + // - 31 bits of value 0 + // - 1 bit of value 1 + // - 96 bits of value 0 + // - 94 bits of value 1 + // - 1 bit of value 0 + // - 1 bit of value 1 + // To speed up the square-and-multiply algorithm, precompute a^(2^31-1). + // + // Courtesy of Thomas Pornin + // + var t, r [native.FieldLimbs]uint64 + copy(t[:], arg[:]) + + for i := 0; i < 30; i++ { + f.Square(&t, &t) + f.Mul(&t, &t, arg) + } + copy(r[:], t[:]) + for i := 224; i >= 0; i-- { + f.Square(&r, &r) + switch i { + case 0: + fallthrough + case 2: + fallthrough + case 192: + fallthrough + case 224: + f.Mul(&r, &r, arg) + case 3: + fallthrough + case 34: + fallthrough + case 65: + f.Mul(&r, &r, &t) + } + } + + *wasInverted = (&native.Field{ + Value: *arg, + Params: getP256FpParams(), + Arithmetic: f, + }).IsNonZero() + Selectznz(out, uint1(*wasInverted), out, &r) +} + +// FromBytes converts a little endian byte array into a field element +func (f p256FpArithmetic) FromBytes(out *[native.FieldLimbs]uint64, arg *[native.FieldBytes]byte) { + FromBytes(out, arg) +} + +// ToBytes converts a field element to a little endian byte array +func (f p256FpArithmetic) ToBytes(out *[native.FieldBytes]byte, arg *[native.FieldLimbs]uint64) { + ToBytes(out, arg) +} + +// Selectznz performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f p256FpArithmetic) Selectznz(out, arg1, arg2 *[native.FieldLimbs]uint64, choice int) { + Selectznz(out, uint1(choice), arg1, arg2) +} diff --git a/pkg/crypto/core/curves/native/p256/fp/fp_test.go b/pkg/crypto/core/curves/native/p256/fp/fp_test.go new file mode 100755 index 000000000..97b950b48 --- /dev/null +++ b/pkg/crypto/core/curves/native/p256/fp/fp_test.go @@ -0,0 +1,328 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fp + +import ( + crand "crypto/rand" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func TestFpSetOne(t *testing.T) { + fq := P256FpNew().SetOne() + require.NotNil(t, fq) + require.Equal(t, fq.Value, getP256FpParams().R) +} + +func TestFpSetUint64(t *testing.T) { + act := P256FpNew().SetUint64(1 << 60) + require.NotNil(t, act) + // Remember it will be in montgomery form + require.Equal(t, act.Value[0], uint64(0x100000000fffffff)) +} + +func TestFpAdd(t *testing.T) { + lhs := P256FpNew().SetOne() + rhs := P256FpNew().SetOne() + exp := P256FpNew().SetUint64(2) + res := P256FpNew().Add(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + e := l + r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := P256FpNew().Add(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpSub(t *testing.T) { + lhs := P256FpNew().SetOne() + rhs := P256FpNew().SetOne() + exp := P256FpNew().SetZero() + res := P256FpNew().Sub(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + if l < r { + l, r = r, l + } + e := l - r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := P256FpNew().Sub(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpMul(t *testing.T) { + lhs := P256FpNew().SetOne() + rhs := P256FpNew().SetOne() + exp := P256FpNew().SetOne() + res := P256FpNew().Mul(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint32() + r := rand.Uint32() + e := uint64(l) * uint64(r) + lhs.SetUint64(uint64(l)) + rhs.SetUint64(uint64(r)) + exp.SetUint64(e) + + a := P256FpNew().Mul(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpDouble(t *testing.T) { + a := P256FpNew().SetUint64(2) + e := P256FpNew().SetUint64(4) + require.Equal(t, e, P256FpNew().Double(a)) + + for i := 0; i < 25; i++ { + tv := rand.Uint32() + ttv := uint64(tv) * 2 + a = P256FpNew().SetUint64(uint64(tv)) + e = P256FpNew().SetUint64(ttv) + require.Equal(t, e, P256FpNew().Double(a)) + } +} + +func TestFpSquare(t *testing.T) { + a := P256FpNew().SetUint64(4) + e := P256FpNew().SetUint64(16) + require.Equal(t, e, a.Square(a)) + + for i := 0; i < 25; i++ { + j := rand.Uint32() + exp := uint64(j) * uint64(j) + e.SetUint64(exp) + a.SetUint64(uint64(j)) + require.Equal(t, e, a.Square(a)) + } +} + +func TestFpNeg(t *testing.T) { + g := P256FpNew().SetUint64(7) + a := P256FpNew().SetOne() + a.Neg(a) + e := P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xfffffffffffffffe, 0x00000001ffffffff, 0x0000000000000000, 0xfffffffe00000002}) + require.Equal(t, e, a) + a.Neg(g) + e = P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xfffffffffffffff8, 0x00000007ffffffff, 0x0000000000000000, 0xfffffff800000008}) + require.Equal(t, e, a) +} + +func TestFpExp(t *testing.T) { + e := P256FpNew().SetUint64(8) + a := P256FpNew().SetUint64(2) + by := P256FpNew().SetUint64(3) + require.Equal(t, e, a.Exp(a, by)) +} + +func TestFpSqrt(t *testing.T) { + t1 := P256FpNew().SetUint64(2) + t2 := P256FpNew().Neg(t1) + t3 := P256FpNew().Square(t1) + _, wasSquare := t3.Sqrt(t3) + + require.True(t, wasSquare) + require.Equal(t, 1, t1.Equal(t3)|t2.Equal(t3)) + t1.SetUint64(3) + _, wasSquare = P256FpNew().Sqrt(t1) + require.False(t, wasSquare) +} + +func TestFpInvert(t *testing.T) { + twoInv := P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8000000000000000}) + two := P256FpNew().SetUint64(2) + a, inverted := P256FpNew().Invert(two) + require.True(t, inverted) + require.Equal(t, a, twoInv) + + rootOfUnity := P256FpNew().SetLimbs(&[native.FieldLimbs]uint64{0x8619a9e760c01d0c, 0xa883c4fba37998df, 0x45607580b6eabd98, 0xf252b002544b2f99}) + rootOfUnityInv := P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0x2609d8ab477f96d1, 0x6e5f128fb20a0f24, 0xe4d636874d99643b, 0x376080cc1f2a3735}) + a, inverted = P256FpNew().Invert(rootOfUnity) + require.True(t, inverted) + require.Equal(t, a, rootOfUnityInv) + + lhs := P256FpNew().SetUint64(9) + rhs := P256FpNew().SetUint64(3) + rhsInv, inverted := P256FpNew().Invert(rhs) + require.True(t, inverted) + require.Equal(t, rhs, P256FpNew().Mul(lhs, rhsInv)) + + rhs.SetZero() + _, inverted = P256FpNew().Invert(rhs) + require.False(t, inverted) +} + +func TestFpCMove(t *testing.T) { + t1 := P256FpNew().SetUint64(5) + t2 := P256FpNew().SetUint64(10) + require.Equal(t, t1, P256FpNew().CMove(t1, t2, 0)) + require.Equal(t, t2, P256FpNew().CMove(t1, t2, 1)) +} + +func TestFpBytes(t *testing.T) { + t1 := P256FpNew().SetUint64(99) + seq := t1.Bytes() + t2, err := P256FpNew().SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + + for i := 0; i < 25; i++ { + t1.SetUint64(rand.Uint64()) + seq = t1.Bytes() + _, err = t2.SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + } +} + +func TestFpCmp(t *testing.T) { + tests := []struct { + a *native.Field + b *native.Field + e int + }{ + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{2731658267414164836, 14655288906067898431, 6537465423330262322, 8306191141697566219}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{6472764012681988529, 10848812988401906064, 2961825807536828898, 4282183981941645679}), + e: 1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{8023004109510539223, 4652004072850285717, 1877219145646046927, 383214385093921911}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{10099384440823804262, 16139476942229308465, 8636966320777393798, 5435928725024696785}), + e: -1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{3741840066202388211, 12165774400417314871, 16619312580230515379, 16195032234110087705}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{3905865991286066744, 543690822309071825, 17963103015950210055, 3745476720756119742}), + e: 1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{16660853697936147788, 7799793619412111108, 13515141085171033220, 2641079731236069032}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{17790588295388238399, 571847801379669440, 14537208974498222469, 12792570372087452754}), + e: -1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{3912839285384959186, 2701177075110484070, 6453856448115499033, 6475797457962597458}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{1282566391665688512, 13503640416992806563, 2962240104675990153, 3374904770947067689}), + e: 1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{5716631803409360103, 7859567470082614154, 12747956220853330146, 18434584096087315020}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{16317076441459028418, 12854146980376319601, 2258436689269031143, 9531877130792223752}), + e: 1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{17955191469941083403, 10350326247207200880, 17263512235150705075, 12700328451238078022}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{6767595547459644695, 7146403825494928147, 12269344038346710612, 9122477829383225603}), + e: 1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{17099388671847024438, 6426264987820696548, 10641143464957227405, 7709745403700754098}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{10799154372990268556, 17178492485719929374, 5705777922258988797, 8051037767683567782}), + e: -1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{4567139260680454325, 1629385880182139061, 16607020832317899145, 1261011562621553200}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{13487234491304534488, 17872642955936089265, 17651026784972590233, 9468934643333871559}), + e: -1, + }, + { + a: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{18071070103467571798, 11787850505799426140, 10631355976141928593, 4867785203635092610}), + b: P256FpNew().SetRaw(&[native.FieldLimbs]uint64{12596443599426461624, 10176122686151524591, 17075755296887483439, 6726169532695070719}), + e: -1, + }, + } + + for _, test := range tests { + require.Equal(t, test.e, test.a.Cmp(test.b)) + require.Equal(t, -test.e, test.b.Cmp(test.a)) + require.Equal(t, 0, test.a.Cmp(test.a)) + require.Equal(t, 0, test.b.Cmp(test.b)) + } +} + +func TestFpBigInt(t *testing.T) { + t1 := P256FpNew().SetBigInt(big.NewInt(9999)) + t2 := P256FpNew().SetBigInt(t1.BigInt()) + require.Equal(t, t1, t2) + + e := P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0x515151513f3f3f3e, 0xc9c9c9cb36363636, 0xb7b7b7b79c9c9c9c, 0xfffffffeaeaeaeaf}) + b := new(big.Int).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}) + t1.SetBigInt(b) + require.Equal(t, e, t1) + e.Value[0] = 0xaeaeaeaec0c0c0c1 + e.Value[1] = 0x36363635c9c9c9c9 + e.Value[2] = 0x4848484863636363 + e.Value[3] = 0x0000000051515151 + b.Neg(b) + t1.SetBigInt(b) + require.Equal(t, e, t1) +} + +func TestFpSetBytesWide(t *testing.T) { + e := P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xccdefd48c77805bc, 0xe935dc2db86364d6, 0xca8ee6e5870a020e, 0x4c94bf4467f3b5bf}) + + a := P256FpNew().SetBytesWide(&[64]byte{ + 0x69, 0x23, 0x5a, 0x0b, 0xce, 0x0c, 0xa8, 0x64, + 0x3c, 0x78, 0xbc, 0x01, 0x05, 0xef, 0xf2, 0x84, + 0xde, 0xbb, 0x6b, 0xc8, 0x63, 0x5e, 0x6e, 0x69, + 0x62, 0xcc, 0xc6, 0x2d, 0xf5, 0x72, 0x40, 0x92, + 0x28, 0x11, 0xd6, 0xc8, 0x07, 0xa5, 0x88, 0x82, + 0xfe, 0xe3, 0x97, 0xf6, 0x1e, 0xfb, 0x2e, 0x3b, + 0x27, 0x5f, 0x85, 0x06, 0x8d, 0x99, 0xa4, 0x75, + 0xc0, 0x2c, 0x71, 0x69, 0x9e, 0x58, 0xea, 0x52, + }) + require.Equal(t, e, a) +} + +func TestFpSetBytesWideBigInt(t *testing.T) { + params := getP256FpParams() + var tv2 [64]byte + for i := 0; i < 25; i++ { + _, _ = crand.Read(tv2[:]) + e := new(big.Int).SetBytes(tv2[:]) + e.Mod(e, params.BiModulus) + + tv := internal.ReverseScalarBytes(tv2[:]) + copy(tv2[:], tv) + a := P256FpNew().SetBytesWide(&tv2) + require.Equal(t, 0, e.Cmp(a.BigInt())) + } +} diff --git a/pkg/crypto/core/curves/native/p256/fp/p256_fp.go b/pkg/crypto/core/curves/native/p256/fp/p256_fp.go new file mode 100755 index 000000000..6931a0688 --- /dev/null +++ b/pkg/crypto/core/curves/native/p256/fp/p256_fp.go @@ -0,0 +1,1463 @@ +// Code generated by Fiat Cryptography. DO NOT EDIT. +// +// Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --lang Go --no-wide-int --relax-primitive-carry-to-bitwidth 32,64 --cmovznz-by-mul --internal-static --package-case flatcase --public-function-case UpperCamelCase --private-function-case camelCase --public-type-case UpperCamelCase --private-type-case camelCase --no-prefix-fiat --doc-newline-in-typedef-bounds --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' --doc-text-before-function-name ” --doc-text-before-type-name ” --package-name p256 ” 64 '2^256 - 2^224 + 2^192 + 2^96 - 1' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one +// +// curve description (via package name): p256 +// +// machine_wordsize = 64 (from "64") +// +// requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp +// +// m = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (from "2^256 - 2^224 + 2^192 + 2^96 - 1") +// +// NOTE: In addition to the bounds specified above each function, all +// +// functions synthesized for this Montgomery arithmetic require the +// +// input to be strictly less than the prime modulus (m), and also +// +// require the input to be in the unique saturated representation. +// +// All functions also ensure that these two properties are true of +// +// return values. +// +// Computed values: +// +// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) +// +// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) +// +// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in +// +// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 +package fp + +import "math/bits" + +type uint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 +type int1 int64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 + +// MontgomeryDomainFieldElement is a field element in the Montgomery domain. +// +// Bounds: +// +// [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type MontgomeryDomainFieldElement [4]uint64 + +// NonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain. +// +// Bounds: +// +// [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type NonMontgomeryDomainFieldElement [4]uint64 + +// cmovznzU64 is a single-word conditional move. +// +// Postconditions: +// +// out1 = (if arg1 = 0 then arg2 else arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [0x0 ~> 0xffffffffffffffff] +// arg3: [0x0 ~> 0xffffffffffffffff] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func cmovznzU64(out1 *uint64, arg1 uint1, arg2 uint64, arg3 uint64) { + x1 := (uint64(arg1) * 0xffffffffffffffff) + x2 := ((x1 & arg3) | ((^x1) & arg2)) + *out1 = x2 +} + +// Mul multiplies two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Mul(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg2[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg2[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg2[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg2[0]) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + x19 := (uint64(uint1(x18)) + x6) + var x20 uint64 + var x21 uint64 + x21, x20 = bits.Mul64(x11, 0xffffffff00000001) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x11, 0xffffffff) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x11, 0xffffffffffffffff) + var x26 uint64 + var x27 uint64 + x26, x27 = bits.Add64(x25, x22, uint64(0x0)) + x28 := (uint64(uint1(x27)) + x23) + var x30 uint64 + _, x30 = bits.Add64(x11, x24, uint64(0x0)) + var x31 uint64 + var x32 uint64 + x31, x32 = bits.Add64(x13, x26, uint64(uint1(x30))) + var x33 uint64 + var x34 uint64 + x33, x34 = bits.Add64(x15, x28, uint64(uint1(x32))) + var x35 uint64 + var x36 uint64 + x35, x36 = bits.Add64(x17, x20, uint64(uint1(x34))) + var x37 uint64 + var x38 uint64 + x37, x38 = bits.Add64(x19, x21, uint64(uint1(x36))) + var x39 uint64 + var x40 uint64 + x40, x39 = bits.Mul64(x1, arg2[3]) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, arg2[2]) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, arg2[1]) + var x45 uint64 + var x46 uint64 + x46, x45 = bits.Mul64(x1, arg2[0]) + var x47 uint64 + var x48 uint64 + x47, x48 = bits.Add64(x46, x43, uint64(0x0)) + var x49 uint64 + var x50 uint64 + x49, x50 = bits.Add64(x44, x41, uint64(uint1(x48))) + var x51 uint64 + var x52 uint64 + x51, x52 = bits.Add64(x42, x39, uint64(uint1(x50))) + x53 := (uint64(uint1(x52)) + x40) + var x54 uint64 + var x55 uint64 + x54, x55 = bits.Add64(x31, x45, uint64(0x0)) + var x56 uint64 + var x57 uint64 + x56, x57 = bits.Add64(x33, x47, uint64(uint1(x55))) + var x58 uint64 + var x59 uint64 + x58, x59 = bits.Add64(x35, x49, uint64(uint1(x57))) + var x60 uint64 + var x61 uint64 + x60, x61 = bits.Add64(x37, x51, uint64(uint1(x59))) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(uint64(uint1(x38)), x53, uint64(uint1(x61))) + var x64 uint64 + var x65 uint64 + x65, x64 = bits.Mul64(x54, 0xffffffff00000001) + var x66 uint64 + var x67 uint64 + x67, x66 = bits.Mul64(x54, 0xffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x54, 0xffffffffffffffff) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(x69, x66, uint64(0x0)) + x72 := (uint64(uint1(x71)) + x67) + var x74 uint64 + _, x74 = bits.Add64(x54, x68, uint64(0x0)) + var x75 uint64 + var x76 uint64 + x75, x76 = bits.Add64(x56, x70, uint64(uint1(x74))) + var x77 uint64 + var x78 uint64 + x77, x78 = bits.Add64(x58, x72, uint64(uint1(x76))) + var x79 uint64 + var x80 uint64 + x79, x80 = bits.Add64(x60, x64, uint64(uint1(x78))) + var x81 uint64 + var x82 uint64 + x81, x82 = bits.Add64(x62, x65, uint64(uint1(x80))) + x83 := (uint64(uint1(x82)) + uint64(uint1(x63))) + var x84 uint64 + var x85 uint64 + x85, x84 = bits.Mul64(x2, arg2[3]) + var x86 uint64 + var x87 uint64 + x87, x86 = bits.Mul64(x2, arg2[2]) + var x88 uint64 + var x89 uint64 + x89, x88 = bits.Mul64(x2, arg2[1]) + var x90 uint64 + var x91 uint64 + x91, x90 = bits.Mul64(x2, arg2[0]) + var x92 uint64 + var x93 uint64 + x92, x93 = bits.Add64(x91, x88, uint64(0x0)) + var x94 uint64 + var x95 uint64 + x94, x95 = bits.Add64(x89, x86, uint64(uint1(x93))) + var x96 uint64 + var x97 uint64 + x96, x97 = bits.Add64(x87, x84, uint64(uint1(x95))) + x98 := (uint64(uint1(x97)) + x85) + var x99 uint64 + var x100 uint64 + x99, x100 = bits.Add64(x75, x90, uint64(0x0)) + var x101 uint64 + var x102 uint64 + x101, x102 = bits.Add64(x77, x92, uint64(uint1(x100))) + var x103 uint64 + var x104 uint64 + x103, x104 = bits.Add64(x79, x94, uint64(uint1(x102))) + var x105 uint64 + var x106 uint64 + x105, x106 = bits.Add64(x81, x96, uint64(uint1(x104))) + var x107 uint64 + var x108 uint64 + x107, x108 = bits.Add64(x83, x98, uint64(uint1(x106))) + var x109 uint64 + var x110 uint64 + x110, x109 = bits.Mul64(x99, 0xffffffff00000001) + var x111 uint64 + var x112 uint64 + x112, x111 = bits.Mul64(x99, 0xffffffff) + var x113 uint64 + var x114 uint64 + x114, x113 = bits.Mul64(x99, 0xffffffffffffffff) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x114, x111, uint64(0x0)) + x117 := (uint64(uint1(x116)) + x112) + var x119 uint64 + _, x119 = bits.Add64(x99, x113, uint64(0x0)) + var x120 uint64 + var x121 uint64 + x120, x121 = bits.Add64(x101, x115, uint64(uint1(x119))) + var x122 uint64 + var x123 uint64 + x122, x123 = bits.Add64(x103, x117, uint64(uint1(x121))) + var x124 uint64 + var x125 uint64 + x124, x125 = bits.Add64(x105, x109, uint64(uint1(x123))) + var x126 uint64 + var x127 uint64 + x126, x127 = bits.Add64(x107, x110, uint64(uint1(x125))) + x128 := (uint64(uint1(x127)) + uint64(uint1(x108))) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x3, arg2[3]) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x3, arg2[2]) + var x133 uint64 + var x134 uint64 + x134, x133 = bits.Mul64(x3, arg2[1]) + var x135 uint64 + var x136 uint64 + x136, x135 = bits.Mul64(x3, arg2[0]) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x136, x133, uint64(0x0)) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(x134, x131, uint64(uint1(x138))) + var x141 uint64 + var x142 uint64 + x141, x142 = bits.Add64(x132, x129, uint64(uint1(x140))) + x143 := (uint64(uint1(x142)) + x130) + var x144 uint64 + var x145 uint64 + x144, x145 = bits.Add64(x120, x135, uint64(0x0)) + var x146 uint64 + var x147 uint64 + x146, x147 = bits.Add64(x122, x137, uint64(uint1(x145))) + var x148 uint64 + var x149 uint64 + x148, x149 = bits.Add64(x124, x139, uint64(uint1(x147))) + var x150 uint64 + var x151 uint64 + x150, x151 = bits.Add64(x126, x141, uint64(uint1(x149))) + var x152 uint64 + var x153 uint64 + x152, x153 = bits.Add64(x128, x143, uint64(uint1(x151))) + var x154 uint64 + var x155 uint64 + x155, x154 = bits.Mul64(x144, 0xffffffff00000001) + var x156 uint64 + var x157 uint64 + x157, x156 = bits.Mul64(x144, 0xffffffff) + var x158 uint64 + var x159 uint64 + x159, x158 = bits.Mul64(x144, 0xffffffffffffffff) + var x160 uint64 + var x161 uint64 + x160, x161 = bits.Add64(x159, x156, uint64(0x0)) + x162 := (uint64(uint1(x161)) + x157) + var x164 uint64 + _, x164 = bits.Add64(x144, x158, uint64(0x0)) + var x165 uint64 + var x166 uint64 + x165, x166 = bits.Add64(x146, x160, uint64(uint1(x164))) + var x167 uint64 + var x168 uint64 + x167, x168 = bits.Add64(x148, x162, uint64(uint1(x166))) + var x169 uint64 + var x170 uint64 + x169, x170 = bits.Add64(x150, x154, uint64(uint1(x168))) + var x171 uint64 + var x172 uint64 + x171, x172 = bits.Add64(x152, x155, uint64(uint1(x170))) + x173 := (uint64(uint1(x172)) + uint64(uint1(x153))) + var x174 uint64 + var x175 uint64 + x174, x175 = bits.Sub64(x165, 0xffffffffffffffff, uint64(0x0)) + var x176 uint64 + var x177 uint64 + x176, x177 = bits.Sub64(x167, 0xffffffff, uint64(uint1(x175))) + var x178 uint64 + var x179 uint64 + x178, x179 = bits.Sub64(x169, uint64(0x0), uint64(uint1(x177))) + var x180 uint64 + var x181 uint64 + x180, x181 = bits.Sub64(x171, 0xffffffff00000001, uint64(uint1(x179))) + var x183 uint64 + _, x183 = bits.Sub64(x173, uint64(0x0), uint64(uint1(x181))) + var x184 uint64 + cmovznzU64(&x184, uint1(x183), x174, x165) + var x185 uint64 + cmovznzU64(&x185, uint1(x183), x176, x167) + var x186 uint64 + cmovznzU64(&x186, uint1(x183), x178, x169) + var x187 uint64 + cmovznzU64(&x187, uint1(x183), x180, x171) + out1[0] = x184 + out1[1] = x185 + out1[2] = x186 + out1[3] = x187 +} + +// Square squares a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m +// 0 ≤ eval out1 < m +func Square(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg1[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg1[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg1[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg1[0]) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + x19 := (uint64(uint1(x18)) + x6) + var x20 uint64 + var x21 uint64 + x21, x20 = bits.Mul64(x11, 0xffffffff00000001) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x11, 0xffffffff) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x11, 0xffffffffffffffff) + var x26 uint64 + var x27 uint64 + x26, x27 = bits.Add64(x25, x22, uint64(0x0)) + x28 := (uint64(uint1(x27)) + x23) + var x30 uint64 + _, x30 = bits.Add64(x11, x24, uint64(0x0)) + var x31 uint64 + var x32 uint64 + x31, x32 = bits.Add64(x13, x26, uint64(uint1(x30))) + var x33 uint64 + var x34 uint64 + x33, x34 = bits.Add64(x15, x28, uint64(uint1(x32))) + var x35 uint64 + var x36 uint64 + x35, x36 = bits.Add64(x17, x20, uint64(uint1(x34))) + var x37 uint64 + var x38 uint64 + x37, x38 = bits.Add64(x19, x21, uint64(uint1(x36))) + var x39 uint64 + var x40 uint64 + x40, x39 = bits.Mul64(x1, arg1[3]) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, arg1[2]) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, arg1[1]) + var x45 uint64 + var x46 uint64 + x46, x45 = bits.Mul64(x1, arg1[0]) + var x47 uint64 + var x48 uint64 + x47, x48 = bits.Add64(x46, x43, uint64(0x0)) + var x49 uint64 + var x50 uint64 + x49, x50 = bits.Add64(x44, x41, uint64(uint1(x48))) + var x51 uint64 + var x52 uint64 + x51, x52 = bits.Add64(x42, x39, uint64(uint1(x50))) + x53 := (uint64(uint1(x52)) + x40) + var x54 uint64 + var x55 uint64 + x54, x55 = bits.Add64(x31, x45, uint64(0x0)) + var x56 uint64 + var x57 uint64 + x56, x57 = bits.Add64(x33, x47, uint64(uint1(x55))) + var x58 uint64 + var x59 uint64 + x58, x59 = bits.Add64(x35, x49, uint64(uint1(x57))) + var x60 uint64 + var x61 uint64 + x60, x61 = bits.Add64(x37, x51, uint64(uint1(x59))) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(uint64(uint1(x38)), x53, uint64(uint1(x61))) + var x64 uint64 + var x65 uint64 + x65, x64 = bits.Mul64(x54, 0xffffffff00000001) + var x66 uint64 + var x67 uint64 + x67, x66 = bits.Mul64(x54, 0xffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x54, 0xffffffffffffffff) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(x69, x66, uint64(0x0)) + x72 := (uint64(uint1(x71)) + x67) + var x74 uint64 + _, x74 = bits.Add64(x54, x68, uint64(0x0)) + var x75 uint64 + var x76 uint64 + x75, x76 = bits.Add64(x56, x70, uint64(uint1(x74))) + var x77 uint64 + var x78 uint64 + x77, x78 = bits.Add64(x58, x72, uint64(uint1(x76))) + var x79 uint64 + var x80 uint64 + x79, x80 = bits.Add64(x60, x64, uint64(uint1(x78))) + var x81 uint64 + var x82 uint64 + x81, x82 = bits.Add64(x62, x65, uint64(uint1(x80))) + x83 := (uint64(uint1(x82)) + uint64(uint1(x63))) + var x84 uint64 + var x85 uint64 + x85, x84 = bits.Mul64(x2, arg1[3]) + var x86 uint64 + var x87 uint64 + x87, x86 = bits.Mul64(x2, arg1[2]) + var x88 uint64 + var x89 uint64 + x89, x88 = bits.Mul64(x2, arg1[1]) + var x90 uint64 + var x91 uint64 + x91, x90 = bits.Mul64(x2, arg1[0]) + var x92 uint64 + var x93 uint64 + x92, x93 = bits.Add64(x91, x88, uint64(0x0)) + var x94 uint64 + var x95 uint64 + x94, x95 = bits.Add64(x89, x86, uint64(uint1(x93))) + var x96 uint64 + var x97 uint64 + x96, x97 = bits.Add64(x87, x84, uint64(uint1(x95))) + x98 := (uint64(uint1(x97)) + x85) + var x99 uint64 + var x100 uint64 + x99, x100 = bits.Add64(x75, x90, uint64(0x0)) + var x101 uint64 + var x102 uint64 + x101, x102 = bits.Add64(x77, x92, uint64(uint1(x100))) + var x103 uint64 + var x104 uint64 + x103, x104 = bits.Add64(x79, x94, uint64(uint1(x102))) + var x105 uint64 + var x106 uint64 + x105, x106 = bits.Add64(x81, x96, uint64(uint1(x104))) + var x107 uint64 + var x108 uint64 + x107, x108 = bits.Add64(x83, x98, uint64(uint1(x106))) + var x109 uint64 + var x110 uint64 + x110, x109 = bits.Mul64(x99, 0xffffffff00000001) + var x111 uint64 + var x112 uint64 + x112, x111 = bits.Mul64(x99, 0xffffffff) + var x113 uint64 + var x114 uint64 + x114, x113 = bits.Mul64(x99, 0xffffffffffffffff) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x114, x111, uint64(0x0)) + x117 := (uint64(uint1(x116)) + x112) + var x119 uint64 + _, x119 = bits.Add64(x99, x113, uint64(0x0)) + var x120 uint64 + var x121 uint64 + x120, x121 = bits.Add64(x101, x115, uint64(uint1(x119))) + var x122 uint64 + var x123 uint64 + x122, x123 = bits.Add64(x103, x117, uint64(uint1(x121))) + var x124 uint64 + var x125 uint64 + x124, x125 = bits.Add64(x105, x109, uint64(uint1(x123))) + var x126 uint64 + var x127 uint64 + x126, x127 = bits.Add64(x107, x110, uint64(uint1(x125))) + x128 := (uint64(uint1(x127)) + uint64(uint1(x108))) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x3, arg1[3]) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x3, arg1[2]) + var x133 uint64 + var x134 uint64 + x134, x133 = bits.Mul64(x3, arg1[1]) + var x135 uint64 + var x136 uint64 + x136, x135 = bits.Mul64(x3, arg1[0]) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x136, x133, uint64(0x0)) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(x134, x131, uint64(uint1(x138))) + var x141 uint64 + var x142 uint64 + x141, x142 = bits.Add64(x132, x129, uint64(uint1(x140))) + x143 := (uint64(uint1(x142)) + x130) + var x144 uint64 + var x145 uint64 + x144, x145 = bits.Add64(x120, x135, uint64(0x0)) + var x146 uint64 + var x147 uint64 + x146, x147 = bits.Add64(x122, x137, uint64(uint1(x145))) + var x148 uint64 + var x149 uint64 + x148, x149 = bits.Add64(x124, x139, uint64(uint1(x147))) + var x150 uint64 + var x151 uint64 + x150, x151 = bits.Add64(x126, x141, uint64(uint1(x149))) + var x152 uint64 + var x153 uint64 + x152, x153 = bits.Add64(x128, x143, uint64(uint1(x151))) + var x154 uint64 + var x155 uint64 + x155, x154 = bits.Mul64(x144, 0xffffffff00000001) + var x156 uint64 + var x157 uint64 + x157, x156 = bits.Mul64(x144, 0xffffffff) + var x158 uint64 + var x159 uint64 + x159, x158 = bits.Mul64(x144, 0xffffffffffffffff) + var x160 uint64 + var x161 uint64 + x160, x161 = bits.Add64(x159, x156, uint64(0x0)) + x162 := (uint64(uint1(x161)) + x157) + var x164 uint64 + _, x164 = bits.Add64(x144, x158, uint64(0x0)) + var x165 uint64 + var x166 uint64 + x165, x166 = bits.Add64(x146, x160, uint64(uint1(x164))) + var x167 uint64 + var x168 uint64 + x167, x168 = bits.Add64(x148, x162, uint64(uint1(x166))) + var x169 uint64 + var x170 uint64 + x169, x170 = bits.Add64(x150, x154, uint64(uint1(x168))) + var x171 uint64 + var x172 uint64 + x171, x172 = bits.Add64(x152, x155, uint64(uint1(x170))) + x173 := (uint64(uint1(x172)) + uint64(uint1(x153))) + var x174 uint64 + var x175 uint64 + x174, x175 = bits.Sub64(x165, 0xffffffffffffffff, uint64(0x0)) + var x176 uint64 + var x177 uint64 + x176, x177 = bits.Sub64(x167, 0xffffffff, uint64(uint1(x175))) + var x178 uint64 + var x179 uint64 + x178, x179 = bits.Sub64(x169, uint64(0x0), uint64(uint1(x177))) + var x180 uint64 + var x181 uint64 + x180, x181 = bits.Sub64(x171, 0xffffffff00000001, uint64(uint1(x179))) + var x183 uint64 + _, x183 = bits.Sub64(x173, uint64(0x0), uint64(uint1(x181))) + var x184 uint64 + cmovznzU64(&x184, uint1(x183), x174, x165) + var x185 uint64 + cmovznzU64(&x185, uint1(x183), x176, x167) + var x186 uint64 + cmovznzU64(&x186, uint1(x183), x178, x169) + var x187 uint64 + cmovznzU64(&x187, uint1(x183), x180, x171) + out1[0] = x184 + out1[1] = x185 + out1[2] = x186 + out1[3] = x187 +} + +// Add adds two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Add(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Add64(arg1[0], arg2[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Add64(arg1[1], arg2[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Add64(arg1[2], arg2[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Add64(arg1[3], arg2[3], uint64(uint1(x6))) + var x9 uint64 + var x10 uint64 + x9, x10 = bits.Sub64(x1, 0xffffffffffffffff, uint64(0x0)) + var x11 uint64 + var x12 uint64 + x11, x12 = bits.Sub64(x3, 0xffffffff, uint64(uint1(x10))) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Sub64(x5, uint64(0x0), uint64(uint1(x12))) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Sub64(x7, 0xffffffff00000001, uint64(uint1(x14))) + var x18 uint64 + _, x18 = bits.Sub64(uint64(uint1(x8)), uint64(0x0), uint64(uint1(x16))) + var x19 uint64 + cmovznzU64(&x19, uint1(x18), x9, x1) + var x20 uint64 + cmovznzU64(&x20, uint1(x18), x11, x3) + var x21 uint64 + cmovznzU64(&x21, uint1(x18), x13, x5) + var x22 uint64 + cmovznzU64(&x22, uint1(x18), x15, x7) + out1[0] = x19 + out1[1] = x20 + out1[2] = x21 + out1[3] = x22 +} + +// Sub subtracts two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Sub(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Sub64(arg1[0], arg2[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Sub64(arg1[1], arg2[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Sub64(arg1[2], arg2[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Sub64(arg1[3], arg2[3], uint64(uint1(x6))) + var x9 uint64 + cmovznzU64(&x9, uint1(x8), uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x10, x11 = bits.Add64(x1, x9, uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x3, (x9 & 0xffffffff), uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x5, uint64(0x0), uint64(uint1(x13))) + var x16 uint64 + x16, _ = bits.Add64(x7, (x9 & 0xffffffff00000001), uint64(uint1(x15))) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// Opp negates a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m +// 0 ≤ eval out1 < m +func Opp(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Sub64(uint64(0x0), arg1[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Sub64(uint64(0x0), arg1[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Sub64(uint64(0x0), arg1[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Sub64(uint64(0x0), arg1[3], uint64(uint1(x6))) + var x9 uint64 + cmovznzU64(&x9, uint1(x8), uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x10, x11 = bits.Add64(x1, x9, uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x3, (x9 & 0xffffffff), uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x5, uint64(0x0), uint64(uint1(x13))) + var x16 uint64 + x16, _ = bits.Add64(x7, (x9 & 0xffffffff00000001), uint64(uint1(x15))) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// FromMontgomery translates a field element out of the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m +// 0 ≤ eval out1 < m +func FromMontgomery(out1 *NonMontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + x1 := arg1[0] + var x2 uint64 + var x3 uint64 + x3, x2 = bits.Mul64(x1, 0xffffffff00000001) + var x4 uint64 + var x5 uint64 + x5, x4 = bits.Mul64(x1, 0xffffffff) + var x6 uint64 + var x7 uint64 + x7, x6 = bits.Mul64(x1, 0xffffffffffffffff) + var x8 uint64 + var x9 uint64 + x8, x9 = bits.Add64(x7, x4, uint64(0x0)) + var x11 uint64 + _, x11 = bits.Add64(x1, x6, uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(uint64(0x0), x8, uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x12, arg1[1], uint64(0x0)) + var x16 uint64 + var x17 uint64 + x17, x16 = bits.Mul64(x14, 0xffffffff00000001) + var x18 uint64 + var x19 uint64 + x19, x18 = bits.Mul64(x14, 0xffffffff) + var x20 uint64 + var x21 uint64 + x21, x20 = bits.Mul64(x14, 0xffffffffffffffff) + var x22 uint64 + var x23 uint64 + x22, x23 = bits.Add64(x21, x18, uint64(0x0)) + var x25 uint64 + _, x25 = bits.Add64(x14, x20, uint64(0x0)) + var x26 uint64 + var x27 uint64 + x26, x27 = bits.Add64((uint64(uint1(x15)) + (uint64(uint1(x13)) + (uint64(uint1(x9)) + x5))), x22, uint64(uint1(x25))) + var x28 uint64 + var x29 uint64 + x28, x29 = bits.Add64(x2, (uint64(uint1(x23)) + x19), uint64(uint1(x27))) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x3, x16, uint64(uint1(x29))) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x26, arg1[2], uint64(0x0)) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x28, uint64(0x0), uint64(uint1(x33))) + var x36 uint64 + var x37 uint64 + x36, x37 = bits.Add64(x30, uint64(0x0), uint64(uint1(x35))) + var x38 uint64 + var x39 uint64 + x39, x38 = bits.Mul64(x32, 0xffffffff00000001) + var x40 uint64 + var x41 uint64 + x41, x40 = bits.Mul64(x32, 0xffffffff) + var x42 uint64 + var x43 uint64 + x43, x42 = bits.Mul64(x32, 0xffffffffffffffff) + var x44 uint64 + var x45 uint64 + x44, x45 = bits.Add64(x43, x40, uint64(0x0)) + var x47 uint64 + _, x47 = bits.Add64(x32, x42, uint64(0x0)) + var x48 uint64 + var x49 uint64 + x48, x49 = bits.Add64(x34, x44, uint64(uint1(x47))) + var x50 uint64 + var x51 uint64 + x50, x51 = bits.Add64(x36, (uint64(uint1(x45)) + x41), uint64(uint1(x49))) + var x52 uint64 + var x53 uint64 + x52, x53 = bits.Add64((uint64(uint1(x37)) + (uint64(uint1(x31)) + x17)), x38, uint64(uint1(x51))) + var x54 uint64 + var x55 uint64 + x54, x55 = bits.Add64(x48, arg1[3], uint64(0x0)) + var x56 uint64 + var x57 uint64 + x56, x57 = bits.Add64(x50, uint64(0x0), uint64(uint1(x55))) + var x58 uint64 + var x59 uint64 + x58, x59 = bits.Add64(x52, uint64(0x0), uint64(uint1(x57))) + var x60 uint64 + var x61 uint64 + x61, x60 = bits.Mul64(x54, 0xffffffff00000001) + var x62 uint64 + var x63 uint64 + x63, x62 = bits.Mul64(x54, 0xffffffff) + var x64 uint64 + var x65 uint64 + x65, x64 = bits.Mul64(x54, 0xffffffffffffffff) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x65, x62, uint64(0x0)) + var x69 uint64 + _, x69 = bits.Add64(x54, x64, uint64(0x0)) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(x56, x66, uint64(uint1(x69))) + var x72 uint64 + var x73 uint64 + x72, x73 = bits.Add64(x58, (uint64(uint1(x67)) + x63), uint64(uint1(x71))) + var x74 uint64 + var x75 uint64 + x74, x75 = bits.Add64((uint64(uint1(x59)) + (uint64(uint1(x53)) + x39)), x60, uint64(uint1(x73))) + x76 := (uint64(uint1(x75)) + x61) + var x77 uint64 + var x78 uint64 + x77, x78 = bits.Sub64(x70, 0xffffffffffffffff, uint64(0x0)) + var x79 uint64 + var x80 uint64 + x79, x80 = bits.Sub64(x72, 0xffffffff, uint64(uint1(x78))) + var x81 uint64 + var x82 uint64 + x81, x82 = bits.Sub64(x74, uint64(0x0), uint64(uint1(x80))) + var x83 uint64 + var x84 uint64 + x83, x84 = bits.Sub64(x76, 0xffffffff00000001, uint64(uint1(x82))) + var x86 uint64 + _, x86 = bits.Sub64(uint64(0x0), uint64(0x0), uint64(uint1(x84))) + var x87 uint64 + cmovznzU64(&x87, uint1(x86), x77, x70) + var x88 uint64 + cmovznzU64(&x88, uint1(x86), x79, x72) + var x89 uint64 + cmovznzU64(&x89, uint1(x86), x81, x74) + var x90 uint64 + cmovznzU64(&x90, uint1(x86), x83, x76) + out1[0] = x87 + out1[1] = x88 + out1[2] = x89 + out1[3] = x90 +} + +// ToMontgomery translates a field element into the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = eval arg1 mod m +// 0 ≤ eval out1 < m +func ToMontgomery(out1 *MontgomeryDomainFieldElement, arg1 *NonMontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, 0x4fffffffd) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, 0xfffffffffffffffe) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, 0xfffffffbffffffff) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, 0x3) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + var x19 uint64 + var x20 uint64 + x20, x19 = bits.Mul64(x11, 0xffffffff00000001) + var x21 uint64 + var x22 uint64 + x22, x21 = bits.Mul64(x11, 0xffffffff) + var x23 uint64 + var x24 uint64 + x24, x23 = bits.Mul64(x11, 0xffffffffffffffff) + var x25 uint64 + var x26 uint64 + x25, x26 = bits.Add64(x24, x21, uint64(0x0)) + var x28 uint64 + _, x28 = bits.Add64(x11, x23, uint64(0x0)) + var x29 uint64 + var x30 uint64 + x29, x30 = bits.Add64(x13, x25, uint64(uint1(x28))) + var x31 uint64 + var x32 uint64 + x31, x32 = bits.Add64(x15, (uint64(uint1(x26)) + x22), uint64(uint1(x30))) + var x33 uint64 + var x34 uint64 + x33, x34 = bits.Add64(x17, x19, uint64(uint1(x32))) + var x35 uint64 + var x36 uint64 + x35, x36 = bits.Add64((uint64(uint1(x18)) + x6), x20, uint64(uint1(x34))) + var x37 uint64 + var x38 uint64 + x38, x37 = bits.Mul64(x1, 0x4fffffffd) + var x39 uint64 + var x40 uint64 + x40, x39 = bits.Mul64(x1, 0xfffffffffffffffe) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, 0xfffffffbffffffff) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, 0x3) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Add64(x44, x41, uint64(0x0)) + var x47 uint64 + var x48 uint64 + x47, x48 = bits.Add64(x42, x39, uint64(uint1(x46))) + var x49 uint64 + var x50 uint64 + x49, x50 = bits.Add64(x40, x37, uint64(uint1(x48))) + var x51 uint64 + var x52 uint64 + x51, x52 = bits.Add64(x29, x43, uint64(0x0)) + var x53 uint64 + var x54 uint64 + x53, x54 = bits.Add64(x31, x45, uint64(uint1(x52))) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x33, x47, uint64(uint1(x54))) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x35, x49, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x60, x59 = bits.Mul64(x51, 0xffffffff00000001) + var x61 uint64 + var x62 uint64 + x62, x61 = bits.Mul64(x51, 0xffffffff) + var x63 uint64 + var x64 uint64 + x64, x63 = bits.Mul64(x51, 0xffffffffffffffff) + var x65 uint64 + var x66 uint64 + x65, x66 = bits.Add64(x64, x61, uint64(0x0)) + var x68 uint64 + _, x68 = bits.Add64(x51, x63, uint64(0x0)) + var x69 uint64 + var x70 uint64 + x69, x70 = bits.Add64(x53, x65, uint64(uint1(x68))) + var x71 uint64 + var x72 uint64 + x71, x72 = bits.Add64(x55, (uint64(uint1(x66)) + x62), uint64(uint1(x70))) + var x73 uint64 + var x74 uint64 + x73, x74 = bits.Add64(x57, x59, uint64(uint1(x72))) + var x75 uint64 + var x76 uint64 + x75, x76 = bits.Add64(((uint64(uint1(x58)) + uint64(uint1(x36))) + (uint64(uint1(x50)) + x38)), x60, uint64(uint1(x74))) + var x77 uint64 + var x78 uint64 + x78, x77 = bits.Mul64(x2, 0x4fffffffd) + var x79 uint64 + var x80 uint64 + x80, x79 = bits.Mul64(x2, 0xfffffffffffffffe) + var x81 uint64 + var x82 uint64 + x82, x81 = bits.Mul64(x2, 0xfffffffbffffffff) + var x83 uint64 + var x84 uint64 + x84, x83 = bits.Mul64(x2, 0x3) + var x85 uint64 + var x86 uint64 + x85, x86 = bits.Add64(x84, x81, uint64(0x0)) + var x87 uint64 + var x88 uint64 + x87, x88 = bits.Add64(x82, x79, uint64(uint1(x86))) + var x89 uint64 + var x90 uint64 + x89, x90 = bits.Add64(x80, x77, uint64(uint1(x88))) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(x69, x83, uint64(0x0)) + var x93 uint64 + var x94 uint64 + x93, x94 = bits.Add64(x71, x85, uint64(uint1(x92))) + var x95 uint64 + var x96 uint64 + x95, x96 = bits.Add64(x73, x87, uint64(uint1(x94))) + var x97 uint64 + var x98 uint64 + x97, x98 = bits.Add64(x75, x89, uint64(uint1(x96))) + var x99 uint64 + var x100 uint64 + x100, x99 = bits.Mul64(x91, 0xffffffff00000001) + var x101 uint64 + var x102 uint64 + x102, x101 = bits.Mul64(x91, 0xffffffff) + var x103 uint64 + var x104 uint64 + x104, x103 = bits.Mul64(x91, 0xffffffffffffffff) + var x105 uint64 + var x106 uint64 + x105, x106 = bits.Add64(x104, x101, uint64(0x0)) + var x108 uint64 + _, x108 = bits.Add64(x91, x103, uint64(0x0)) + var x109 uint64 + var x110 uint64 + x109, x110 = bits.Add64(x93, x105, uint64(uint1(x108))) + var x111 uint64 + var x112 uint64 + x111, x112 = bits.Add64(x95, (uint64(uint1(x106)) + x102), uint64(uint1(x110))) + var x113 uint64 + var x114 uint64 + x113, x114 = bits.Add64(x97, x99, uint64(uint1(x112))) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(((uint64(uint1(x98)) + uint64(uint1(x76))) + (uint64(uint1(x90)) + x78)), x100, uint64(uint1(x114))) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x3, 0x4fffffffd) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x3, 0xfffffffffffffffe) + var x121 uint64 + var x122 uint64 + x122, x121 = bits.Mul64(x3, 0xfffffffbffffffff) + var x123 uint64 + var x124 uint64 + x124, x123 = bits.Mul64(x3, 0x3) + var x125 uint64 + var x126 uint64 + x125, x126 = bits.Add64(x124, x121, uint64(0x0)) + var x127 uint64 + var x128 uint64 + x127, x128 = bits.Add64(x122, x119, uint64(uint1(x126))) + var x129 uint64 + var x130 uint64 + x129, x130 = bits.Add64(x120, x117, uint64(uint1(x128))) + var x131 uint64 + var x132 uint64 + x131, x132 = bits.Add64(x109, x123, uint64(0x0)) + var x133 uint64 + var x134 uint64 + x133, x134 = bits.Add64(x111, x125, uint64(uint1(x132))) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x113, x127, uint64(uint1(x134))) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x115, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x140, x139 = bits.Mul64(x131, 0xffffffff00000001) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x131, 0xffffffff) + var x143 uint64 + var x144 uint64 + x144, x143 = bits.Mul64(x131, 0xffffffffffffffff) + var x145 uint64 + var x146 uint64 + x145, x146 = bits.Add64(x144, x141, uint64(0x0)) + var x148 uint64 + _, x148 = bits.Add64(x131, x143, uint64(0x0)) + var x149 uint64 + var x150 uint64 + x149, x150 = bits.Add64(x133, x145, uint64(uint1(x148))) + var x151 uint64 + var x152 uint64 + x151, x152 = bits.Add64(x135, (uint64(uint1(x146)) + x142), uint64(uint1(x150))) + var x153 uint64 + var x154 uint64 + x153, x154 = bits.Add64(x137, x139, uint64(uint1(x152))) + var x155 uint64 + var x156 uint64 + x155, x156 = bits.Add64(((uint64(uint1(x138)) + uint64(uint1(x116))) + (uint64(uint1(x130)) + x118)), x140, uint64(uint1(x154))) + var x157 uint64 + var x158 uint64 + x157, x158 = bits.Sub64(x149, 0xffffffffffffffff, uint64(0x0)) + var x159 uint64 + var x160 uint64 + x159, x160 = bits.Sub64(x151, 0xffffffff, uint64(uint1(x158))) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Sub64(x153, uint64(0x0), uint64(uint1(x160))) + var x163 uint64 + var x164 uint64 + x163, x164 = bits.Sub64(x155, 0xffffffff00000001, uint64(uint1(x162))) + var x166 uint64 + _, x166 = bits.Sub64(uint64(uint1(x156)), uint64(0x0), uint64(uint1(x164))) + var x167 uint64 + cmovznzU64(&x167, uint1(x166), x157, x149) + var x168 uint64 + cmovznzU64(&x168, uint1(x166), x159, x151) + var x169 uint64 + cmovznzU64(&x169, uint1(x166), x161, x153) + var x170 uint64 + cmovznzU64(&x170, uint1(x166), x163, x155) + out1[0] = x167 + out1[1] = x168 + out1[2] = x169 + out1[3] = x170 +} + +// Nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0 +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func Nonzero(out1 *uint64, arg1 *[4]uint64) { + x1 := (arg1[0] | (arg1[1] | (arg1[2] | arg1[3]))) + *out1 = x1 +} + +// Selectznz is a multi-limb conditional select. +// +// Postconditions: +// +// eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func Selectznz(out1 *[4]uint64, arg1 uint1, arg2 *[4]uint64, arg3 *[4]uint64) { + var x1 uint64 + cmovznzU64(&x1, arg1, arg2[0], arg3[0]) + var x2 uint64 + cmovznzU64(&x2, arg1, arg2[1], arg3[1]) + var x3 uint64 + cmovznzU64(&x3, arg1, arg2[2], arg3[2]) + var x4 uint64 + cmovznzU64(&x4, arg1, arg2[3], arg3[3]) + out1[0] = x1 + out1[1] = x2 + out1[2] = x3 + out1[3] = x4 +} + +// ToBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] +func ToBytes(out1 *[32]uint8, arg1 *[4]uint64) { + x1 := arg1[3] + x2 := arg1[2] + x3 := arg1[1] + x4 := arg1[0] + x5 := (uint8(x4) & 0xff) + x6 := (x4 >> 8) + x7 := (uint8(x6) & 0xff) + x8 := (x6 >> 8) + x9 := (uint8(x8) & 0xff) + x10 := (x8 >> 8) + x11 := (uint8(x10) & 0xff) + x12 := (x10 >> 8) + x13 := (uint8(x12) & 0xff) + x14 := (x12 >> 8) + x15 := (uint8(x14) & 0xff) + x16 := (x14 >> 8) + x17 := (uint8(x16) & 0xff) + x18 := uint8((x16 >> 8)) + x19 := (uint8(x3) & 0xff) + x20 := (x3 >> 8) + x21 := (uint8(x20) & 0xff) + x22 := (x20 >> 8) + x23 := (uint8(x22) & 0xff) + x24 := (x22 >> 8) + x25 := (uint8(x24) & 0xff) + x26 := (x24 >> 8) + x27 := (uint8(x26) & 0xff) + x28 := (x26 >> 8) + x29 := (uint8(x28) & 0xff) + x30 := (x28 >> 8) + x31 := (uint8(x30) & 0xff) + x32 := uint8((x30 >> 8)) + x33 := (uint8(x2) & 0xff) + x34 := (x2 >> 8) + x35 := (uint8(x34) & 0xff) + x36 := (x34 >> 8) + x37 := (uint8(x36) & 0xff) + x38 := (x36 >> 8) + x39 := (uint8(x38) & 0xff) + x40 := (x38 >> 8) + x41 := (uint8(x40) & 0xff) + x42 := (x40 >> 8) + x43 := (uint8(x42) & 0xff) + x44 := (x42 >> 8) + x45 := (uint8(x44) & 0xff) + x46 := uint8((x44 >> 8)) + x47 := (uint8(x1) & 0xff) + x48 := (x1 >> 8) + x49 := (uint8(x48) & 0xff) + x50 := (x48 >> 8) + x51 := (uint8(x50) & 0xff) + x52 := (x50 >> 8) + x53 := (uint8(x52) & 0xff) + x54 := (x52 >> 8) + x55 := (uint8(x54) & 0xff) + x56 := (x54 >> 8) + x57 := (uint8(x56) & 0xff) + x58 := (x56 >> 8) + x59 := (uint8(x58) & 0xff) + x60 := uint8((x58 >> 8)) + out1[0] = x5 + out1[1] = x7 + out1[2] = x9 + out1[3] = x11 + out1[4] = x13 + out1[5] = x15 + out1[6] = x17 + out1[7] = x18 + out1[8] = x19 + out1[9] = x21 + out1[10] = x23 + out1[11] = x25 + out1[12] = x27 + out1[13] = x29 + out1[14] = x31 + out1[15] = x32 + out1[16] = x33 + out1[17] = x35 + out1[18] = x37 + out1[19] = x39 + out1[20] = x41 + out1[21] = x43 + out1[22] = x45 + out1[23] = x46 + out1[24] = x47 + out1[25] = x49 + out1[26] = x51 + out1[27] = x53 + out1[28] = x55 + out1[29] = x57 + out1[30] = x59 + out1[31] = x60 +} + +// FromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ bytes_eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = bytes_eval arg1 mod m +// 0 ≤ eval out1 < m +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func FromBytes(out1 *[4]uint64, arg1 *[32]uint8) { + x1 := (uint64(arg1[31]) << 56) + x2 := (uint64(arg1[30]) << 48) + x3 := (uint64(arg1[29]) << 40) + x4 := (uint64(arg1[28]) << 32) + x5 := (uint64(arg1[27]) << 24) + x6 := (uint64(arg1[26]) << 16) + x7 := (uint64(arg1[25]) << 8) + x8 := arg1[24] + x9 := (uint64(arg1[23]) << 56) + x10 := (uint64(arg1[22]) << 48) + x11 := (uint64(arg1[21]) << 40) + x12 := (uint64(arg1[20]) << 32) + x13 := (uint64(arg1[19]) << 24) + x14 := (uint64(arg1[18]) << 16) + x15 := (uint64(arg1[17]) << 8) + x16 := arg1[16] + x17 := (uint64(arg1[15]) << 56) + x18 := (uint64(arg1[14]) << 48) + x19 := (uint64(arg1[13]) << 40) + x20 := (uint64(arg1[12]) << 32) + x21 := (uint64(arg1[11]) << 24) + x22 := (uint64(arg1[10]) << 16) + x23 := (uint64(arg1[9]) << 8) + x24 := arg1[8] + x25 := (uint64(arg1[7]) << 56) + x26 := (uint64(arg1[6]) << 48) + x27 := (uint64(arg1[5]) << 40) + x28 := (uint64(arg1[4]) << 32) + x29 := (uint64(arg1[3]) << 24) + x30 := (uint64(arg1[2]) << 16) + x31 := (uint64(arg1[1]) << 8) + x32 := arg1[0] + x33 := (x31 + uint64(x32)) + x34 := (x30 + x33) + x35 := (x29 + x34) + x36 := (x28 + x35) + x37 := (x27 + x36) + x38 := (x26 + x37) + x39 := (x25 + x38) + x40 := (x23 + uint64(x24)) + x41 := (x22 + x40) + x42 := (x21 + x41) + x43 := (x20 + x42) + x44 := (x19 + x43) + x45 := (x18 + x44) + x46 := (x17 + x45) + x47 := (x15 + uint64(x16)) + x48 := (x14 + x47) + x49 := (x13 + x48) + x50 := (x12 + x49) + x51 := (x11 + x50) + x52 := (x10 + x51) + x53 := (x9 + x52) + x54 := (x7 + uint64(x8)) + x55 := (x6 + x54) + x56 := (x5 + x55) + x57 := (x4 + x56) + x58 := (x3 + x57) + x59 := (x2 + x58) + x60 := (x1 + x59) + out1[0] = x39 + out1[1] = x46 + out1[2] = x53 + out1[3] = x60 +} + +// SetOne returns the field element one in the Montgomery domain. +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = 1 mod m +// 0 ≤ eval out1 < m +func SetOne(out1 *MontgomeryDomainFieldElement) { + out1[0] = uint64(0x1) + out1[1] = 0xffffffff00000000 + out1[2] = 0xffffffffffffffff + out1[3] = 0xfffffffe +} diff --git a/pkg/crypto/core/curves/native/p256/fq/fq.go b/pkg/crypto/core/curves/native/p256/fq/fq.go new file mode 100755 index 000000000..6d4cd2bbb --- /dev/null +++ b/pkg/crypto/core/curves/native/p256/fq/fq.go @@ -0,0 +1,295 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fq + +import ( + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" +) + +var ( + p256FqInitonce sync.Once + p256FqParams native.FieldParams +) + +func P256FqNew() *native.Field { + return &native.Field{ + Value: [native.FieldLimbs]uint64{}, + Params: getP256FqParams(), + Arithmetic: p256FqArithmetic{}, + } +} + +func p256FqParamsInit() { + // See FIPS 186-3, section D.2.3 + p256FqParams = native.FieldParams{ + R: [native.FieldLimbs]uint64{0x0c46353d039cdaaf, 0x4319055258e8617b, 0x0000000000000000, 0x00000000ffffffff}, + R2: [native.FieldLimbs]uint64{0x83244c95be79eea2, 0x4699799c49bd6fa6, 0x2845b2392b6bec59, 0x66e12d94f3d95620}, + R3: [native.FieldLimbs]uint64{0xac8ebec90b65a624, 0x111f28ae0c0555c9, 0x2543b9246ba5e93f, 0x503a54e76407be65}, + Modulus: [native.FieldLimbs]uint64{0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000}, + BiModulus: new(big.Int).SetBytes([]byte{ + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, + }), + } +} + +func getP256FqParams() *native.FieldParams { + p256FqInitonce.Do(p256FqParamsInit) + return &p256FqParams +} + +// p256FqArithmetic is a struct with all the methods needed for working +// in mod q +type p256FqArithmetic struct{} + +// ToMontgomery converts this field to montgomery form +func (f p256FqArithmetic) ToMontgomery(out, arg *[native.FieldLimbs]uint64) { + ToMontgomery((*MontgomeryDomainFieldElement)(out), (*NonMontgomeryDomainFieldElement)(arg)) +} + +// FromMontgomery converts this field from montgomery form +func (f p256FqArithmetic) FromMontgomery(out, arg *[native.FieldLimbs]uint64) { + FromMontgomery((*NonMontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Neg performs modular negation +func (f p256FqArithmetic) Neg(out, arg *[native.FieldLimbs]uint64) { + Opp((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Square performs modular square +func (f p256FqArithmetic) Square(out, arg *[native.FieldLimbs]uint64) { + Square((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg)) +} + +// Mul performs modular multiplication +func (f p256FqArithmetic) Mul(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Mul((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Add performs modular addition +func (f p256FqArithmetic) Add(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Add((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Sub performs modular subtraction +func (f p256FqArithmetic) Sub(out, arg1, arg2 *[native.FieldLimbs]uint64) { + Sub((*MontgomeryDomainFieldElement)(out), (*MontgomeryDomainFieldElement)(arg1), (*MontgomeryDomainFieldElement)(arg2)) +} + +// Sqrt performs modular square root +func (f p256FqArithmetic) Sqrt(wasSquare *int, out, arg *[native.FieldLimbs]uint64) { + // See sqrt_ts_ct at + // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-I.4 + // c1 := s + // c2 := (q - 1) / (2^c1) + // c2 := [4]uint64{ + // 0x4f3b9cac2fc63255, + // 0xfbce6faada7179e8, + // 0x0fffffffffffffff, + // 0x0ffffffff0000000, + // } + // c3 := (c2 - 1) / 2 + c3 := [native.FieldLimbs]uint64{ + 0x279dce5617e3192a, + 0xfde737d56d38bcf4, + 0x07ffffffffffffff, + 0x07fffffff8000000, + } + // c4 := generator + // c5 := new(Fq).pow(generator, c2) + c5 := [native.FieldLimbs]uint64{0x1015708f7e368fe1, 0x31c6c5456ecc4511, 0x5281fe8998a19ea1, 0x0279089e10c63fe8} + var z, t, b, c, tv [native.FieldLimbs]uint64 + + native.Pow(&z, arg, &c3, getP256FqParams(), f) + Square((*MontgomeryDomainFieldElement)(&t), (*MontgomeryDomainFieldElement)(&z)) + Mul((*MontgomeryDomainFieldElement)(&t), (*MontgomeryDomainFieldElement)(&t), (*MontgomeryDomainFieldElement)(arg)) + Mul((*MontgomeryDomainFieldElement)(&z), (*MontgomeryDomainFieldElement)(&z), (*MontgomeryDomainFieldElement)(arg)) + + copy(b[:], t[:]) + copy(c[:], c5[:]) + + for i := s; i >= 2; i-- { + for j := 1; j <= i-2; j++ { + Square((*MontgomeryDomainFieldElement)(&b), (*MontgomeryDomainFieldElement)(&b)) + } + // if b == 1 flag = 0 else flag = 1 + flag := -(&native.Field{ + Value: b, + Params: getP256FqParams(), + Arithmetic: f, + }).IsOne() + 1 + Mul((*MontgomeryDomainFieldElement)(&tv), (*MontgomeryDomainFieldElement)(&z), (*MontgomeryDomainFieldElement)(&c)) + Selectznz(&z, uint1(flag), &z, &tv) + Square((*MontgomeryDomainFieldElement)(&c), (*MontgomeryDomainFieldElement)(&c)) + Mul((*MontgomeryDomainFieldElement)(&tv), (*MontgomeryDomainFieldElement)(&t), (*MontgomeryDomainFieldElement)(&c)) + Selectznz(&t, uint1(flag), &t, &tv) + copy(b[:], t[:]) + } + Square((*MontgomeryDomainFieldElement)(&c), (*MontgomeryDomainFieldElement)(&z)) + *wasSquare = (&native.Field{ + Value: c, + Params: getP256FqParams(), + Arithmetic: f, + }).Equal(&native.Field{ + Value: *arg, + Params: getP256FqParams(), + Arithmetic: f, + }) + Selectznz(out, uint1(*wasSquare), out, &z) +} + +// Invert performs modular inverse +func (f p256FqArithmetic) Invert(wasInverted *int, out, arg *[native.FieldLimbs]uint64) { + // Using an addition chain from + // https://briansmith.org/ecc-inversion-addition-chains-01#p256_field_inversion + var x1, x10, x11, x101, x111, x1010, x1111, x10101, x101010, x101111 [native.FieldLimbs]uint64 + var x6, x8, x16, x32, tmp [native.FieldLimbs]uint64 + + copy(x1[:], arg[:]) + native.Pow2k(&x10, arg, 1, f) + Mul((*MontgomeryDomainFieldElement)(&x11), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x1)) + Mul((*MontgomeryDomainFieldElement)(&x101), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x11)) + Mul((*MontgomeryDomainFieldElement)(&x111), (*MontgomeryDomainFieldElement)(&x10), (*MontgomeryDomainFieldElement)(&x101)) + native.Pow2k(&x1010, &x101, 1, f) + Mul((*MontgomeryDomainFieldElement)(&x1111), (*MontgomeryDomainFieldElement)(&x101), (*MontgomeryDomainFieldElement)(&x1010)) + native.Pow2k(&x10101, &x1010, 1, f) + Mul((*MontgomeryDomainFieldElement)(&x10101), (*MontgomeryDomainFieldElement)(&x10101), (*MontgomeryDomainFieldElement)(&x1)) + native.Pow2k(&x101010, &x10101, 1, f) + Mul((*MontgomeryDomainFieldElement)(&x101111), (*MontgomeryDomainFieldElement)(&x101), (*MontgomeryDomainFieldElement)(&x101010)) + + Mul((*MontgomeryDomainFieldElement)(&x6), (*MontgomeryDomainFieldElement)(&x10101), (*MontgomeryDomainFieldElement)(&x101010)) + + native.Pow2k(&x8, &x6, 2, f) + Mul((*MontgomeryDomainFieldElement)(&x8), (*MontgomeryDomainFieldElement)(&x8), (*MontgomeryDomainFieldElement)(&x11)) + + native.Pow2k(&x16, &x8, 8, f) + Mul((*MontgomeryDomainFieldElement)(&x16), (*MontgomeryDomainFieldElement)(&x16), (*MontgomeryDomainFieldElement)(&x8)) + + native.Pow2k(&x32, &x16, 16, f) + Mul((*MontgomeryDomainFieldElement)(&x32), (*MontgomeryDomainFieldElement)(&x32), (*MontgomeryDomainFieldElement)(&x16)) + + native.Pow2k(&tmp, &x32, 64, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x32)) + + native.Pow2k(&tmp, &tmp, 32, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x32)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101111)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x11)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1111)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x10101)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101)) + + native.Pow2k(&tmp, &tmp, 3, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101)) + + native.Pow2k(&tmp, &tmp, 3, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 9, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101111)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1111)) + + native.Pow2k(&tmp, &tmp, 2, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1111)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 4, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x111)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101)) + + native.Pow2k(&tmp, &tmp, 3, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x11)) + + native.Pow2k(&tmp, &tmp, 10, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x101111)) + + native.Pow2k(&tmp, &tmp, 2, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x11)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x11)) + + native.Pow2k(&tmp, &tmp, 5, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x11)) + + native.Pow2k(&tmp, &tmp, 3, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1)) + + native.Pow2k(&tmp, &tmp, 7, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x10101)) + + native.Pow2k(&tmp, &tmp, 6, f) + Mul((*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&tmp), (*MontgomeryDomainFieldElement)(&x1111)) + + *wasInverted = (&native.Field{ + Value: *arg, + Params: getP256FqParams(), + Arithmetic: f, + }).IsNonZero() + Selectznz(out, uint1(*wasInverted), out, &tmp) +} + +// FromBytes converts a little endian byte array into a field element +func (f p256FqArithmetic) FromBytes(out *[native.FieldLimbs]uint64, arg *[native.FieldBytes]byte) { + FromBytes(out, arg) +} + +// ToBytes converts a field element to a little endian byte array +func (f p256FqArithmetic) ToBytes(out *[native.FieldBytes]byte, arg *[native.FieldLimbs]uint64) { + ToBytes(out, arg) +} + +// Selectznz performs conditional select. +// selects arg1 if choice == 0 and arg2 if choice == 1 +func (f p256FqArithmetic) Selectznz(out, arg1, arg2 *[native.FieldLimbs]uint64, choice int) { + Selectznz(out, uint1(choice), arg1, arg2) +} + +// generator = 7 mod q is a generator of the `q - 1` order multiplicative +// subgroup, or in other words a primitive element of the field. +// generator^t where t * 2^s + 1 = q +var generator = &[native.FieldLimbs]uint64{0x55eb74ab1949fac9, 0xd5af25406e5aaa5d, 0x0000000000000001, 0x00000006fffffff9} + +// s satisfies the equation 2^s * t = q - 1 with t odd. +var s = 4 + +// rootOfUnity +var rootOfUnity = &[native.FieldLimbs]uint64{0x0592d7fbb41e6602, 0x1546cad004378daf, 0xba807ace842a3dfc, 0xffc97f062a770992} diff --git a/pkg/crypto/core/curves/native/p256/fq/fq_test.go b/pkg/crypto/core/curves/native/p256/fq/fq_test.go new file mode 100755 index 000000000..577912558 --- /dev/null +++ b/pkg/crypto/core/curves/native/p256/fq/fq_test.go @@ -0,0 +1,328 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fq + +import ( + crand "crypto/rand" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func TestFqSetOne(t *testing.T) { + fq := P256FqNew().SetOne() + require.NotNil(t, fq) + require.Equal(t, fq.Value, getP256FqParams().R) +} + +func TestFqSetUint64(t *testing.T) { + act := P256FqNew().SetUint64(1 << 60) + require.NotNil(t, act) + // Remember it will be in montgomery form + require.Equal(t, act.Value[0], uint64(0xb3f3986dec632551)) +} + +func TestFqAdd(t *testing.T) { + lhs := P256FqNew().SetOne() + rhs := P256FqNew().SetOne() + exp := P256FqNew().SetUint64(2) + res := P256FqNew().Add(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + e := l + r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := P256FqNew().Add(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqSub(t *testing.T) { + lhs := P256FqNew().SetOne() + rhs := P256FqNew().SetOne() + exp := P256FqNew().SetZero() + res := P256FqNew().Sub(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + if l < r { + l, r = r, l + } + e := l - r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := P256FqNew().Sub(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqMul(t *testing.T) { + lhs := P256FqNew().SetOne() + rhs := P256FqNew().SetOne() + exp := P256FqNew().SetOne() + res := P256FqNew().Mul(lhs, rhs) + require.NotNil(t, res) + require.Equal(t, 1, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint32() + r := rand.Uint32() + e := uint64(l) * uint64(r) + lhs.SetUint64(uint64(l)) + rhs.SetUint64(uint64(r)) + exp.SetUint64(e) + + a := P256FqNew().Mul(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqDouble(t *testing.T) { + a := P256FqNew().SetUint64(2) + e := P256FqNew().SetUint64(4) + require.Equal(t, e, P256FqNew().Double(a)) + + for i := 0; i < 25; i++ { + tv := rand.Uint32() + ttv := uint64(tv) * 2 + a = P256FqNew().SetUint64(uint64(tv)) + e = P256FqNew().SetUint64(ttv) + require.Equal(t, e, P256FqNew().Double(a)) + } +} + +func TestFqSquare(t *testing.T) { + a := P256FqNew().SetUint64(4) + e := P256FqNew().SetUint64(16) + require.Equal(t, e, a.Square(a)) + + for i := 0; i < 25; i++ { + j := rand.Uint32() + exp := uint64(j) * uint64(j) + e.SetUint64(exp) + a.SetUint64(uint64(j)) + require.Equal(t, e, a.Square(a)) + } +} + +func TestFqNeg(t *testing.T) { + g := P256FqNew().SetRaw(generator) + a := P256FqNew().SetOne() + a.Neg(a) + e := P256FqNew().SetRaw(&[native.FieldLimbs]uint64{0xe7739585f8c64aa2, 0x79cdf55b4e2f3d09, 0xffffffffffffffff, 0xfffffffe00000001}) + require.Equal(t, e, a) + a.Neg(g) + e = P256FqNew().SetRaw(&[native.FieldLimbs]uint64{0x9dce5617e3192a88, 0xe737d56d38bcf427, 0xfffffffffffffffd, 0xfffffff800000007}) + require.Equal(t, e, a) +} + +func TestFqExp(t *testing.T) { + e := P256FqNew().SetUint64(8) + a := P256FqNew().SetUint64(2) + by := P256FqNew().SetUint64(3) + require.Equal(t, e, a.Exp(a, by)) +} + +func TestFqSqrt(t *testing.T) { + t1 := P256FqNew().SetUint64(2) + t2 := P256FqNew().Neg(t1) + t3 := P256FqNew().Square(t1) + _, wasSquare := t3.Sqrt(t3) + + require.True(t, wasSquare) + require.Equal(t, 1, t1.Equal(t3)|t2.Equal(t3)) + t1.SetUint64(7) + _, wasSquare = t3.Sqrt(t1) + require.False(t, wasSquare) +} + +func TestFqInvert(t *testing.T) { + twoInv := P256FqNew().SetRaw(&[native.FieldLimbs]uint64{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8000000000000000}) + two := P256FqNew().SetUint64(2) + a, inverted := P256FqNew().Invert(two) + require.True(t, inverted) + require.Equal(t, a, twoInv) + + rootOfUnityInv := P256FqNew().SetRaw(&[native.FieldLimbs]uint64{0xcfbf53b9618acf96, 0xf17e5c39df7bd05b, 0xc7acb1f83e3ad9ad, 0x4659a42b394ff7df}) + rootOU := P256FqNew().SetRaw(rootOfUnity) + a, inverted = P256FqNew().Invert(rootOU) + require.True(t, inverted) + require.Equal(t, a, rootOfUnityInv) + + lhs := P256FqNew().SetUint64(9) + rhs := P256FqNew().SetUint64(3) + rhsInv, inverted := P256FqNew().Invert(rhs) + require.True(t, inverted) + require.Equal(t, rhs, P256FqNew().Mul(lhs, rhsInv)) + + rhs.SetZero() + _, inverted = P256FqNew().Invert(rhs) + require.False(t, inverted) +} + +func TestFqCMove(t *testing.T) { + t1 := P256FqNew().SetUint64(5) + t2 := P256FqNew().SetUint64(10) + require.Equal(t, t1, P256FqNew().CMove(t1, t2, 0)) + require.Equal(t, t2, P256FqNew().CMove(t1, t2, 1)) +} + +func TestFqBytes(t *testing.T) { + t1 := P256FqNew().SetUint64(99) + seq := t1.Bytes() + t2, err := P256FqNew().SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + + for i := 0; i < 25; i++ { + t1.SetUint64(rand.Uint64()) + seq = t1.Bytes() + _, err = t2.SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + } +} + +func TestFqCmp(t *testing.T) { + tests := []struct { + a *native.Field + b *native.Field + e int + }{ + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{2731658267414164836, 14655288906067898431, 6537465423330262322, 8306191141697566219}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{6472764012681988529, 10848812988401906064, 2961825807536828898, 4282183981941645679}), + e: 1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{8023004109510539223, 4652004072850285717, 1877219145646046927, 383214385093921911}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{10099384440823804262, 16139476942229308465, 8636966320777393798, 5435928725024696785}), + e: -1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{3741840066202388211, 12165774400417314871, 16619312580230515379, 16195032234110087705}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{3905865991286066744, 543690822309071825, 17963103015950210055, 3745476720756119742}), + e: 1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{16660853697936147788, 7799793619412111108, 13515141085171033220, 2641079731236069032}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{17790588295388238399, 571847801379669440, 14537208974498222469, 12792570372087452754}), + e: -1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{3912839285384959186, 2701177075110484070, 6453856448115499033, 6475797457962597458}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{1282566391665688512, 13503640416992806563, 2962240104675990153, 3374904770947067689}), + e: 1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{5716631803409360103, 7859567470082614154, 12747956220853330146, 18434584096087315020}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{16317076441459028418, 12854146980376319601, 2258436689269031143, 9531877130792223752}), + e: 1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{17955191469941083403, 10350326247207200880, 17263512235150705075, 12700328451238078022}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{6767595547459644695, 7146403825494928147, 12269344038346710612, 9122477829383225603}), + e: 1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{17099388671847024438, 6426264987820696548, 10641143464957227405, 7709745403700754098}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{10799154372990268556, 17178492485719929374, 5705777922258988797, 8051037767683567782}), + e: -1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{4567139260680454325, 1629385880182139061, 16607020832317899145, 1261011562621553200}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{13487234491304534488, 17872642955936089265, 17651026784972590233, 9468934643333871559}), + e: -1, + }, + { + a: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{18071070103467571798, 11787850505799426140, 10631355976141928593, 4867785203635092610}), + b: P256FqNew().SetRaw(&[native.FieldLimbs]uint64{12596443599426461624, 10176122686151524591, 17075755296887483439, 6726169532695070719}), + e: -1, + }, + } + + for _, test := range tests { + require.Equal(t, test.e, test.a.Cmp(test.b)) + require.Equal(t, -test.e, test.b.Cmp(test.a)) + require.Equal(t, 0, test.a.Cmp(test.a)) + require.Equal(t, 0, test.b.Cmp(test.b)) + } +} + +func TestFqBigInt(t *testing.T) { + t1 := P256FqNew().SetBigInt(big.NewInt(9999)) + t2 := P256FqNew().SetBigInt(t1.BigInt()) + require.Equal(t, t1, t2) + + e := P256FqNew().SetRaw(&[native.FieldLimbs]uint64{0x21dcaaadf1cb6aa0, 0x568de5f5990a98d7, 0x354f43b0d837fac5, 0x3e02532cb23f481a}) + b := new(big.Int).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}) + t1.SetBigInt(b) + require.Equal(t, e, t1) + e.Value[0] = 0xd1dd20150a97bab1 + e.Value[1] = 0x665914b80e0d05ad + e.Value[2] = 0xcab0bc4f27c8053a + e.Value[3] = 0xc1fdacd24dc0b7e6 + b.Neg(b) + t1.SetBigInt(b) + require.Equal(t, e, t1) +} + +func TestFqSetBytesWide(t *testing.T) { + e := P256FqNew().SetRaw(&[native.FieldLimbs]uint64{0xe2b8d4b0e576c8fa, 0x9d2b215f85d3bdf7, 0xf6070a872442640c, 0xcf15d1e49c990b88}) + + a := P256FqNew().SetBytesWide(&[64]byte{ + 0x69, 0x23, 0x5a, 0x0b, 0xce, 0x0c, 0xa8, 0x64, + 0x3c, 0x78, 0xbc, 0x01, 0x05, 0xef, 0xf2, 0x84, + 0xde, 0xbb, 0x6b, 0xc8, 0x63, 0x5e, 0x6e, 0x69, + 0x62, 0xcc, 0xc6, 0x2d, 0xf5, 0x72, 0x40, 0x92, + 0x28, 0x11, 0xd6, 0xc8, 0x07, 0xa5, 0x88, 0x82, + 0xfe, 0xe3, 0x97, 0xf6, 0x1e, 0xfb, 0x2e, 0x3b, + 0x27, 0x5f, 0x85, 0x06, 0x8d, 0x99, 0xa4, 0x75, + 0xc0, 0x2c, 0x71, 0x69, 0x9e, 0x58, 0xea, 0x52, + }) + require.Equal(t, e, a) +} + +func TestFpSetBytesWideBigInt(t *testing.T) { + params := getP256FqParams() + var tv2 [64]byte + for i := 0; i < 25; i++ { + _, _ = crand.Read(tv2[:]) + e := new(big.Int).SetBytes(tv2[:]) + e.Mod(e, params.BiModulus) + + tv := internal.ReverseScalarBytes(tv2[:]) + copy(tv2[:], tv) + a := P256FqNew().SetBytesWide(&tv2) + require.Equal(t, 0, e.Cmp(a.BigInt())) + } +} diff --git a/pkg/crypto/core/curves/native/p256/fq/p256_fq.go b/pkg/crypto/core/curves/native/p256/fq/p256_fq.go new file mode 100755 index 000000000..728e58b1f --- /dev/null +++ b/pkg/crypto/core/curves/native/p256/fq/p256_fq.go @@ -0,0 +1,1651 @@ +// Code generated by Fiat Cryptography. DO NOT EDIT. +// +// Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --lang Go --no-wide-int --relax-primitive-carry-to-bitwidth 32,64 --cmovznz-by-mul --internal-static --package-case flatcase --public-function-case UpperCamelCase --private-function-case camelCase --public-type-case UpperCamelCase --private-type-case camelCase --no-prefix-fiat --doc-newline-in-typedef-bounds --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' --doc-text-before-function-name ” --doc-text-before-type-name ” --package-name fq ” 64 '2^256 - 2^224 + 2^192 - 89188191075325690597107910205041859247' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one +// +// curve description (via package name): fq +// +// machine_wordsize = 64 (from "64") +// +// requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one +// +// m = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 (from "2^256 - 2^224 + 2^192 - 89188191075325690597107910205041859247") +// +// NOTE: In addition to the bounds specified above each function, all +// +// functions synthesized for this Montgomery arithmetic require the +// +// input to be strictly less than the prime modulus (m), and also +// +// require the input to be in the unique saturated representation. +// +// All functions also ensure that these two properties are true of +// +// return values. +// +// Computed values: +// +// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) +// +// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) +// +// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in +// +// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 +package fq + +import "math/bits" + +type uint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 +type int1 int64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 + +// MontgomeryDomainFieldElement is a field element in the Montgomery domain. +// +// Bounds: +// +// [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type MontgomeryDomainFieldElement [4]uint64 + +// NonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain. +// +// Bounds: +// +// [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type NonMontgomeryDomainFieldElement [4]uint64 + +// cmovznzU64 is a single-word conditional move. +// +// Postconditions: +// +// out1 = (if arg1 = 0 then arg2 else arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [0x0 ~> 0xffffffffffffffff] +// arg3: [0x0 ~> 0xffffffffffffffff] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func cmovznzU64(out1 *uint64, arg1 uint1, arg2 uint64, arg3 uint64) { + x1 := (uint64(arg1) * 0xffffffffffffffff) + x2 := ((x1 & arg3) | ((^x1) & arg2)) + *out1 = x2 +} + +// Mul multiplies two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Mul(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg2[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg2[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg2[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg2[0]) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + x19 := (uint64(uint1(x18)) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0xccd1c8aaee00bc4f) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0xffffffff00000000) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0xffffffffffffffff) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0xbce6faada7179e84) + var x28 uint64 + var x29 uint64 + x29, x28 = bits.Mul64(x20, 0xf3b9cac2fc632551) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x29, x26, uint64(0x0)) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x27, x24, uint64(uint1(x31))) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x25, x22, uint64(uint1(x33))) + x36 := (uint64(uint1(x35)) + x23) + var x38 uint64 + _, x38 = bits.Add64(x11, x28, uint64(0x0)) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x13, x30, uint64(uint1(x38))) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x15, x32, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64(x17, x34, uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Add64(x19, x36, uint64(uint1(x44))) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg2[3]) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x1, arg2[2]) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x1, arg2[1]) + var x53 uint64 + var x54 uint64 + x54, x53 = bits.Mul64(x1, arg2[0]) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x54, x51, uint64(0x0)) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x52, x49, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x50, x47, uint64(uint1(x58))) + x61 := (uint64(uint1(x60)) + x48) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x39, x53, uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x41, x55, uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x43, x57, uint64(uint1(x65))) + var x68 uint64 + var x69 uint64 + x68, x69 = bits.Add64(x45, x59, uint64(uint1(x67))) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(uint64(uint1(x46)), x61, uint64(uint1(x69))) + var x72 uint64 + _, x72 = bits.Mul64(x62, 0xccd1c8aaee00bc4f) + var x74 uint64 + var x75 uint64 + x75, x74 = bits.Mul64(x72, 0xffffffff00000000) + var x76 uint64 + var x77 uint64 + x77, x76 = bits.Mul64(x72, 0xffffffffffffffff) + var x78 uint64 + var x79 uint64 + x79, x78 = bits.Mul64(x72, 0xbce6faada7179e84) + var x80 uint64 + var x81 uint64 + x81, x80 = bits.Mul64(x72, 0xf3b9cac2fc632551) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x81, x78, uint64(0x0)) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x79, x76, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x77, x74, uint64(uint1(x85))) + x88 := (uint64(uint1(x87)) + x75) + var x90 uint64 + _, x90 = bits.Add64(x62, x80, uint64(0x0)) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(x64, x82, uint64(uint1(x90))) + var x93 uint64 + var x94 uint64 + x93, x94 = bits.Add64(x66, x84, uint64(uint1(x92))) + var x95 uint64 + var x96 uint64 + x95, x96 = bits.Add64(x68, x86, uint64(uint1(x94))) + var x97 uint64 + var x98 uint64 + x97, x98 = bits.Add64(x70, x88, uint64(uint1(x96))) + x99 := (uint64(uint1(x98)) + uint64(uint1(x71))) + var x100 uint64 + var x101 uint64 + x101, x100 = bits.Mul64(x2, arg2[3]) + var x102 uint64 + var x103 uint64 + x103, x102 = bits.Mul64(x2, arg2[2]) + var x104 uint64 + var x105 uint64 + x105, x104 = bits.Mul64(x2, arg2[1]) + var x106 uint64 + var x107 uint64 + x107, x106 = bits.Mul64(x2, arg2[0]) + var x108 uint64 + var x109 uint64 + x108, x109 = bits.Add64(x107, x104, uint64(0x0)) + var x110 uint64 + var x111 uint64 + x110, x111 = bits.Add64(x105, x102, uint64(uint1(x109))) + var x112 uint64 + var x113 uint64 + x112, x113 = bits.Add64(x103, x100, uint64(uint1(x111))) + x114 := (uint64(uint1(x113)) + x101) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x91, x106, uint64(0x0)) + var x117 uint64 + var x118 uint64 + x117, x118 = bits.Add64(x93, x108, uint64(uint1(x116))) + var x119 uint64 + var x120 uint64 + x119, x120 = bits.Add64(x95, x110, uint64(uint1(x118))) + var x121 uint64 + var x122 uint64 + x121, x122 = bits.Add64(x97, x112, uint64(uint1(x120))) + var x123 uint64 + var x124 uint64 + x123, x124 = bits.Add64(x99, x114, uint64(uint1(x122))) + var x125 uint64 + _, x125 = bits.Mul64(x115, 0xccd1c8aaee00bc4f) + var x127 uint64 + var x128 uint64 + x128, x127 = bits.Mul64(x125, 0xffffffff00000000) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x125, 0xffffffffffffffff) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x125, 0xbce6faada7179e84) + var x133 uint64 + var x134 uint64 + x134, x133 = bits.Mul64(x125, 0xf3b9cac2fc632551) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x134, x131, uint64(0x0)) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x132, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(x130, x127, uint64(uint1(x138))) + x141 := (uint64(uint1(x140)) + x128) + var x143 uint64 + _, x143 = bits.Add64(x115, x133, uint64(0x0)) + var x144 uint64 + var x145 uint64 + x144, x145 = bits.Add64(x117, x135, uint64(uint1(x143))) + var x146 uint64 + var x147 uint64 + x146, x147 = bits.Add64(x119, x137, uint64(uint1(x145))) + var x148 uint64 + var x149 uint64 + x148, x149 = bits.Add64(x121, x139, uint64(uint1(x147))) + var x150 uint64 + var x151 uint64 + x150, x151 = bits.Add64(x123, x141, uint64(uint1(x149))) + x152 := (uint64(uint1(x151)) + uint64(uint1(x124))) + var x153 uint64 + var x154 uint64 + x154, x153 = bits.Mul64(x3, arg2[3]) + var x155 uint64 + var x156 uint64 + x156, x155 = bits.Mul64(x3, arg2[2]) + var x157 uint64 + var x158 uint64 + x158, x157 = bits.Mul64(x3, arg2[1]) + var x159 uint64 + var x160 uint64 + x160, x159 = bits.Mul64(x3, arg2[0]) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Add64(x160, x157, uint64(0x0)) + var x163 uint64 + var x164 uint64 + x163, x164 = bits.Add64(x158, x155, uint64(uint1(x162))) + var x165 uint64 + var x166 uint64 + x165, x166 = bits.Add64(x156, x153, uint64(uint1(x164))) + x167 := (uint64(uint1(x166)) + x154) + var x168 uint64 + var x169 uint64 + x168, x169 = bits.Add64(x144, x159, uint64(0x0)) + var x170 uint64 + var x171 uint64 + x170, x171 = bits.Add64(x146, x161, uint64(uint1(x169))) + var x172 uint64 + var x173 uint64 + x172, x173 = bits.Add64(x148, x163, uint64(uint1(x171))) + var x174 uint64 + var x175 uint64 + x174, x175 = bits.Add64(x150, x165, uint64(uint1(x173))) + var x176 uint64 + var x177 uint64 + x176, x177 = bits.Add64(x152, x167, uint64(uint1(x175))) + var x178 uint64 + _, x178 = bits.Mul64(x168, 0xccd1c8aaee00bc4f) + var x180 uint64 + var x181 uint64 + x181, x180 = bits.Mul64(x178, 0xffffffff00000000) + var x182 uint64 + var x183 uint64 + x183, x182 = bits.Mul64(x178, 0xffffffffffffffff) + var x184 uint64 + var x185 uint64 + x185, x184 = bits.Mul64(x178, 0xbce6faada7179e84) + var x186 uint64 + var x187 uint64 + x187, x186 = bits.Mul64(x178, 0xf3b9cac2fc632551) + var x188 uint64 + var x189 uint64 + x188, x189 = bits.Add64(x187, x184, uint64(0x0)) + var x190 uint64 + var x191 uint64 + x190, x191 = bits.Add64(x185, x182, uint64(uint1(x189))) + var x192 uint64 + var x193 uint64 + x192, x193 = bits.Add64(x183, x180, uint64(uint1(x191))) + x194 := (uint64(uint1(x193)) + x181) + var x196 uint64 + _, x196 = bits.Add64(x168, x186, uint64(0x0)) + var x197 uint64 + var x198 uint64 + x197, x198 = bits.Add64(x170, x188, uint64(uint1(x196))) + var x199 uint64 + var x200 uint64 + x199, x200 = bits.Add64(x172, x190, uint64(uint1(x198))) + var x201 uint64 + var x202 uint64 + x201, x202 = bits.Add64(x174, x192, uint64(uint1(x200))) + var x203 uint64 + var x204 uint64 + x203, x204 = bits.Add64(x176, x194, uint64(uint1(x202))) + x205 := (uint64(uint1(x204)) + uint64(uint1(x177))) + var x206 uint64 + var x207 uint64 + x206, x207 = bits.Sub64(x197, 0xf3b9cac2fc632551, uint64(0x0)) + var x208 uint64 + var x209 uint64 + x208, x209 = bits.Sub64(x199, 0xbce6faada7179e84, uint64(uint1(x207))) + var x210 uint64 + var x211 uint64 + x210, x211 = bits.Sub64(x201, 0xffffffffffffffff, uint64(uint1(x209))) + var x212 uint64 + var x213 uint64 + x212, x213 = bits.Sub64(x203, 0xffffffff00000000, uint64(uint1(x211))) + var x215 uint64 + _, x215 = bits.Sub64(x205, uint64(0x0), uint64(uint1(x213))) + var x216 uint64 + cmovznzU64(&x216, uint1(x215), x206, x197) + var x217 uint64 + cmovznzU64(&x217, uint1(x215), x208, x199) + var x218 uint64 + cmovznzU64(&x218, uint1(x215), x210, x201) + var x219 uint64 + cmovznzU64(&x219, uint1(x215), x212, x203) + out1[0] = x216 + out1[1] = x217 + out1[2] = x218 + out1[3] = x219 +} + +// Square squares a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m +// 0 ≤ eval out1 < m +func Square(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg1[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg1[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg1[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg1[0]) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + x19 := (uint64(uint1(x18)) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0xccd1c8aaee00bc4f) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0xffffffff00000000) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0xffffffffffffffff) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0xbce6faada7179e84) + var x28 uint64 + var x29 uint64 + x29, x28 = bits.Mul64(x20, 0xf3b9cac2fc632551) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x29, x26, uint64(0x0)) + var x32 uint64 + var x33 uint64 + x32, x33 = bits.Add64(x27, x24, uint64(uint1(x31))) + var x34 uint64 + var x35 uint64 + x34, x35 = bits.Add64(x25, x22, uint64(uint1(x33))) + x36 := (uint64(uint1(x35)) + x23) + var x38 uint64 + _, x38 = bits.Add64(x11, x28, uint64(0x0)) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x13, x30, uint64(uint1(x38))) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x15, x32, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64(x17, x34, uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x45, x46 = bits.Add64(x19, x36, uint64(uint1(x44))) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg1[3]) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x1, arg1[2]) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x1, arg1[1]) + var x53 uint64 + var x54 uint64 + x54, x53 = bits.Mul64(x1, arg1[0]) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x54, x51, uint64(0x0)) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x52, x49, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x50, x47, uint64(uint1(x58))) + x61 := (uint64(uint1(x60)) + x48) + var x62 uint64 + var x63 uint64 + x62, x63 = bits.Add64(x39, x53, uint64(0x0)) + var x64 uint64 + var x65 uint64 + x64, x65 = bits.Add64(x41, x55, uint64(uint1(x63))) + var x66 uint64 + var x67 uint64 + x66, x67 = bits.Add64(x43, x57, uint64(uint1(x65))) + var x68 uint64 + var x69 uint64 + x68, x69 = bits.Add64(x45, x59, uint64(uint1(x67))) + var x70 uint64 + var x71 uint64 + x70, x71 = bits.Add64(uint64(uint1(x46)), x61, uint64(uint1(x69))) + var x72 uint64 + _, x72 = bits.Mul64(x62, 0xccd1c8aaee00bc4f) + var x74 uint64 + var x75 uint64 + x75, x74 = bits.Mul64(x72, 0xffffffff00000000) + var x76 uint64 + var x77 uint64 + x77, x76 = bits.Mul64(x72, 0xffffffffffffffff) + var x78 uint64 + var x79 uint64 + x79, x78 = bits.Mul64(x72, 0xbce6faada7179e84) + var x80 uint64 + var x81 uint64 + x81, x80 = bits.Mul64(x72, 0xf3b9cac2fc632551) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x81, x78, uint64(0x0)) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64(x79, x76, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x77, x74, uint64(uint1(x85))) + x88 := (uint64(uint1(x87)) + x75) + var x90 uint64 + _, x90 = bits.Add64(x62, x80, uint64(0x0)) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(x64, x82, uint64(uint1(x90))) + var x93 uint64 + var x94 uint64 + x93, x94 = bits.Add64(x66, x84, uint64(uint1(x92))) + var x95 uint64 + var x96 uint64 + x95, x96 = bits.Add64(x68, x86, uint64(uint1(x94))) + var x97 uint64 + var x98 uint64 + x97, x98 = bits.Add64(x70, x88, uint64(uint1(x96))) + x99 := (uint64(uint1(x98)) + uint64(uint1(x71))) + var x100 uint64 + var x101 uint64 + x101, x100 = bits.Mul64(x2, arg1[3]) + var x102 uint64 + var x103 uint64 + x103, x102 = bits.Mul64(x2, arg1[2]) + var x104 uint64 + var x105 uint64 + x105, x104 = bits.Mul64(x2, arg1[1]) + var x106 uint64 + var x107 uint64 + x107, x106 = bits.Mul64(x2, arg1[0]) + var x108 uint64 + var x109 uint64 + x108, x109 = bits.Add64(x107, x104, uint64(0x0)) + var x110 uint64 + var x111 uint64 + x110, x111 = bits.Add64(x105, x102, uint64(uint1(x109))) + var x112 uint64 + var x113 uint64 + x112, x113 = bits.Add64(x103, x100, uint64(uint1(x111))) + x114 := (uint64(uint1(x113)) + x101) + var x115 uint64 + var x116 uint64 + x115, x116 = bits.Add64(x91, x106, uint64(0x0)) + var x117 uint64 + var x118 uint64 + x117, x118 = bits.Add64(x93, x108, uint64(uint1(x116))) + var x119 uint64 + var x120 uint64 + x119, x120 = bits.Add64(x95, x110, uint64(uint1(x118))) + var x121 uint64 + var x122 uint64 + x121, x122 = bits.Add64(x97, x112, uint64(uint1(x120))) + var x123 uint64 + var x124 uint64 + x123, x124 = bits.Add64(x99, x114, uint64(uint1(x122))) + var x125 uint64 + _, x125 = bits.Mul64(x115, 0xccd1c8aaee00bc4f) + var x127 uint64 + var x128 uint64 + x128, x127 = bits.Mul64(x125, 0xffffffff00000000) + var x129 uint64 + var x130 uint64 + x130, x129 = bits.Mul64(x125, 0xffffffffffffffff) + var x131 uint64 + var x132 uint64 + x132, x131 = bits.Mul64(x125, 0xbce6faada7179e84) + var x133 uint64 + var x134 uint64 + x134, x133 = bits.Mul64(x125, 0xf3b9cac2fc632551) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x134, x131, uint64(0x0)) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x132, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(x130, x127, uint64(uint1(x138))) + x141 := (uint64(uint1(x140)) + x128) + var x143 uint64 + _, x143 = bits.Add64(x115, x133, uint64(0x0)) + var x144 uint64 + var x145 uint64 + x144, x145 = bits.Add64(x117, x135, uint64(uint1(x143))) + var x146 uint64 + var x147 uint64 + x146, x147 = bits.Add64(x119, x137, uint64(uint1(x145))) + var x148 uint64 + var x149 uint64 + x148, x149 = bits.Add64(x121, x139, uint64(uint1(x147))) + var x150 uint64 + var x151 uint64 + x150, x151 = bits.Add64(x123, x141, uint64(uint1(x149))) + x152 := (uint64(uint1(x151)) + uint64(uint1(x124))) + var x153 uint64 + var x154 uint64 + x154, x153 = bits.Mul64(x3, arg1[3]) + var x155 uint64 + var x156 uint64 + x156, x155 = bits.Mul64(x3, arg1[2]) + var x157 uint64 + var x158 uint64 + x158, x157 = bits.Mul64(x3, arg1[1]) + var x159 uint64 + var x160 uint64 + x160, x159 = bits.Mul64(x3, arg1[0]) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Add64(x160, x157, uint64(0x0)) + var x163 uint64 + var x164 uint64 + x163, x164 = bits.Add64(x158, x155, uint64(uint1(x162))) + var x165 uint64 + var x166 uint64 + x165, x166 = bits.Add64(x156, x153, uint64(uint1(x164))) + x167 := (uint64(uint1(x166)) + x154) + var x168 uint64 + var x169 uint64 + x168, x169 = bits.Add64(x144, x159, uint64(0x0)) + var x170 uint64 + var x171 uint64 + x170, x171 = bits.Add64(x146, x161, uint64(uint1(x169))) + var x172 uint64 + var x173 uint64 + x172, x173 = bits.Add64(x148, x163, uint64(uint1(x171))) + var x174 uint64 + var x175 uint64 + x174, x175 = bits.Add64(x150, x165, uint64(uint1(x173))) + var x176 uint64 + var x177 uint64 + x176, x177 = bits.Add64(x152, x167, uint64(uint1(x175))) + var x178 uint64 + _, x178 = bits.Mul64(x168, 0xccd1c8aaee00bc4f) + var x180 uint64 + var x181 uint64 + x181, x180 = bits.Mul64(x178, 0xffffffff00000000) + var x182 uint64 + var x183 uint64 + x183, x182 = bits.Mul64(x178, 0xffffffffffffffff) + var x184 uint64 + var x185 uint64 + x185, x184 = bits.Mul64(x178, 0xbce6faada7179e84) + var x186 uint64 + var x187 uint64 + x187, x186 = bits.Mul64(x178, 0xf3b9cac2fc632551) + var x188 uint64 + var x189 uint64 + x188, x189 = bits.Add64(x187, x184, uint64(0x0)) + var x190 uint64 + var x191 uint64 + x190, x191 = bits.Add64(x185, x182, uint64(uint1(x189))) + var x192 uint64 + var x193 uint64 + x192, x193 = bits.Add64(x183, x180, uint64(uint1(x191))) + x194 := (uint64(uint1(x193)) + x181) + var x196 uint64 + _, x196 = bits.Add64(x168, x186, uint64(0x0)) + var x197 uint64 + var x198 uint64 + x197, x198 = bits.Add64(x170, x188, uint64(uint1(x196))) + var x199 uint64 + var x200 uint64 + x199, x200 = bits.Add64(x172, x190, uint64(uint1(x198))) + var x201 uint64 + var x202 uint64 + x201, x202 = bits.Add64(x174, x192, uint64(uint1(x200))) + var x203 uint64 + var x204 uint64 + x203, x204 = bits.Add64(x176, x194, uint64(uint1(x202))) + x205 := (uint64(uint1(x204)) + uint64(uint1(x177))) + var x206 uint64 + var x207 uint64 + x206, x207 = bits.Sub64(x197, 0xf3b9cac2fc632551, uint64(0x0)) + var x208 uint64 + var x209 uint64 + x208, x209 = bits.Sub64(x199, 0xbce6faada7179e84, uint64(uint1(x207))) + var x210 uint64 + var x211 uint64 + x210, x211 = bits.Sub64(x201, 0xffffffffffffffff, uint64(uint1(x209))) + var x212 uint64 + var x213 uint64 + x212, x213 = bits.Sub64(x203, 0xffffffff00000000, uint64(uint1(x211))) + var x215 uint64 + _, x215 = bits.Sub64(x205, uint64(0x0), uint64(uint1(x213))) + var x216 uint64 + cmovznzU64(&x216, uint1(x215), x206, x197) + var x217 uint64 + cmovznzU64(&x217, uint1(x215), x208, x199) + var x218 uint64 + cmovznzU64(&x218, uint1(x215), x210, x201) + var x219 uint64 + cmovznzU64(&x219, uint1(x215), x212, x203) + out1[0] = x216 + out1[1] = x217 + out1[2] = x218 + out1[3] = x219 +} + +// Add adds two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Add(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Add64(arg1[0], arg2[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Add64(arg1[1], arg2[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Add64(arg1[2], arg2[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Add64(arg1[3], arg2[3], uint64(uint1(x6))) + var x9 uint64 + var x10 uint64 + x9, x10 = bits.Sub64(x1, 0xf3b9cac2fc632551, uint64(0x0)) + var x11 uint64 + var x12 uint64 + x11, x12 = bits.Sub64(x3, 0xbce6faada7179e84, uint64(uint1(x10))) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Sub64(x5, 0xffffffffffffffff, uint64(uint1(x12))) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Sub64(x7, 0xffffffff00000000, uint64(uint1(x14))) + var x18 uint64 + _, x18 = bits.Sub64(uint64(uint1(x8)), uint64(0x0), uint64(uint1(x16))) + var x19 uint64 + cmovznzU64(&x19, uint1(x18), x9, x1) + var x20 uint64 + cmovznzU64(&x20, uint1(x18), x11, x3) + var x21 uint64 + cmovznzU64(&x21, uint1(x18), x13, x5) + var x22 uint64 + cmovznzU64(&x22, uint1(x18), x15, x7) + out1[0] = x19 + out1[1] = x20 + out1[2] = x21 + out1[3] = x22 +} + +// Sub subtracts two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func Sub(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement, arg2 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Sub64(arg1[0], arg2[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Sub64(arg1[1], arg2[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Sub64(arg1[2], arg2[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Sub64(arg1[3], arg2[3], uint64(uint1(x6))) + var x9 uint64 + cmovznzU64(&x9, uint1(x8), uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x10, x11 = bits.Add64(x1, (x9 & 0xf3b9cac2fc632551), uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x3, (x9 & 0xbce6faada7179e84), uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x5, x9, uint64(uint1(x13))) + var x16 uint64 + x16, _ = bits.Add64(x7, (x9 & 0xffffffff00000000), uint64(uint1(x15))) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// Opp negates a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m +// 0 ≤ eval out1 < m +func Opp(out1 *MontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + var x1 uint64 + var x2 uint64 + x1, x2 = bits.Sub64(uint64(0x0), arg1[0], uint64(0x0)) + var x3 uint64 + var x4 uint64 + x3, x4 = bits.Sub64(uint64(0x0), arg1[1], uint64(uint1(x2))) + var x5 uint64 + var x6 uint64 + x5, x6 = bits.Sub64(uint64(0x0), arg1[2], uint64(uint1(x4))) + var x7 uint64 + var x8 uint64 + x7, x8 = bits.Sub64(uint64(0x0), arg1[3], uint64(uint1(x6))) + var x9 uint64 + cmovznzU64(&x9, uint1(x8), uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 uint64 + x10, x11 = bits.Add64(x1, (x9 & 0xf3b9cac2fc632551), uint64(0x0)) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x3, (x9 & 0xbce6faada7179e84), uint64(uint1(x11))) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x5, x9, uint64(uint1(x13))) + var x16 uint64 + x16, _ = bits.Add64(x7, (x9 & 0xffffffff00000000), uint64(uint1(x15))) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// FromMontgomery translates a field element out of the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m +// 0 ≤ eval out1 < m +func FromMontgomery(out1 *NonMontgomeryDomainFieldElement, arg1 *MontgomeryDomainFieldElement) { + x1 := arg1[0] + var x2 uint64 + _, x2 = bits.Mul64(x1, 0xccd1c8aaee00bc4f) + var x4 uint64 + var x5 uint64 + x5, x4 = bits.Mul64(x2, 0xffffffff00000000) + var x6 uint64 + var x7 uint64 + x7, x6 = bits.Mul64(x2, 0xffffffffffffffff) + var x8 uint64 + var x9 uint64 + x9, x8 = bits.Mul64(x2, 0xbce6faada7179e84) + var x10 uint64 + var x11 uint64 + x11, x10 = bits.Mul64(x2, 0xf3b9cac2fc632551) + var x12 uint64 + var x13 uint64 + x12, x13 = bits.Add64(x11, x8, uint64(0x0)) + var x14 uint64 + var x15 uint64 + x14, x15 = bits.Add64(x9, x6, uint64(uint1(x13))) + var x16 uint64 + var x17 uint64 + x16, x17 = bits.Add64(x7, x4, uint64(uint1(x15))) + var x19 uint64 + _, x19 = bits.Add64(x1, x10, uint64(0x0)) + var x20 uint64 + var x21 uint64 + x20, x21 = bits.Add64(uint64(0x0), x12, uint64(uint1(x19))) + var x22 uint64 + var x23 uint64 + x22, x23 = bits.Add64(uint64(0x0), x14, uint64(uint1(x21))) + var x24 uint64 + var x25 uint64 + x24, x25 = bits.Add64(uint64(0x0), x16, uint64(uint1(x23))) + var x26 uint64 + var x27 uint64 + x26, x27 = bits.Add64(x20, arg1[1], uint64(0x0)) + var x28 uint64 + var x29 uint64 + x28, x29 = bits.Add64(x22, uint64(0x0), uint64(uint1(x27))) + var x30 uint64 + var x31 uint64 + x30, x31 = bits.Add64(x24, uint64(0x0), uint64(uint1(x29))) + var x32 uint64 + _, x32 = bits.Mul64(x26, 0xccd1c8aaee00bc4f) + var x34 uint64 + var x35 uint64 + x35, x34 = bits.Mul64(x32, 0xffffffff00000000) + var x36 uint64 + var x37 uint64 + x37, x36 = bits.Mul64(x32, 0xffffffffffffffff) + var x38 uint64 + var x39 uint64 + x39, x38 = bits.Mul64(x32, 0xbce6faada7179e84) + var x40 uint64 + var x41 uint64 + x41, x40 = bits.Mul64(x32, 0xf3b9cac2fc632551) + var x42 uint64 + var x43 uint64 + x42, x43 = bits.Add64(x41, x38, uint64(0x0)) + var x44 uint64 + var x45 uint64 + x44, x45 = bits.Add64(x39, x36, uint64(uint1(x43))) + var x46 uint64 + var x47 uint64 + x46, x47 = bits.Add64(x37, x34, uint64(uint1(x45))) + var x49 uint64 + _, x49 = bits.Add64(x26, x40, uint64(0x0)) + var x50 uint64 + var x51 uint64 + x50, x51 = bits.Add64(x28, x42, uint64(uint1(x49))) + var x52 uint64 + var x53 uint64 + x52, x53 = bits.Add64(x30, x44, uint64(uint1(x51))) + var x54 uint64 + var x55 uint64 + x54, x55 = bits.Add64((uint64(uint1(x31)) + (uint64(uint1(x25)) + (uint64(uint1(x17)) + x5))), x46, uint64(uint1(x53))) + var x56 uint64 + var x57 uint64 + x56, x57 = bits.Add64(x50, arg1[2], uint64(0x0)) + var x58 uint64 + var x59 uint64 + x58, x59 = bits.Add64(x52, uint64(0x0), uint64(uint1(x57))) + var x60 uint64 + var x61 uint64 + x60, x61 = bits.Add64(x54, uint64(0x0), uint64(uint1(x59))) + var x62 uint64 + _, x62 = bits.Mul64(x56, 0xccd1c8aaee00bc4f) + var x64 uint64 + var x65 uint64 + x65, x64 = bits.Mul64(x62, 0xffffffff00000000) + var x66 uint64 + var x67 uint64 + x67, x66 = bits.Mul64(x62, 0xffffffffffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x62, 0xbce6faada7179e84) + var x70 uint64 + var x71 uint64 + x71, x70 = bits.Mul64(x62, 0xf3b9cac2fc632551) + var x72 uint64 + var x73 uint64 + x72, x73 = bits.Add64(x71, x68, uint64(0x0)) + var x74 uint64 + var x75 uint64 + x74, x75 = bits.Add64(x69, x66, uint64(uint1(x73))) + var x76 uint64 + var x77 uint64 + x76, x77 = bits.Add64(x67, x64, uint64(uint1(x75))) + var x79 uint64 + _, x79 = bits.Add64(x56, x70, uint64(0x0)) + var x80 uint64 + var x81 uint64 + x80, x81 = bits.Add64(x58, x72, uint64(uint1(x79))) + var x82 uint64 + var x83 uint64 + x82, x83 = bits.Add64(x60, x74, uint64(uint1(x81))) + var x84 uint64 + var x85 uint64 + x84, x85 = bits.Add64((uint64(uint1(x61)) + (uint64(uint1(x55)) + (uint64(uint1(x47)) + x35))), x76, uint64(uint1(x83))) + var x86 uint64 + var x87 uint64 + x86, x87 = bits.Add64(x80, arg1[3], uint64(0x0)) + var x88 uint64 + var x89 uint64 + x88, x89 = bits.Add64(x82, uint64(0x0), uint64(uint1(x87))) + var x90 uint64 + var x91 uint64 + x90, x91 = bits.Add64(x84, uint64(0x0), uint64(uint1(x89))) + var x92 uint64 + _, x92 = bits.Mul64(x86, 0xccd1c8aaee00bc4f) + var x94 uint64 + var x95 uint64 + x95, x94 = bits.Mul64(x92, 0xffffffff00000000) + var x96 uint64 + var x97 uint64 + x97, x96 = bits.Mul64(x92, 0xffffffffffffffff) + var x98 uint64 + var x99 uint64 + x99, x98 = bits.Mul64(x92, 0xbce6faada7179e84) + var x100 uint64 + var x101 uint64 + x101, x100 = bits.Mul64(x92, 0xf3b9cac2fc632551) + var x102 uint64 + var x103 uint64 + x102, x103 = bits.Add64(x101, x98, uint64(0x0)) + var x104 uint64 + var x105 uint64 + x104, x105 = bits.Add64(x99, x96, uint64(uint1(x103))) + var x106 uint64 + var x107 uint64 + x106, x107 = bits.Add64(x97, x94, uint64(uint1(x105))) + var x109 uint64 + _, x109 = bits.Add64(x86, x100, uint64(0x0)) + var x110 uint64 + var x111 uint64 + x110, x111 = bits.Add64(x88, x102, uint64(uint1(x109))) + var x112 uint64 + var x113 uint64 + x112, x113 = bits.Add64(x90, x104, uint64(uint1(x111))) + var x114 uint64 + var x115 uint64 + x114, x115 = bits.Add64((uint64(uint1(x91)) + (uint64(uint1(x85)) + (uint64(uint1(x77)) + x65))), x106, uint64(uint1(x113))) + x116 := (uint64(uint1(x115)) + (uint64(uint1(x107)) + x95)) + var x117 uint64 + var x118 uint64 + x117, x118 = bits.Sub64(x110, 0xf3b9cac2fc632551, uint64(0x0)) + var x119 uint64 + var x120 uint64 + x119, x120 = bits.Sub64(x112, 0xbce6faada7179e84, uint64(uint1(x118))) + var x121 uint64 + var x122 uint64 + x121, x122 = bits.Sub64(x114, 0xffffffffffffffff, uint64(uint1(x120))) + var x123 uint64 + var x124 uint64 + x123, x124 = bits.Sub64(x116, 0xffffffff00000000, uint64(uint1(x122))) + var x126 uint64 + _, x126 = bits.Sub64(uint64(0x0), uint64(0x0), uint64(uint1(x124))) + var x127 uint64 + cmovznzU64(&x127, uint1(x126), x117, x110) + var x128 uint64 + cmovznzU64(&x128, uint1(x126), x119, x112) + var x129 uint64 + cmovznzU64(&x129, uint1(x126), x121, x114) + var x130 uint64 + cmovznzU64(&x130, uint1(x126), x123, x116) + out1[0] = x127 + out1[1] = x128 + out1[2] = x129 + out1[3] = x130 +} + +// ToMontgomery translates a field element into the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = eval arg1 mod m +// 0 ≤ eval out1 < m +func ToMontgomery(out1 *MontgomeryDomainFieldElement, arg1 *NonMontgomeryDomainFieldElement) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, 0x66e12d94f3d95620) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, 0x2845b2392b6bec59) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, 0x4699799c49bd6fa6) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, 0x83244c95be79eea2) + var x13 uint64 + var x14 uint64 + x13, x14 = bits.Add64(x12, x9, uint64(0x0)) + var x15 uint64 + var x16 uint64 + x15, x16 = bits.Add64(x10, x7, uint64(uint1(x14))) + var x17 uint64 + var x18 uint64 + x17, x18 = bits.Add64(x8, x5, uint64(uint1(x16))) + var x19 uint64 + _, x19 = bits.Mul64(x11, 0xccd1c8aaee00bc4f) + var x21 uint64 + var x22 uint64 + x22, x21 = bits.Mul64(x19, 0xffffffff00000000) + var x23 uint64 + var x24 uint64 + x24, x23 = bits.Mul64(x19, 0xffffffffffffffff) + var x25 uint64 + var x26 uint64 + x26, x25 = bits.Mul64(x19, 0xbce6faada7179e84) + var x27 uint64 + var x28 uint64 + x28, x27 = bits.Mul64(x19, 0xf3b9cac2fc632551) + var x29 uint64 + var x30 uint64 + x29, x30 = bits.Add64(x28, x25, uint64(0x0)) + var x31 uint64 + var x32 uint64 + x31, x32 = bits.Add64(x26, x23, uint64(uint1(x30))) + var x33 uint64 + var x34 uint64 + x33, x34 = bits.Add64(x24, x21, uint64(uint1(x32))) + var x36 uint64 + _, x36 = bits.Add64(x11, x27, uint64(0x0)) + var x37 uint64 + var x38 uint64 + x37, x38 = bits.Add64(x13, x29, uint64(uint1(x36))) + var x39 uint64 + var x40 uint64 + x39, x40 = bits.Add64(x15, x31, uint64(uint1(x38))) + var x41 uint64 + var x42 uint64 + x41, x42 = bits.Add64(x17, x33, uint64(uint1(x40))) + var x43 uint64 + var x44 uint64 + x43, x44 = bits.Add64((uint64(uint1(x18)) + x6), (uint64(uint1(x34)) + x22), uint64(uint1(x42))) + var x45 uint64 + var x46 uint64 + x46, x45 = bits.Mul64(x1, 0x66e12d94f3d95620) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, 0x2845b2392b6bec59) + var x49 uint64 + var x50 uint64 + x50, x49 = bits.Mul64(x1, 0x4699799c49bd6fa6) + var x51 uint64 + var x52 uint64 + x52, x51 = bits.Mul64(x1, 0x83244c95be79eea2) + var x53 uint64 + var x54 uint64 + x53, x54 = bits.Add64(x52, x49, uint64(0x0)) + var x55 uint64 + var x56 uint64 + x55, x56 = bits.Add64(x50, x47, uint64(uint1(x54))) + var x57 uint64 + var x58 uint64 + x57, x58 = bits.Add64(x48, x45, uint64(uint1(x56))) + var x59 uint64 + var x60 uint64 + x59, x60 = bits.Add64(x37, x51, uint64(0x0)) + var x61 uint64 + var x62 uint64 + x61, x62 = bits.Add64(x39, x53, uint64(uint1(x60))) + var x63 uint64 + var x64 uint64 + x63, x64 = bits.Add64(x41, x55, uint64(uint1(x62))) + var x65 uint64 + var x66 uint64 + x65, x66 = bits.Add64(x43, x57, uint64(uint1(x64))) + var x67 uint64 + _, x67 = bits.Mul64(x59, 0xccd1c8aaee00bc4f) + var x69 uint64 + var x70 uint64 + x70, x69 = bits.Mul64(x67, 0xffffffff00000000) + var x71 uint64 + var x72 uint64 + x72, x71 = bits.Mul64(x67, 0xffffffffffffffff) + var x73 uint64 + var x74 uint64 + x74, x73 = bits.Mul64(x67, 0xbce6faada7179e84) + var x75 uint64 + var x76 uint64 + x76, x75 = bits.Mul64(x67, 0xf3b9cac2fc632551) + var x77 uint64 + var x78 uint64 + x77, x78 = bits.Add64(x76, x73, uint64(0x0)) + var x79 uint64 + var x80 uint64 + x79, x80 = bits.Add64(x74, x71, uint64(uint1(x78))) + var x81 uint64 + var x82 uint64 + x81, x82 = bits.Add64(x72, x69, uint64(uint1(x80))) + var x84 uint64 + _, x84 = bits.Add64(x59, x75, uint64(0x0)) + var x85 uint64 + var x86 uint64 + x85, x86 = bits.Add64(x61, x77, uint64(uint1(x84))) + var x87 uint64 + var x88 uint64 + x87, x88 = bits.Add64(x63, x79, uint64(uint1(x86))) + var x89 uint64 + var x90 uint64 + x89, x90 = bits.Add64(x65, x81, uint64(uint1(x88))) + var x91 uint64 + var x92 uint64 + x91, x92 = bits.Add64(((uint64(uint1(x66)) + uint64(uint1(x44))) + (uint64(uint1(x58)) + x46)), (uint64(uint1(x82)) + x70), uint64(uint1(x90))) + var x93 uint64 + var x94 uint64 + x94, x93 = bits.Mul64(x2, 0x66e12d94f3d95620) + var x95 uint64 + var x96 uint64 + x96, x95 = bits.Mul64(x2, 0x2845b2392b6bec59) + var x97 uint64 + var x98 uint64 + x98, x97 = bits.Mul64(x2, 0x4699799c49bd6fa6) + var x99 uint64 + var x100 uint64 + x100, x99 = bits.Mul64(x2, 0x83244c95be79eea2) + var x101 uint64 + var x102 uint64 + x101, x102 = bits.Add64(x100, x97, uint64(0x0)) + var x103 uint64 + var x104 uint64 + x103, x104 = bits.Add64(x98, x95, uint64(uint1(x102))) + var x105 uint64 + var x106 uint64 + x105, x106 = bits.Add64(x96, x93, uint64(uint1(x104))) + var x107 uint64 + var x108 uint64 + x107, x108 = bits.Add64(x85, x99, uint64(0x0)) + var x109 uint64 + var x110 uint64 + x109, x110 = bits.Add64(x87, x101, uint64(uint1(x108))) + var x111 uint64 + var x112 uint64 + x111, x112 = bits.Add64(x89, x103, uint64(uint1(x110))) + var x113 uint64 + var x114 uint64 + x113, x114 = bits.Add64(x91, x105, uint64(uint1(x112))) + var x115 uint64 + _, x115 = bits.Mul64(x107, 0xccd1c8aaee00bc4f) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x115, 0xffffffff00000000) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x115, 0xffffffffffffffff) + var x121 uint64 + var x122 uint64 + x122, x121 = bits.Mul64(x115, 0xbce6faada7179e84) + var x123 uint64 + var x124 uint64 + x124, x123 = bits.Mul64(x115, 0xf3b9cac2fc632551) + var x125 uint64 + var x126 uint64 + x125, x126 = bits.Add64(x124, x121, uint64(0x0)) + var x127 uint64 + var x128 uint64 + x127, x128 = bits.Add64(x122, x119, uint64(uint1(x126))) + var x129 uint64 + var x130 uint64 + x129, x130 = bits.Add64(x120, x117, uint64(uint1(x128))) + var x132 uint64 + _, x132 = bits.Add64(x107, x123, uint64(0x0)) + var x133 uint64 + var x134 uint64 + x133, x134 = bits.Add64(x109, x125, uint64(uint1(x132))) + var x135 uint64 + var x136 uint64 + x135, x136 = bits.Add64(x111, x127, uint64(uint1(x134))) + var x137 uint64 + var x138 uint64 + x137, x138 = bits.Add64(x113, x129, uint64(uint1(x136))) + var x139 uint64 + var x140 uint64 + x139, x140 = bits.Add64(((uint64(uint1(x114)) + uint64(uint1(x92))) + (uint64(uint1(x106)) + x94)), (uint64(uint1(x130)) + x118), uint64(uint1(x138))) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x3, 0x66e12d94f3d95620) + var x143 uint64 + var x144 uint64 + x144, x143 = bits.Mul64(x3, 0x2845b2392b6bec59) + var x145 uint64 + var x146 uint64 + x146, x145 = bits.Mul64(x3, 0x4699799c49bd6fa6) + var x147 uint64 + var x148 uint64 + x148, x147 = bits.Mul64(x3, 0x83244c95be79eea2) + var x149 uint64 + var x150 uint64 + x149, x150 = bits.Add64(x148, x145, uint64(0x0)) + var x151 uint64 + var x152 uint64 + x151, x152 = bits.Add64(x146, x143, uint64(uint1(x150))) + var x153 uint64 + var x154 uint64 + x153, x154 = bits.Add64(x144, x141, uint64(uint1(x152))) + var x155 uint64 + var x156 uint64 + x155, x156 = bits.Add64(x133, x147, uint64(0x0)) + var x157 uint64 + var x158 uint64 + x157, x158 = bits.Add64(x135, x149, uint64(uint1(x156))) + var x159 uint64 + var x160 uint64 + x159, x160 = bits.Add64(x137, x151, uint64(uint1(x158))) + var x161 uint64 + var x162 uint64 + x161, x162 = bits.Add64(x139, x153, uint64(uint1(x160))) + var x163 uint64 + _, x163 = bits.Mul64(x155, 0xccd1c8aaee00bc4f) + var x165 uint64 + var x166 uint64 + x166, x165 = bits.Mul64(x163, 0xffffffff00000000) + var x167 uint64 + var x168 uint64 + x168, x167 = bits.Mul64(x163, 0xffffffffffffffff) + var x169 uint64 + var x170 uint64 + x170, x169 = bits.Mul64(x163, 0xbce6faada7179e84) + var x171 uint64 + var x172 uint64 + x172, x171 = bits.Mul64(x163, 0xf3b9cac2fc632551) + var x173 uint64 + var x174 uint64 + x173, x174 = bits.Add64(x172, x169, uint64(0x0)) + var x175 uint64 + var x176 uint64 + x175, x176 = bits.Add64(x170, x167, uint64(uint1(x174))) + var x177 uint64 + var x178 uint64 + x177, x178 = bits.Add64(x168, x165, uint64(uint1(x176))) + var x180 uint64 + _, x180 = bits.Add64(x155, x171, uint64(0x0)) + var x181 uint64 + var x182 uint64 + x181, x182 = bits.Add64(x157, x173, uint64(uint1(x180))) + var x183 uint64 + var x184 uint64 + x183, x184 = bits.Add64(x159, x175, uint64(uint1(x182))) + var x185 uint64 + var x186 uint64 + x185, x186 = bits.Add64(x161, x177, uint64(uint1(x184))) + var x187 uint64 + var x188 uint64 + x187, x188 = bits.Add64(((uint64(uint1(x162)) + uint64(uint1(x140))) + (uint64(uint1(x154)) + x142)), (uint64(uint1(x178)) + x166), uint64(uint1(x186))) + var x189 uint64 + var x190 uint64 + x189, x190 = bits.Sub64(x181, 0xf3b9cac2fc632551, uint64(0x0)) + var x191 uint64 + var x192 uint64 + x191, x192 = bits.Sub64(x183, 0xbce6faada7179e84, uint64(uint1(x190))) + var x193 uint64 + var x194 uint64 + x193, x194 = bits.Sub64(x185, 0xffffffffffffffff, uint64(uint1(x192))) + var x195 uint64 + var x196 uint64 + x195, x196 = bits.Sub64(x187, 0xffffffff00000000, uint64(uint1(x194))) + var x198 uint64 + _, x198 = bits.Sub64(uint64(uint1(x188)), uint64(0x0), uint64(uint1(x196))) + var x199 uint64 + cmovznzU64(&x199, uint1(x198), x189, x181) + var x200 uint64 + cmovznzU64(&x200, uint1(x198), x191, x183) + var x201 uint64 + cmovznzU64(&x201, uint1(x198), x193, x185) + var x202 uint64 + cmovznzU64(&x202, uint1(x198), x195, x187) + out1[0] = x199 + out1[1] = x200 + out1[2] = x201 + out1[3] = x202 +} + +// Nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0 +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func Nonzero(out1 *uint64, arg1 *[4]uint64) { + x1 := (arg1[0] | (arg1[1] | (arg1[2] | arg1[3]))) + *out1 = x1 +} + +// Selectznz is a multi-limb conditional select. +// +// Postconditions: +// +// eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func Selectznz(out1 *[4]uint64, arg1 uint1, arg2 *[4]uint64, arg3 *[4]uint64) { + var x1 uint64 + cmovznzU64(&x1, arg1, arg2[0], arg3[0]) + var x2 uint64 + cmovznzU64(&x2, arg1, arg2[1], arg3[1]) + var x3 uint64 + cmovznzU64(&x3, arg1, arg2[2], arg3[2]) + var x4 uint64 + cmovznzU64(&x4, arg1, arg2[3], arg3[3]) + out1[0] = x1 + out1[1] = x2 + out1[2] = x3 + out1[3] = x4 +} + +// ToBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] +func ToBytes(out1 *[32]uint8, arg1 *[4]uint64) { + x1 := arg1[3] + x2 := arg1[2] + x3 := arg1[1] + x4 := arg1[0] + x5 := (uint8(x4) & 0xff) + x6 := (x4 >> 8) + x7 := (uint8(x6) & 0xff) + x8 := (x6 >> 8) + x9 := (uint8(x8) & 0xff) + x10 := (x8 >> 8) + x11 := (uint8(x10) & 0xff) + x12 := (x10 >> 8) + x13 := (uint8(x12) & 0xff) + x14 := (x12 >> 8) + x15 := (uint8(x14) & 0xff) + x16 := (x14 >> 8) + x17 := (uint8(x16) & 0xff) + x18 := uint8((x16 >> 8)) + x19 := (uint8(x3) & 0xff) + x20 := (x3 >> 8) + x21 := (uint8(x20) & 0xff) + x22 := (x20 >> 8) + x23 := (uint8(x22) & 0xff) + x24 := (x22 >> 8) + x25 := (uint8(x24) & 0xff) + x26 := (x24 >> 8) + x27 := (uint8(x26) & 0xff) + x28 := (x26 >> 8) + x29 := (uint8(x28) & 0xff) + x30 := (x28 >> 8) + x31 := (uint8(x30) & 0xff) + x32 := uint8((x30 >> 8)) + x33 := (uint8(x2) & 0xff) + x34 := (x2 >> 8) + x35 := (uint8(x34) & 0xff) + x36 := (x34 >> 8) + x37 := (uint8(x36) & 0xff) + x38 := (x36 >> 8) + x39 := (uint8(x38) & 0xff) + x40 := (x38 >> 8) + x41 := (uint8(x40) & 0xff) + x42 := (x40 >> 8) + x43 := (uint8(x42) & 0xff) + x44 := (x42 >> 8) + x45 := (uint8(x44) & 0xff) + x46 := uint8((x44 >> 8)) + x47 := (uint8(x1) & 0xff) + x48 := (x1 >> 8) + x49 := (uint8(x48) & 0xff) + x50 := (x48 >> 8) + x51 := (uint8(x50) & 0xff) + x52 := (x50 >> 8) + x53 := (uint8(x52) & 0xff) + x54 := (x52 >> 8) + x55 := (uint8(x54) & 0xff) + x56 := (x54 >> 8) + x57 := (uint8(x56) & 0xff) + x58 := (x56 >> 8) + x59 := (uint8(x58) & 0xff) + x60 := uint8((x58 >> 8)) + out1[0] = x5 + out1[1] = x7 + out1[2] = x9 + out1[3] = x11 + out1[4] = x13 + out1[5] = x15 + out1[6] = x17 + out1[7] = x18 + out1[8] = x19 + out1[9] = x21 + out1[10] = x23 + out1[11] = x25 + out1[12] = x27 + out1[13] = x29 + out1[14] = x31 + out1[15] = x32 + out1[16] = x33 + out1[17] = x35 + out1[18] = x37 + out1[19] = x39 + out1[20] = x41 + out1[21] = x43 + out1[22] = x45 + out1[23] = x46 + out1[24] = x47 + out1[25] = x49 + out1[26] = x51 + out1[27] = x53 + out1[28] = x55 + out1[29] = x57 + out1[30] = x59 + out1[31] = x60 +} + +// FromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ bytes_eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = bytes_eval arg1 mod m +// 0 ≤ eval out1 < m +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func FromBytes(out1 *[4]uint64, arg1 *[32]uint8) { + x1 := (uint64(arg1[31]) << 56) + x2 := (uint64(arg1[30]) << 48) + x3 := (uint64(arg1[29]) << 40) + x4 := (uint64(arg1[28]) << 32) + x5 := (uint64(arg1[27]) << 24) + x6 := (uint64(arg1[26]) << 16) + x7 := (uint64(arg1[25]) << 8) + x8 := arg1[24] + x9 := (uint64(arg1[23]) << 56) + x10 := (uint64(arg1[22]) << 48) + x11 := (uint64(arg1[21]) << 40) + x12 := (uint64(arg1[20]) << 32) + x13 := (uint64(arg1[19]) << 24) + x14 := (uint64(arg1[18]) << 16) + x15 := (uint64(arg1[17]) << 8) + x16 := arg1[16] + x17 := (uint64(arg1[15]) << 56) + x18 := (uint64(arg1[14]) << 48) + x19 := (uint64(arg1[13]) << 40) + x20 := (uint64(arg1[12]) << 32) + x21 := (uint64(arg1[11]) << 24) + x22 := (uint64(arg1[10]) << 16) + x23 := (uint64(arg1[9]) << 8) + x24 := arg1[8] + x25 := (uint64(arg1[7]) << 56) + x26 := (uint64(arg1[6]) << 48) + x27 := (uint64(arg1[5]) << 40) + x28 := (uint64(arg1[4]) << 32) + x29 := (uint64(arg1[3]) << 24) + x30 := (uint64(arg1[2]) << 16) + x31 := (uint64(arg1[1]) << 8) + x32 := arg1[0] + x33 := (x31 + uint64(x32)) + x34 := (x30 + x33) + x35 := (x29 + x34) + x36 := (x28 + x35) + x37 := (x27 + x36) + x38 := (x26 + x37) + x39 := (x25 + x38) + x40 := (x23 + uint64(x24)) + x41 := (x22 + x40) + x42 := (x21 + x41) + x43 := (x20 + x42) + x44 := (x19 + x43) + x45 := (x18 + x44) + x46 := (x17 + x45) + x47 := (x15 + uint64(x16)) + x48 := (x14 + x47) + x49 := (x13 + x48) + x50 := (x12 + x49) + x51 := (x11 + x50) + x52 := (x10 + x51) + x53 := (x9 + x52) + x54 := (x7 + uint64(x8)) + x55 := (x6 + x54) + x56 := (x5 + x55) + x57 := (x4 + x56) + x58 := (x3 + x57) + x59 := (x2 + x58) + x60 := (x1 + x59) + out1[0] = x39 + out1[1] = x46 + out1[2] = x53 + out1[3] = x60 +} + +// SetOne returns the field element one in the Montgomery domain. +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = 1 mod m +// 0 ≤ eval out1 < m +func SetOne(out1 *MontgomeryDomainFieldElement) { + out1[0] = 0xc46353d039cdaaf + out1[1] = 0x4319055258e8617b + out1[2] = uint64(0x0) + out1[3] = 0xffffffff +} diff --git a/pkg/crypto/core/curves/native/p256/point.go b/pkg/crypto/core/curves/native/p256/point.go new file mode 100755 index 000000000..ddc981db9 --- /dev/null +++ b/pkg/crypto/core/curves/native/p256/point.go @@ -0,0 +1,317 @@ +package p256 + +import ( + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/p256/fp" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + p256PointInitonce sync.Once + p256PointParams native.EllipticPointParams + p256PointSswuInitOnce sync.Once + p256PointSswuParams native.SswuParams +) + +func P256PointNew() *native.EllipticPoint { + return &native.EllipticPoint{ + X: fp.P256FpNew(), + Y: fp.P256FpNew(), + Z: fp.P256FpNew(), + Params: getP256PointParams(), + Arithmetic: &p256PointArithmetic{}, + } +} + +func p256PointParamsInit() { + // How these values were derived + // left for informational purposes + // params := elliptic.P256().Params() + // a := big.NewInt(-3) + // a.Mod(a, params.P) + // capA := fp.P256FpNew().SetBigInt(a) + // capB := fp.P256FpNew().SetBigInt(params.B) + // gx := fp.P256FpNew().SetBigInt(params.Gx) + // gy := fp.P256FpNew().SetBigInt(params.Gy) + + p256PointParams = native.EllipticPointParams{ + A: fp.P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xfffffffffffffffc, 0x00000003ffffffff, 0x0000000000000000, 0xfffffffc00000004}), + B: fp.P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xd89cdf6229c4bddf, 0xacf005cd78843090, 0xe5a220abf7212ed6, 0xdc30061d04874834}), + Gx: fp.P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6}), + Gy: fp.P256FpNew().SetRaw(&[native.FieldLimbs]uint64{0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, 0x8571ff1825885d85}), + BitSize: 256, + Name: "P256", + } +} + +func getP256PointParams() *native.EllipticPointParams { + p256PointInitonce.Do(p256PointParamsInit) + return &p256PointParams +} + +func getP256PointSswuParams() *native.SswuParams { + p256PointSswuInitOnce.Do(p256PointSswuParamsInit) + return &p256PointSswuParams +} + +func p256PointSswuParamsInit() { + // How these values were derived + // left for informational purposes + //params := elliptic.P256().Params() + // + //// c1 = (q - 3) / 4 + //c1 := new(big.Int).Set(params.P) + //c1.Sub(c1, big.NewInt(3)) + //c1.Rsh(c1, 2) + // + //a := big.NewInt(-3) + //a.Mod(a, params.P) + //b := new(big.Int).Set(params.B) + //z := big.NewInt(-10) + //z.Mod(z, params.P) + //// sqrt(-Z^3) + //zTmp := new(big.Int).Exp(z, big.NewInt(3), nil) + //zTmp = zTmp.Neg(zTmp) + //zTmp.Mod(zTmp, params.P) + //c2 := new(big.Int).ModSqrt(zTmp, params.P) + // + //var capC1Bytes [32]byte + //c1.FillBytes(capC1Bytes[:]) + //capC1 := fp.P256FpNew().SetRaw(&[native.FieldLimbs]uint64{ + // binary.BigEndian.Uint64(capC1Bytes[24:]), + // binary.BigEndian.Uint64(capC1Bytes[16:24]), + // binary.BigEndian.Uint64(capC1Bytes[8:16]), + // binary.BigEndian.Uint64(capC1Bytes[:8]), + //}) + //capC2 := fp.P256FpNew().SetBigInt(c2) + //capA := fp.P256FpNew().SetBigInt(a) + //capB := fp.P256FpNew().SetBigInt(b) + //capZ := fp.P256FpNew().SetBigInt(z) + + p256PointSswuParams = native.SswuParams{ + C1: [native.FieldLimbs]uint64{0xffffffffffffffff, 0x000000003fffffff, 0x4000000000000000, 0x3fffffffc0000000}, + C2: [native.FieldLimbs]uint64{0x53e43951f64fdbe7, 0xb2806c63966a1a66, 0x1ac5d59c3298bf50, 0xa3323851ba997e27}, + A: [native.FieldLimbs]uint64{0xfffffffffffffffc, 0x00000003ffffffff, 0x0000000000000000, 0xfffffffc00000004}, + B: [native.FieldLimbs]uint64{0xd89cdf6229c4bddf, 0xacf005cd78843090, 0xe5a220abf7212ed6, 0xdc30061d04874834}, + Z: [native.FieldLimbs]uint64{0xfffffffffffffff5, 0x0000000affffffff, 0x0000000000000000, 0xfffffff50000000b}, + } +} + +type p256PointArithmetic struct{} + +func (k p256PointArithmetic) Hash(out *native.EllipticPoint, hash *native.EllipticPointHasher, msg, dst []byte) error { + var u []byte + sswuParams := getP256PointSswuParams() + + switch hash.Type() { + case native.XMD: + u = native.ExpandMsgXmd(hash, msg, dst, 96) + case native.XOF: + u = native.ExpandMsgXof(hash, msg, dst, 96) + } + var buf [64]byte + copy(buf[:48], internal.ReverseScalarBytes(u[:48])) + u0 := fp.P256FpNew().SetBytesWide(&buf) + copy(buf[:48], internal.ReverseScalarBytes(u[48:])) + u1 := fp.P256FpNew().SetBytesWide(&buf) + + q0x, q0y := sswuParams.Osswu3mod4(u0) + q1x, q1y := sswuParams.Osswu3mod4(u1) + out.X = q0x + out.Y = q0y + out.Z.SetOne() + tv := &native.EllipticPoint{ + X: q1x, + Y: q1y, + Z: fp.P256FpNew().SetOne(), + } + k.Add(out, out, tv) + return nil +} + +func (k p256PointArithmetic) Double(out, arg *native.EllipticPoint) { + // Addition formula from Renes-Costello-Batina 2015 + // (https://eprint.iacr.org/2015/1060 Algorithm 6) + var xx, yy, zz, xy2, yz2, xz2, bzz, bzz3 [native.FieldLimbs]uint64 + var yyMBzz3, yyPBzz3, yFrag, xFrag, zz3 [native.FieldLimbs]uint64 + var bxz2, bxz6, xx3Mzz3, x, y, z [native.FieldLimbs]uint64 + b := getP256PointParams().B.Value + f := arg.X.Arithmetic + + f.Square(&xx, &arg.X.Value) + f.Square(&yy, &arg.Y.Value) + f.Square(&zz, &arg.Z.Value) + + f.Mul(&xy2, &arg.X.Value, &arg.Y.Value) + f.Add(&xy2, &xy2, &xy2) + + f.Mul(&yz2, &arg.Y.Value, &arg.Z.Value) + f.Add(&yz2, &yz2, &yz2) + + f.Mul(&xz2, &arg.X.Value, &arg.Z.Value) + f.Add(&xz2, &xz2, &xz2) + + f.Mul(&bzz, &b, &zz) + f.Sub(&bzz, &bzz, &xz2) + + f.Add(&bzz3, &bzz, &bzz) + f.Add(&bzz3, &bzz3, &bzz) + + f.Sub(&yyMBzz3, &yy, &bzz3) + f.Add(&yyPBzz3, &yy, &bzz3) + f.Mul(&yFrag, &yyPBzz3, &yyMBzz3) + f.Mul(&xFrag, &yyMBzz3, &xy2) + + f.Add(&zz3, &zz, &zz) + f.Add(&zz3, &zz3, &zz) + + f.Mul(&bxz2, &b, &xz2) + f.Sub(&bxz2, &bxz2, &zz3) + f.Sub(&bxz2, &bxz2, &xx) + + f.Add(&bxz6, &bxz2, &bxz2) + f.Add(&bxz6, &bxz6, &bxz2) + + f.Add(&xx3Mzz3, &xx, &xx) + f.Add(&xx3Mzz3, &xx3Mzz3, &xx) + f.Sub(&xx3Mzz3, &xx3Mzz3, &zz3) + + f.Mul(&x, &bxz6, &yz2) + f.Sub(&x, &xFrag, &x) + + f.Mul(&y, &xx3Mzz3, &bxz6) + f.Add(&y, &yFrag, &y) + + f.Mul(&z, &yz2, &yy) + f.Add(&z, &z, &z) + f.Add(&z, &z, &z) + + out.X.Value = x + out.Y.Value = y + out.Z.Value = z +} + +func (k p256PointArithmetic) Add(out, arg1, arg2 *native.EllipticPoint) { + // Addition formula from Renes-Costello-Batina 2015 + // (https://eprint.iacr.org/2015/1060 Algorithm 4). + var xx, yy, zz, zz3, bxz, bxz3 [native.FieldLimbs]uint64 + var tv1, xyPairs, yzPairs, xzPairs [native.FieldLimbs]uint64 + var bzz, bzz3, yyMBzz3, yyPBzz3 [native.FieldLimbs]uint64 + var xx3Mzz3, x, y, z [native.FieldLimbs]uint64 + f := arg1.X.Arithmetic + b := getP256PointParams().B.Value + + f.Mul(&xx, &arg1.X.Value, &arg2.X.Value) + f.Mul(&yy, &arg1.Y.Value, &arg2.Y.Value) + f.Mul(&zz, &arg1.Z.Value, &arg2.Z.Value) + + f.Add(&tv1, &arg2.X.Value, &arg2.Y.Value) + f.Add(&xyPairs, &arg1.X.Value, &arg1.Y.Value) + f.Mul(&xyPairs, &xyPairs, &tv1) + f.Sub(&xyPairs, &xyPairs, &xx) + f.Sub(&xyPairs, &xyPairs, &yy) + + f.Add(&tv1, &arg2.Y.Value, &arg2.Z.Value) + f.Add(&yzPairs, &arg1.Y.Value, &arg1.Z.Value) + f.Mul(&yzPairs, &yzPairs, &tv1) + f.Sub(&yzPairs, &yzPairs, &yy) + f.Sub(&yzPairs, &yzPairs, &zz) + + f.Add(&tv1, &arg2.X.Value, &arg2.Z.Value) + f.Add(&xzPairs, &arg1.X.Value, &arg1.Z.Value) + f.Mul(&xzPairs, &xzPairs, &tv1) + f.Sub(&xzPairs, &xzPairs, &xx) + f.Sub(&xzPairs, &xzPairs, &zz) + + f.Mul(&bzz, &b, &zz) + f.Sub(&bzz, &xzPairs, &bzz) + + f.Add(&bzz3, &bzz, &bzz) + f.Add(&bzz3, &bzz3, &bzz) + + f.Sub(&yyMBzz3, &yy, &bzz3) + f.Add(&yyPBzz3, &yy, &bzz3) + + f.Add(&zz3, &zz, &zz) + f.Add(&zz3, &zz3, &zz) + + f.Mul(&bxz, &b, &xzPairs) + f.Sub(&bxz, &bxz, &zz3) + f.Sub(&bxz, &bxz, &xx) + + f.Add(&bxz3, &bxz, &bxz) + f.Add(&bxz3, &bxz3, &bxz) + + f.Add(&xx3Mzz3, &xx, &xx) + f.Add(&xx3Mzz3, &xx3Mzz3, &xx) + f.Sub(&xx3Mzz3, &xx3Mzz3, &zz3) + + f.Mul(&tv1, &yzPairs, &bxz3) + f.Mul(&x, &yyPBzz3, &xyPairs) + f.Sub(&x, &x, &tv1) + + f.Mul(&tv1, &xx3Mzz3, &bxz3) + f.Mul(&y, &yyPBzz3, &yyMBzz3) + f.Add(&y, &y, &tv1) + + f.Mul(&tv1, &xyPairs, &xx3Mzz3) + f.Mul(&z, &yyMBzz3, &yzPairs) + f.Add(&z, &z, &tv1) + + e1 := arg1.Z.IsZero() + e2 := arg2.Z.IsZero() + + // If arg1 is identity set it to arg2 + f.Selectznz(&z, &z, &arg2.Z.Value, e1) + f.Selectznz(&y, &y, &arg2.Y.Value, e1) + f.Selectznz(&x, &x, &arg2.X.Value, e1) + // If arg2 is identity set it to arg1 + f.Selectznz(&z, &z, &arg1.Z.Value, e2) + f.Selectznz(&y, &y, &arg1.Y.Value, e2) + f.Selectznz(&x, &x, &arg1.X.Value, e2) + + out.X.Value = x + out.Y.Value = y + out.Z.Value = z +} + +func (k p256PointArithmetic) IsOnCurve(arg *native.EllipticPoint) bool { + affine := P256PointNew() + k.ToAffine(affine, arg) + lhs := fp.P256FpNew().Square(affine.Y) + rhs := fp.P256FpNew() + k.RhsEq(rhs, affine.X) + return lhs.Equal(rhs) == 1 +} + +func (k p256PointArithmetic) ToAffine(out, arg *native.EllipticPoint) { + var wasInverted int + var zero, x, y, z [native.FieldLimbs]uint64 + f := arg.X.Arithmetic + + f.Invert(&wasInverted, &z, &arg.Z.Value) + f.Mul(&x, &arg.X.Value, &z) + f.Mul(&y, &arg.Y.Value, &z) + + out.Z.SetOne() + // If point at infinity this does nothing + f.Selectznz(&x, &zero, &x, wasInverted) + f.Selectznz(&y, &zero, &y, wasInverted) + f.Selectznz(&z, &zero, &out.Z.Value, wasInverted) + + out.X.Value = x + out.Y.Value = y + out.Z.Value = z + out.Params = arg.Params + out.Arithmetic = arg.Arithmetic +} + +func (k p256PointArithmetic) RhsEq(out, x *native.Field) { + // Elliptic curve equation for p256 is: y^2 = x^3 ax + b + out.Square(x) + out.Mul(out, x) + out.Add(out, getP256PointParams().B) + out.Add(out, fp.P256FpNew().Mul(getP256PointParams().A, x)) +} diff --git a/pkg/crypto/core/curves/native/p256/point_test.go b/pkg/crypto/core/curves/native/p256/point_test.go new file mode 100755 index 000000000..650e39492 --- /dev/null +++ b/pkg/crypto/core/curves/native/p256/point_test.go @@ -0,0 +1,38 @@ +package p256_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/p256" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/p256/fp" +) + +func TestP256PointArithmetic_Double(t *testing.T) { + g := p256.P256PointNew().Generator() + pt1 := p256.P256PointNew().Double(g) + pt2 := p256.P256PointNew().Add(g, g) + pt3 := p256.P256PointNew().Mul(g, fp.P256FpNew().SetUint64(2)) + + e1 := pt1.Equal(pt2) + e2 := pt1.Equal(pt3) + e3 := pt2.Equal(pt3) + require.Equal(t, 1, e1) + require.Equal(t, 1, e2) + require.Equal(t, 1, e3) +} + +func TestP256PointArithmetic_Hash(t *testing.T) { + var b [32]byte + sc, err := p256.P256PointNew().Hash(b[:], native.EllipticPointHasherSha256()) + sc1 := curves.P256().NewIdentityPoint().Hash(b[:]) + fmt.Printf("%v\n", sc1) + + require.NoError(t, err) + require.True(t, !sc.IsIdentity()) + require.True(t, sc.IsOnCurve()) +} diff --git a/pkg/crypto/core/curves/native/pasta/README.md b/pkg/crypto/core/curves/native/pasta/README.md new file mode 100755 index 000000000..e0785f20f --- /dev/null +++ b/pkg/crypto/core/curves/native/pasta/README.md @@ -0,0 +1,10 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## Pallas and Pasta Curve diff --git a/pkg/crypto/core/curves/native/pasta/fp/fp.go b/pkg/crypto/core/curves/native/pasta/fp/fp.go new file mode 100755 index 000000000..25b3045c2 --- /dev/null +++ b/pkg/crypto/core/curves/native/pasta/fp/fp.go @@ -0,0 +1,369 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fp + +import ( + "encoding/binary" + "fmt" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +type Fp fiat_pasta_fp_montgomery_domain_field_element + +// r = 2^256 mod p +var r = &Fp{0x34786d38fffffffd, 0x992c350be41914ad, 0xffffffffffffffff, 0x3fffffffffffffff} + +// r2 = 2^512 mod p +var r2 = &Fp{0x8c78ecb30000000f, 0xd7d30dbd8b0de0e7, 0x7797a99bc3c95d18, 0x096d41af7b9cb714} + +// r3 = 2^768 mod p +var r3 = &Fp{0xf185a5993a9e10f9, 0xf6a68f3b6ac5b1d1, 0xdf8d1014353fd42c, 0x2ae309222d2d9910} + +// generator = 5 mod p is a generator of the `p - 1` order multiplicative +// subgroup, or in other words a primitive element of the field. +var generator = &Fp{0xa1a55e68ffffffed, 0x74c2a54b4f4982f3, 0xfffffffffffffffd, 0x3fffffffffffffff} + +var s = 32 + +// modulus representation +// p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 +var modulus = &Fp{0x992d30ed00000001, 0x224698fc094cf91b, 0x0000000000000000, 0x4000000000000000} + +var biModulus = new(big.Int).SetBytes([]byte{ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x46, 0x98, 0xfc, 0x09, 0x4c, 0xf9, 0x1b, + 0x99, 0x2d, 0x30, 0xed, 0x00, 0x00, 0x00, 0x01, +}) + +// Cmp returns -1 if fp < rhs +// 0 if fp == rhs +// 1 if fp > rhs +func (fp *Fp) Cmp(rhs *Fp) int { + gt := 0 + lt := 0 + for i := len(fp) - 1; i >= 0; i-- { + gt |= int((rhs[i]-fp[i])>>63) &^ lt + lt |= int((fp[i]-rhs[i])>>63) &^ gt + } + return gt - lt +} + +// Equal returns true if fp == rhs +func (fp *Fp) Equal(rhs *Fp) bool { + t := fp[0] ^ rhs[0] + t |= fp[1] ^ rhs[1] + t |= fp[2] ^ rhs[2] + t |= fp[3] ^ rhs[3] + return t == 0 +} + +// IsZero returns true if fp == 0 +func (fp *Fp) IsZero() bool { + t := fp[0] + t |= fp[1] + t |= fp[2] + t |= fp[3] + return t == 0 +} + +// IsOne returns true if fp == R +func (fp *Fp) IsOne() bool { + return fp.Equal(r) +} + +func (fp *Fp) IsOdd() bool { + tv := new(fiat_pasta_fp_non_montgomery_domain_field_element) + fiat_pasta_fp_from_montgomery(tv, (*fiat_pasta_fp_montgomery_domain_field_element)(fp)) + return tv[0]&0x01 == 0x01 +} + +// Set fp == rhs +func (fp *Fp) Set(rhs *Fp) *Fp { + fp[0] = rhs[0] + fp[1] = rhs[1] + fp[2] = rhs[2] + fp[3] = rhs[3] + return fp +} + +// SetUint64 sets fp == rhs +func (fp *Fp) SetUint64(rhs uint64) *Fp { + r := &fiat_pasta_fp_non_montgomery_domain_field_element{rhs, 0, 0, 0} + fiat_pasta_fp_to_montgomery((*fiat_pasta_fp_montgomery_domain_field_element)(fp), r) + return fp +} + +func (fp *Fp) SetBool(rhs bool) *Fp { + if rhs { + fp.SetOne() + } else { + fp.SetZero() + } + return fp +} + +// SetOne fp == R +func (fp *Fp) SetOne() *Fp { + return fp.Set(r) +} + +// SetZero fp == 0 +func (fp *Fp) SetZero() *Fp { + fp[0] = 0 + fp[1] = 0 + fp[2] = 0 + fp[3] = 0 + return fp +} + +// SetBytesWide takes 64 bytes as input and treats them as a 512-bit number. +// Attributed to https://github.com/zcash/pasta_curves/blob/main/src/fields/fp.rs#L255 +// We reduce an arbitrary 512-bit number by decomposing it into two 256-bit digits +// with the higher bits multiplied by 2^256. Thus, we perform two reductions +// +// 1. the lower bits are multiplied by R^2, as normal +// 2. the upper bits are multiplied by R^2 * 2^256 = R^3 +// +// and computing their sum in the field. It remains to see that arbitrary 256-bit +// numbers can be placed into Montgomery form safely using the reduction. The +// reduction works so long as the product is less than R=2^256 multiplied by +// the modulus. This holds because for any `c` smaller than the modulus, we have +// that (2^256 - 1)*c is an acceptable product for the reduction. Therefore, the +// reduction always works so long as `c` is in the field; in this case it is either the +// constant `r2` or `r3`. +func (fp *Fp) SetBytesWide(input *[64]byte) *Fp { + d0 := fiat_pasta_fp_montgomery_domain_field_element{ + binary.LittleEndian.Uint64(input[:8]), + binary.LittleEndian.Uint64(input[8:16]), + binary.LittleEndian.Uint64(input[16:24]), + binary.LittleEndian.Uint64(input[24:32]), + } + d1 := fiat_pasta_fp_montgomery_domain_field_element{ + binary.LittleEndian.Uint64(input[32:40]), + binary.LittleEndian.Uint64(input[40:48]), + binary.LittleEndian.Uint64(input[48:56]), + binary.LittleEndian.Uint64(input[56:64]), + } + // Convert to Montgomery form + tv1 := new(fiat_pasta_fp_montgomery_domain_field_element) + tv2 := new(fiat_pasta_fp_montgomery_domain_field_element) + // d0 * r2 + d1 * r3 + fiat_pasta_fp_mul(tv1, &d0, (*fiat_pasta_fp_montgomery_domain_field_element)(r2)) + fiat_pasta_fp_mul(tv2, &d1, (*fiat_pasta_fp_montgomery_domain_field_element)(r3)) + fiat_pasta_fp_add((*fiat_pasta_fp_montgomery_domain_field_element)(fp), tv1, tv2) + return fp +} + +// SetBytes attempts to convert a little endian byte representation +// of a scalar into a `Fp`, failing if input is not canonical +func (fp *Fp) SetBytes(input *[32]byte) (*Fp, error) { + d0 := &Fp{ + binary.LittleEndian.Uint64(input[:8]), + binary.LittleEndian.Uint64(input[8:16]), + binary.LittleEndian.Uint64(input[16:24]), + binary.LittleEndian.Uint64(input[24:32]), + } + if d0.Cmp(modulus) != -1 { + return nil, fmt.Errorf("invalid byte sequence") + } + fiat_pasta_fp_from_bytes((*[4]uint64)(fp), input) + fiat_pasta_fp_to_montgomery((*fiat_pasta_fp_montgomery_domain_field_element)(fp), (*fiat_pasta_fp_non_montgomery_domain_field_element)(fp)) + return fp, nil +} + +// SetBigInt initializes an element from big.Int +// The value is reduced by the modulus +func (fp *Fp) SetBigInt(bi *big.Int) *Fp { + var buffer [32]byte + r := new(big.Int).Set(bi) + r.Mod(r, biModulus) + r.FillBytes(buffer[:]) + copy(buffer[:], internal.ReverseScalarBytes(buffer[:])) + _, _ = fp.SetBytes(&buffer) + return fp +} + +// SetRaw converts a raw array into a field element +func (fp *Fp) SetRaw(array *[4]uint64) *Fp { + fiat_pasta_fp_to_montgomery((*fiat_pasta_fp_montgomery_domain_field_element)(fp), (*fiat_pasta_fp_non_montgomery_domain_field_element)(array)) + return fp +} + +// Bytes converts this element into a byte representation +// in little endian byte order +func (fp *Fp) Bytes() [32]byte { + var output [32]byte + tv := new(fiat_pasta_fp_non_montgomery_domain_field_element) + fiat_pasta_fp_from_montgomery(tv, (*fiat_pasta_fp_montgomery_domain_field_element)(fp)) + fiat_pasta_fp_to_bytes(&output, (*[4]uint64)(tv)) + return output +} + +// BigInt converts this element into the big.Int struct +func (fp *Fp) BigInt() *big.Int { + buffer := fp.Bytes() + return new(big.Int).SetBytes(internal.ReverseScalarBytes(buffer[:])) +} + +// Double this element +func (fp *Fp) Double(elem *Fp) *Fp { + delem := (*fiat_pasta_fp_montgomery_domain_field_element)(elem) + fiat_pasta_fp_add((*fiat_pasta_fp_montgomery_domain_field_element)(fp), delem, delem) + return fp +} + +// Square this element +func (fp *Fp) Square(elem *Fp) *Fp { + delem := (*fiat_pasta_fp_montgomery_domain_field_element)(elem) + fiat_pasta_fp_square((*fiat_pasta_fp_montgomery_domain_field_element)(fp), delem) + return fp +} + +// Sqrt this element, if it exists. If true, then value +// is a square root. If false, value is a QNR +func (fp *Fp) Sqrt(elem *Fp) (*Fp, bool) { + return fp.tonelliShanks(elem) +} + +// See sqrt_ts_ct at +// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-I.4 +func (fp *Fp) tonelliShanks(elem *Fp) (*Fp, bool) { + // c1 := 32 + // c2 := (q - 1) / (2^c1) + // c2 := [4]uint64{ + // 0x094cf91b992d30ed, + // 0x00000000224698fc, + // 0x0000000000000000, + // 0x0000000040000000, + // } + // c3 := (c2 - 1) / 2 + c3 := [4]uint64{ + 0x04a67c8dcc969876, + 0x0000000011234c7e, + 0x0000000000000000, + 0x0000000020000000, + } + // c4 := generator + // c5 := new(Fp).pow(&generator, c2) + c5 := &Fp{ + 0xa28db849bad6dbf0, + 0x9083cd03d3b539df, + 0xfba6b9ca9dc8448e, + 0x3ec928747b89c6da, + } + + z := new(Fp).pow(elem, c3) + t := new(Fp).Square(z) + t.Mul(t, elem) + + z.Mul(z, elem) + + b := new(Fp).Set(t) + c := new(Fp).Set(c5) + flags := map[bool]int{ + true: 1, + false: 0, + } + + for i := s; i >= 2; i-- { + for j := 1; j <= i-2; j++ { + b.Square(b) + } + z.CMove(z, new(Fp).Mul(z, c), flags[!b.IsOne()]) + c.Square(c) + t.CMove(t, new(Fp).Mul(t, c), flags[!b.IsOne()]) + b.Set(t) + } + wasSquare := c.Square(z).Equal(elem) + return fp.Set(z), wasSquare +} + +// Invert this element i.e. compute the multiplicative inverse +// return false, zero if this element is zero +func (fp *Fp) Invert(elem *Fp) (*Fp, bool) { + // computes elem^(p - 2) mod p + exp := [4]uint64{ + 0x992d30ecffffffff, + 0x224698fc094cf91b, + 0x0000000000000000, + 0x4000000000000000, + } + return fp.pow(elem, exp), !elem.IsZero() +} + +// Mul returns the result from multiplying this element by rhs +func (fp *Fp) Mul(lhs, rhs *Fp) *Fp { + dlhs := (*fiat_pasta_fp_montgomery_domain_field_element)(lhs) + drhs := (*fiat_pasta_fp_montgomery_domain_field_element)(rhs) + fiat_pasta_fp_mul((*fiat_pasta_fp_montgomery_domain_field_element)(fp), dlhs, drhs) + return fp +} + +// Sub returns the result from subtracting rhs from this element +func (fp *Fp) Sub(lhs, rhs *Fp) *Fp { + dlhs := (*fiat_pasta_fp_montgomery_domain_field_element)(lhs) + drhs := (*fiat_pasta_fp_montgomery_domain_field_element)(rhs) + fiat_pasta_fp_sub((*fiat_pasta_fp_montgomery_domain_field_element)(fp), dlhs, drhs) + return fp +} + +// Add returns the result from adding rhs to this element +func (fp *Fp) Add(lhs, rhs *Fp) *Fp { + dlhs := (*fiat_pasta_fp_montgomery_domain_field_element)(lhs) + drhs := (*fiat_pasta_fp_montgomery_domain_field_element)(rhs) + fiat_pasta_fp_add((*fiat_pasta_fp_montgomery_domain_field_element)(fp), dlhs, drhs) + return fp +} + +// Neg returns negation of this element +func (fp *Fp) Neg(elem *Fp) *Fp { + delem := (*fiat_pasta_fp_montgomery_domain_field_element)(elem) + fiat_pasta_fp_opp((*fiat_pasta_fp_montgomery_domain_field_element)(fp), delem) + return fp +} + +// Exp exponentiates this element by exp +func (fp *Fp) Exp(base, exp *Fp) *Fp { + // convert exponent to integer form + tv := &fiat_pasta_fp_non_montgomery_domain_field_element{} + fiat_pasta_fp_from_montgomery(tv, (*fiat_pasta_fp_montgomery_domain_field_element)(exp)) + + e := (*[4]uint64)(tv) + return fp.pow(base, *e) +} + +func (fp *Fp) pow(base *Fp, exp [4]uint64) *Fp { + res := new(Fp).SetOne() + tmp := new(Fp) + + for i := len(exp) - 1; i >= 0; i-- { + for j := 63; j >= 0; j-- { + res.Square(res) + tmp.Mul(res, base) + res.CMove(res, tmp, int(exp[i]>>j)&1) + } + } + return fp.Set(res) +} + +// CMove selects lhs if choice == 0 and rhs if choice == 1 +func (fp *Fp) CMove(lhs, rhs *Fp, choice int) *Fp { + dlhs := (*[4]uint64)(lhs) + drhs := (*[4]uint64)(rhs) + fiat_pasta_fp_selectznz((*[4]uint64)(fp), fiat_pasta_fp_uint1(choice), dlhs, drhs) + return fp +} + +// ToRaw converts this element into the a [4]uint64 +func (fp *Fp) ToRaw() [4]uint64 { + res := &fiat_pasta_fp_non_montgomery_domain_field_element{} + fiat_pasta_fp_from_montgomery(res, (*fiat_pasta_fp_montgomery_domain_field_element)(fp)) + return *(*[4]uint64)(res) +} diff --git a/pkg/crypto/core/curves/native/pasta/fp/fp_test.go b/pkg/crypto/core/curves/native/pasta/fp/fp_test.go new file mode 100755 index 000000000..c2fefb0e1 --- /dev/null +++ b/pkg/crypto/core/curves/native/pasta/fp/fp_test.go @@ -0,0 +1,249 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fp + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFpSetOne(t *testing.T) { + fp := new(Fp).SetOne() + require.NotNil(t, fp) + require.True(t, fp.Equal(r)) +} + +func TestFpSetUint64(t *testing.T) { + act := new(Fp).SetUint64(1 << 60) + require.NotNil(t, act) + // Remember it will be in montgomery form + require.Equal(t, int(act[0]), 0x592d30ed00000001) +} + +func TestFpAdd(t *testing.T) { + lhs := new(Fp).SetOne() + rhs := new(Fp).SetOne() + exp := new(Fp).SetUint64(2) + res := new(Fp).Add(lhs, rhs) + require.NotNil(t, res) + require.True(t, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + e := l + r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := new(Fp).Add(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpSub(t *testing.T) { + lhs := new(Fp).SetOne() + rhs := new(Fp).SetOne() + exp := new(Fp).SetZero() + res := new(Fp).Sub(lhs, rhs) + require.NotNil(t, res) + require.True(t, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + if l < r { + l, r = r, l + } + e := l - r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := new(Fp).Sub(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpMul(t *testing.T) { + lhs := new(Fp).SetOne() + rhs := new(Fp).SetOne() + exp := new(Fp).SetOne() + res := new(Fp).Mul(lhs, rhs) + require.NotNil(t, res) + require.True(t, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint32() + r := rand.Uint32() + e := uint64(l) * uint64(r) + lhs.SetUint64(uint64(l)) + rhs.SetUint64(uint64(r)) + exp.SetUint64(e) + + a := new(Fp).Mul(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFpDouble(t *testing.T) { + a := new(Fp).SetUint64(2) + e := new(Fp).SetUint64(4) + require.Equal(t, e, new(Fp).Double(a)) + + for i := 0; i < 25; i++ { + tv := rand.Uint32() + ttv := uint64(tv) * 2 + a = new(Fp).SetUint64(uint64(tv)) + e = new(Fp).SetUint64(ttv) + require.Equal(t, e, new(Fp).Double(a)) + } +} + +func TestFpSquare(t *testing.T) { + a := new(Fp).SetUint64(4) + e := new(Fp).SetUint64(16) + require.Equal(t, e, a.Square(a)) + + for i := 0; i < 25; i++ { + j := rand.Uint32() + exp := uint64(j) * uint64(j) + e.SetUint64(exp) + a.SetUint64(uint64(j)) + require.Equal(t, e, a.Square(a)) + } +} + +func TestFpNeg(t *testing.T) { + a := new(Fp).SetOne() + a.Neg(a) + e := &Fp{7256640077462241284, 9879318615658062958, 0, 0} + require.Equal(t, e, a) + a.Neg(generator) + e = &Fp{0xf787d28400000014, 0xad83f3b0ba037627, 0x2, 0x0} + require.Equal(t, e, a) +} + +func TestFpExp(t *testing.T) { + e := new(Fp).SetUint64(8) + a := new(Fp).SetUint64(2) + by := new(Fp).SetUint64(3) + require.Equal(t, e, a.Exp(a, by)) +} + +func TestFpSqrt(t *testing.T) { + t1 := new(Fp).SetUint64(2) + t2 := new(Fp).Neg(t1) + t3 := new(Fp).Square(t1) + _, wasSquare := t3.Sqrt(t3) + require.True(t, wasSquare) + require.True(t, t1.Equal(t3) || t2.Equal(t3)) + t1.SetUint64(5) + _, wasSquare = new(Fp).Sqrt(t1) + require.False(t, wasSquare) +} + +func TestFpInvert(t *testing.T) { + twoInv := &Fp{0xcc96987680000001, 0x11234c7e04a67c8d, 0x0000000000000000, 0x2000000000000000} + fiat_pasta_fp_to_montgomery((*fiat_pasta_fp_montgomery_domain_field_element)(twoInv), (*fiat_pasta_fp_non_montgomery_domain_field_element)(twoInv)) + two := new(Fp).SetUint64(2) + a, inverted := new(Fp).Invert(two) + require.True(t, inverted) + require.Equal(t, a, twoInv) + + rootOfUnity := &Fp{0xbdad6fabd87ea32f, 0xea322bf2b7bb7584, 0x362120830561f81a, 0x2bce74deac30ebda} + fiat_pasta_fp_to_montgomery((*fiat_pasta_fp_montgomery_domain_field_element)(rootOfUnity), (*fiat_pasta_fp_non_montgomery_domain_field_element)(rootOfUnity)) + rootOfUnityInv := &Fp{0xf0b87c7db2ce91f6, 0x84a0a1d8859f066f, 0xb4ed8e647196dad1, 0x2cd5282c53116b5c} + fiat_pasta_fp_to_montgomery((*fiat_pasta_fp_montgomery_domain_field_element)(rootOfUnityInv), (*fiat_pasta_fp_non_montgomery_domain_field_element)(rootOfUnityInv)) + a, inverted = new(Fp).Invert(rootOfUnity) + require.True(t, inverted) + require.Equal(t, a, rootOfUnityInv) + + lhs := new(Fp).SetUint64(9) + rhs := new(Fp).SetUint64(3) + rhsInv, inverted := new(Fp).Invert(rhs) + require.True(t, inverted) + require.Equal(t, rhs, new(Fp).Mul(lhs, rhsInv)) + + rhs.SetZero() + _, inverted = new(Fp).Invert(rhs) + require.False(t, inverted) +} + +func TestFpCMove(t *testing.T) { + t1 := new(Fp).SetUint64(5) + t2 := new(Fp).SetUint64(10) + require.Equal(t, t1, new(Fp).CMove(t1, t2, 0)) + require.Equal(t, t2, new(Fp).CMove(t1, t2, 1)) +} + +func TestFpBytes(t *testing.T) { + t1 := new(Fp).SetUint64(99) + seq := t1.Bytes() + t2, err := new(Fp).SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + + for i := 0; i < 25; i++ { + t1.SetUint64(rand.Uint64()) + seq = t1.Bytes() + _, err = t2.SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + } +} + +func TestFpBigInt(t *testing.T) { + t1 := new(Fp).SetBigInt(big.NewInt(9999)) + t2 := new(Fp).SetBigInt(t1.BigInt()) + require.Equal(t, t1, t2) + + e := &Fp{0x8c6bc70550c87761, 0xce2c6c48e7063731, 0xf1275fd1e4607cd6, 0x3e6762e63501edbd} + b := new(big.Int).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}) + t1.SetBigInt(b) + require.Equal(t, e, t1) + e[0] = 0xcc169e7af3788a0 + e[1] = 0x541a2cb32246c1ea + e[2] = 0xed8a02e1b9f8329 + e[3] = 0x1989d19cafe1242 + b.Neg(b) + t1.SetBigInt(b) + require.Equal(t, e, t1) +} + +func TestFpSetBool(t *testing.T) { + require.Equal(t, new(Fp).SetOne(), new(Fp).SetBool(true)) + require.Equal(t, new(Fp).SetZero(), new(Fp).SetBool(false)) +} + +func TestFpSetBytesWide(t *testing.T) { + e := &Fp{0x3daec14d565241d9, 0x0b7af45b6073944b, 0xea5b8bd611a5bd4c, 0x150160330625db3d} + fiat_pasta_fp_to_montgomery((*fiat_pasta_fp_montgomery_domain_field_element)(e), (*fiat_pasta_fp_non_montgomery_domain_field_element)(e)) + a := new(Fp).SetBytesWide(&[64]byte{ + 0xa1, 0x78, 0x76, 0x29, 0x41, 0x56, 0x15, 0xee, + 0x65, 0xbe, 0xfd, 0xdb, 0x6b, 0x15, 0x3e, 0xd8, + 0xb5, 0xa0, 0x8b, 0xc6, 0x34, 0xd8, 0xcc, 0xd9, + 0x58, 0x27, 0x27, 0x12, 0xe3, 0xed, 0x08, 0xf5, + 0x89, 0x8e, 0x22, 0xf8, 0xcb, 0xf7, 0x8d, 0x03, + 0x41, 0x4b, 0xc7, 0xa3, 0xe4, 0xa1, 0x05, 0x35, + 0xb3, 0x2d, 0xb8, 0x5e, 0x77, 0x6f, 0xa4, 0xbf, + 0x1d, 0x47, 0x2f, 0x26, 0x7e, 0xe2, 0xeb, 0x26, + }) + require.Equal(t, e, a) +} diff --git a/pkg/crypto/core/curves/native/pasta/fp/pasta_fp.go b/pkg/crypto/core/curves/native/pasta/fp/pasta_fp.go new file mode 100755 index 000000000..88a5bdc6f --- /dev/null +++ b/pkg/crypto/core/curves/native/pasta/fp/pasta_fp.go @@ -0,0 +1,1467 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Autogenerated: './src/ExtractionOCaml/word_by_word_montgomery' --lang Go pasta_fp 64 '2^254 + 45560315531419706090280762371685220353' +// +// curve description: pasta_fp +// +// machine_wordsize = 64 (from "64") +// +// requested operations: (all) +// +// m = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 (from "2^254 + 45560315531419706090280762371685220353") +// +// +// +// NOTE: In addition to the bounds specified above each function, all +// +// functions synthesized for this Montgomery arithmetic require the +// +// input to be strictly less than the prime modulus (m), and also +// +// require the input to be in the unique saturated representation. +// +// All functions also ensure that these two properties are true of +// +// return values. +// +// +// +// Computed values: +// +// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) +// +// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) +// +// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in +// +// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 + +package fp + +import "math/bits" + +type fiat_pasta_fp_uint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 +type fiat_pasta_fp_int1 int64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 + +// The type fiat_pasta_fp_montgomery_domain_field_element is a field element in the Montgomery domain. +// +// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type fiat_pasta_fp_montgomery_domain_field_element [4]uint64 + +// The type fiat_pasta_fp_non_montgomery_domain_field_element is a field element NOT in the Montgomery domain. +// +// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type fiat_pasta_fp_non_montgomery_domain_field_element [4]uint64 + +// The function fiat_pasta_fp_addcarryx_u64 is a thin wrapper around bits.Add64 that uses fiat_pasta_fp_uint1 rather than uint64 +func fiat_pasta_fp_addcarryx_u64(x uint64, y uint64, carry fiat_pasta_fp_uint1) (uint64, fiat_pasta_fp_uint1) { + sum, carryOut := bits.Add64(x, y, uint64(carry)) + return sum, fiat_pasta_fp_uint1(carryOut) +} + +// The function fiat_pasta_fp_subborrowx_u64 is a thin wrapper around bits.Sub64 that uses fiat_pasta_fp_uint1 rather than uint64 +func fiat_pasta_fp_subborrowx_u64(x uint64, y uint64, carry fiat_pasta_fp_uint1) (uint64, fiat_pasta_fp_uint1) { + sum, carryOut := bits.Sub64(x, y, uint64(carry)) + return sum, fiat_pasta_fp_uint1(carryOut) +} + +// The function fiat_pasta_fp_cmovznz_u64 is a single-word conditional move. +// +// Postconditions: +// +// out1 = (if arg1 = 0 then arg2 else arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [0x0 ~> 0xffffffffffffffff] +// arg3: [0x0 ~> 0xffffffffffffffff] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func fiat_pasta_fp_cmovznz_u64(out1 *uint64, arg1 fiat_pasta_fp_uint1, arg2 uint64, arg3 uint64) { + x1 := arg1 + x2 := (uint64((fiat_pasta_fp_int1(0x0) - fiat_pasta_fp_int1(x1))) & 0xffffffffffffffff) + x3 := ((x2 & arg3) | ((^x2) & arg2)) + *out1 = x3 +} + +// The function fiat_pasta_fp_mul multiplies two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fp_mul(out1 *fiat_pasta_fp_montgomery_domain_field_element, arg1 *fiat_pasta_fp_montgomery_domain_field_element, arg2 *fiat_pasta_fp_montgomery_domain_field_element) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg2[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg2[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg2[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg2[0]) + var x13 uint64 + var x14 fiat_pasta_fp_uint1 + x13, x14 = fiat_pasta_fp_addcarryx_u64(x12, x9, 0x0) + var x15 uint64 + var x16 fiat_pasta_fp_uint1 + x15, x16 = fiat_pasta_fp_addcarryx_u64(x10, x7, x14) + var x17 uint64 + var x18 fiat_pasta_fp_uint1 + x17, x18 = fiat_pasta_fp_addcarryx_u64(x8, x5, x16) + x19 := (uint64(x18) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0x992d30ecffffffff) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0x4000000000000000) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0x224698fc094cf91b) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0x992d30ed00000001) + var x28 uint64 + var x29 fiat_pasta_fp_uint1 + x28, x29 = fiat_pasta_fp_addcarryx_u64(x27, x24, 0x0) + x30 := (uint64(x29) + x25) + var x32 fiat_pasta_fp_uint1 + _, x32 = fiat_pasta_fp_addcarryx_u64(x11, x26, 0x0) + var x33 uint64 + var x34 fiat_pasta_fp_uint1 + x33, x34 = fiat_pasta_fp_addcarryx_u64(x13, x28, x32) + var x35 uint64 + var x36 fiat_pasta_fp_uint1 + x35, x36 = fiat_pasta_fp_addcarryx_u64(x15, x30, x34) + var x37 uint64 + var x38 fiat_pasta_fp_uint1 + x37, x38 = fiat_pasta_fp_addcarryx_u64(x17, x22, x36) + var x39 uint64 + var x40 fiat_pasta_fp_uint1 + x39, x40 = fiat_pasta_fp_addcarryx_u64(x19, x23, x38) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, arg2[3]) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, arg2[2]) + var x45 uint64 + var x46 uint64 + x46, x45 = bits.Mul64(x1, arg2[1]) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg2[0]) + var x49 uint64 + var x50 fiat_pasta_fp_uint1 + x49, x50 = fiat_pasta_fp_addcarryx_u64(x48, x45, 0x0) + var x51 uint64 + var x52 fiat_pasta_fp_uint1 + x51, x52 = fiat_pasta_fp_addcarryx_u64(x46, x43, x50) + var x53 uint64 + var x54 fiat_pasta_fp_uint1 + x53, x54 = fiat_pasta_fp_addcarryx_u64(x44, x41, x52) + x55 := (uint64(x54) + x42) + var x56 uint64 + var x57 fiat_pasta_fp_uint1 + x56, x57 = fiat_pasta_fp_addcarryx_u64(x33, x47, 0x0) + var x58 uint64 + var x59 fiat_pasta_fp_uint1 + x58, x59 = fiat_pasta_fp_addcarryx_u64(x35, x49, x57) + var x60 uint64 + var x61 fiat_pasta_fp_uint1 + x60, x61 = fiat_pasta_fp_addcarryx_u64(x37, x51, x59) + var x62 uint64 + var x63 fiat_pasta_fp_uint1 + x62, x63 = fiat_pasta_fp_addcarryx_u64(x39, x53, x61) + var x64 uint64 + var x65 fiat_pasta_fp_uint1 + x64, x65 = fiat_pasta_fp_addcarryx_u64(uint64(x40), x55, x63) + var x66 uint64 + _, x66 = bits.Mul64(x56, 0x992d30ecffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x66, 0x4000000000000000) + var x70 uint64 + var x71 uint64 + x71, x70 = bits.Mul64(x66, 0x224698fc094cf91b) + var x72 uint64 + var x73 uint64 + x73, x72 = bits.Mul64(x66, 0x992d30ed00000001) + var x74 uint64 + var x75 fiat_pasta_fp_uint1 + x74, x75 = fiat_pasta_fp_addcarryx_u64(x73, x70, 0x0) + x76 := (uint64(x75) + x71) + var x78 fiat_pasta_fp_uint1 + _, x78 = fiat_pasta_fp_addcarryx_u64(x56, x72, 0x0) + var x79 uint64 + var x80 fiat_pasta_fp_uint1 + x79, x80 = fiat_pasta_fp_addcarryx_u64(x58, x74, x78) + var x81 uint64 + var x82 fiat_pasta_fp_uint1 + x81, x82 = fiat_pasta_fp_addcarryx_u64(x60, x76, x80) + var x83 uint64 + var x84 fiat_pasta_fp_uint1 + x83, x84 = fiat_pasta_fp_addcarryx_u64(x62, x68, x82) + var x85 uint64 + var x86 fiat_pasta_fp_uint1 + x85, x86 = fiat_pasta_fp_addcarryx_u64(x64, x69, x84) + x87 := (uint64(x86) + uint64(x65)) + var x88 uint64 + var x89 uint64 + x89, x88 = bits.Mul64(x2, arg2[3]) + var x90 uint64 + var x91 uint64 + x91, x90 = bits.Mul64(x2, arg2[2]) + var x92 uint64 + var x93 uint64 + x93, x92 = bits.Mul64(x2, arg2[1]) + var x94 uint64 + var x95 uint64 + x95, x94 = bits.Mul64(x2, arg2[0]) + var x96 uint64 + var x97 fiat_pasta_fp_uint1 + x96, x97 = fiat_pasta_fp_addcarryx_u64(x95, x92, 0x0) + var x98 uint64 + var x99 fiat_pasta_fp_uint1 + x98, x99 = fiat_pasta_fp_addcarryx_u64(x93, x90, x97) + var x100 uint64 + var x101 fiat_pasta_fp_uint1 + x100, x101 = fiat_pasta_fp_addcarryx_u64(x91, x88, x99) + x102 := (uint64(x101) + x89) + var x103 uint64 + var x104 fiat_pasta_fp_uint1 + x103, x104 = fiat_pasta_fp_addcarryx_u64(x79, x94, 0x0) + var x105 uint64 + var x106 fiat_pasta_fp_uint1 + x105, x106 = fiat_pasta_fp_addcarryx_u64(x81, x96, x104) + var x107 uint64 + var x108 fiat_pasta_fp_uint1 + x107, x108 = fiat_pasta_fp_addcarryx_u64(x83, x98, x106) + var x109 uint64 + var x110 fiat_pasta_fp_uint1 + x109, x110 = fiat_pasta_fp_addcarryx_u64(x85, x100, x108) + var x111 uint64 + var x112 fiat_pasta_fp_uint1 + x111, x112 = fiat_pasta_fp_addcarryx_u64(x87, x102, x110) + var x113 uint64 + _, x113 = bits.Mul64(x103, 0x992d30ecffffffff) + var x115 uint64 + var x116 uint64 + x116, x115 = bits.Mul64(x113, 0x4000000000000000) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x113, 0x224698fc094cf91b) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x113, 0x992d30ed00000001) + var x121 uint64 + var x122 fiat_pasta_fp_uint1 + x121, x122 = fiat_pasta_fp_addcarryx_u64(x120, x117, 0x0) + x123 := (uint64(x122) + x118) + var x125 fiat_pasta_fp_uint1 + _, x125 = fiat_pasta_fp_addcarryx_u64(x103, x119, 0x0) + var x126 uint64 + var x127 fiat_pasta_fp_uint1 + x126, x127 = fiat_pasta_fp_addcarryx_u64(x105, x121, x125) + var x128 uint64 + var x129 fiat_pasta_fp_uint1 + x128, x129 = fiat_pasta_fp_addcarryx_u64(x107, x123, x127) + var x130 uint64 + var x131 fiat_pasta_fp_uint1 + x130, x131 = fiat_pasta_fp_addcarryx_u64(x109, x115, x129) + var x132 uint64 + var x133 fiat_pasta_fp_uint1 + x132, x133 = fiat_pasta_fp_addcarryx_u64(x111, x116, x131) + x134 := (uint64(x133) + uint64(x112)) + var x135 uint64 + var x136 uint64 + x136, x135 = bits.Mul64(x3, arg2[3]) + var x137 uint64 + var x138 uint64 + x138, x137 = bits.Mul64(x3, arg2[2]) + var x139 uint64 + var x140 uint64 + x140, x139 = bits.Mul64(x3, arg2[1]) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x3, arg2[0]) + var x143 uint64 + var x144 fiat_pasta_fp_uint1 + x143, x144 = fiat_pasta_fp_addcarryx_u64(x142, x139, 0x0) + var x145 uint64 + var x146 fiat_pasta_fp_uint1 + x145, x146 = fiat_pasta_fp_addcarryx_u64(x140, x137, x144) + var x147 uint64 + var x148 fiat_pasta_fp_uint1 + x147, x148 = fiat_pasta_fp_addcarryx_u64(x138, x135, x146) + x149 := (uint64(x148) + x136) + var x150 uint64 + var x151 fiat_pasta_fp_uint1 + x150, x151 = fiat_pasta_fp_addcarryx_u64(x126, x141, 0x0) + var x152 uint64 + var x153 fiat_pasta_fp_uint1 + x152, x153 = fiat_pasta_fp_addcarryx_u64(x128, x143, x151) + var x154 uint64 + var x155 fiat_pasta_fp_uint1 + x154, x155 = fiat_pasta_fp_addcarryx_u64(x130, x145, x153) + var x156 uint64 + var x157 fiat_pasta_fp_uint1 + x156, x157 = fiat_pasta_fp_addcarryx_u64(x132, x147, x155) + var x158 uint64 + var x159 fiat_pasta_fp_uint1 + x158, x159 = fiat_pasta_fp_addcarryx_u64(x134, x149, x157) + var x160 uint64 + _, x160 = bits.Mul64(x150, 0x992d30ecffffffff) + var x162 uint64 + var x163 uint64 + x163, x162 = bits.Mul64(x160, 0x4000000000000000) + var x164 uint64 + var x165 uint64 + x165, x164 = bits.Mul64(x160, 0x224698fc094cf91b) + var x166 uint64 + var x167 uint64 + x167, x166 = bits.Mul64(x160, 0x992d30ed00000001) + var x168 uint64 + var x169 fiat_pasta_fp_uint1 + x168, x169 = fiat_pasta_fp_addcarryx_u64(x167, x164, 0x0) + x170 := (uint64(x169) + x165) + var x172 fiat_pasta_fp_uint1 + _, x172 = fiat_pasta_fp_addcarryx_u64(x150, x166, 0x0) + var x173 uint64 + var x174 fiat_pasta_fp_uint1 + x173, x174 = fiat_pasta_fp_addcarryx_u64(x152, x168, x172) + var x175 uint64 + var x176 fiat_pasta_fp_uint1 + x175, x176 = fiat_pasta_fp_addcarryx_u64(x154, x170, x174) + var x177 uint64 + var x178 fiat_pasta_fp_uint1 + x177, x178 = fiat_pasta_fp_addcarryx_u64(x156, x162, x176) + var x179 uint64 + var x180 fiat_pasta_fp_uint1 + x179, x180 = fiat_pasta_fp_addcarryx_u64(x158, x163, x178) + x181 := (uint64(x180) + uint64(x159)) + var x182 uint64 + var x183 fiat_pasta_fp_uint1 + x182, x183 = fiat_pasta_fp_subborrowx_u64(x173, 0x992d30ed00000001, 0x0) + var x184 uint64 + var x185 fiat_pasta_fp_uint1 + x184, x185 = fiat_pasta_fp_subborrowx_u64(x175, 0x224698fc094cf91b, x183) + var x186 uint64 + var x187 fiat_pasta_fp_uint1 + x186, x187 = fiat_pasta_fp_subborrowx_u64(x177, uint64(0x0), x185) + var x188 uint64 + var x189 fiat_pasta_fp_uint1 + x188, x189 = fiat_pasta_fp_subborrowx_u64(x179, 0x4000000000000000, x187) + var x191 fiat_pasta_fp_uint1 + _, x191 = fiat_pasta_fp_subborrowx_u64(x181, uint64(0x0), x189) + var x192 uint64 + fiat_pasta_fp_cmovznz_u64(&x192, x191, x182, x173) + var x193 uint64 + fiat_pasta_fp_cmovznz_u64(&x193, x191, x184, x175) + var x194 uint64 + fiat_pasta_fp_cmovznz_u64(&x194, x191, x186, x177) + var x195 uint64 + fiat_pasta_fp_cmovznz_u64(&x195, x191, x188, x179) + out1[0] = x192 + out1[1] = x193 + out1[2] = x194 + out1[3] = x195 +} + +// The function fiat_pasta_fp_square squares a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fp_square(out1 *fiat_pasta_fp_montgomery_domain_field_element, arg1 *fiat_pasta_fp_montgomery_domain_field_element) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg1[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg1[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg1[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg1[0]) + var x13 uint64 + var x14 fiat_pasta_fp_uint1 + x13, x14 = fiat_pasta_fp_addcarryx_u64(x12, x9, 0x0) + var x15 uint64 + var x16 fiat_pasta_fp_uint1 + x15, x16 = fiat_pasta_fp_addcarryx_u64(x10, x7, x14) + var x17 uint64 + var x18 fiat_pasta_fp_uint1 + x17, x18 = fiat_pasta_fp_addcarryx_u64(x8, x5, x16) + x19 := (uint64(x18) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0x992d30ecffffffff) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0x4000000000000000) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0x224698fc094cf91b) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0x992d30ed00000001) + var x28 uint64 + var x29 fiat_pasta_fp_uint1 + x28, x29 = fiat_pasta_fp_addcarryx_u64(x27, x24, 0x0) + x30 := (uint64(x29) + x25) + var x32 fiat_pasta_fp_uint1 + _, x32 = fiat_pasta_fp_addcarryx_u64(x11, x26, 0x0) + var x33 uint64 + var x34 fiat_pasta_fp_uint1 + x33, x34 = fiat_pasta_fp_addcarryx_u64(x13, x28, x32) + var x35 uint64 + var x36 fiat_pasta_fp_uint1 + x35, x36 = fiat_pasta_fp_addcarryx_u64(x15, x30, x34) + var x37 uint64 + var x38 fiat_pasta_fp_uint1 + x37, x38 = fiat_pasta_fp_addcarryx_u64(x17, x22, x36) + var x39 uint64 + var x40 fiat_pasta_fp_uint1 + x39, x40 = fiat_pasta_fp_addcarryx_u64(x19, x23, x38) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, arg1[3]) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, arg1[2]) + var x45 uint64 + var x46 uint64 + x46, x45 = bits.Mul64(x1, arg1[1]) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg1[0]) + var x49 uint64 + var x50 fiat_pasta_fp_uint1 + x49, x50 = fiat_pasta_fp_addcarryx_u64(x48, x45, 0x0) + var x51 uint64 + var x52 fiat_pasta_fp_uint1 + x51, x52 = fiat_pasta_fp_addcarryx_u64(x46, x43, x50) + var x53 uint64 + var x54 fiat_pasta_fp_uint1 + x53, x54 = fiat_pasta_fp_addcarryx_u64(x44, x41, x52) + x55 := (uint64(x54) + x42) + var x56 uint64 + var x57 fiat_pasta_fp_uint1 + x56, x57 = fiat_pasta_fp_addcarryx_u64(x33, x47, 0x0) + var x58 uint64 + var x59 fiat_pasta_fp_uint1 + x58, x59 = fiat_pasta_fp_addcarryx_u64(x35, x49, x57) + var x60 uint64 + var x61 fiat_pasta_fp_uint1 + x60, x61 = fiat_pasta_fp_addcarryx_u64(x37, x51, x59) + var x62 uint64 + var x63 fiat_pasta_fp_uint1 + x62, x63 = fiat_pasta_fp_addcarryx_u64(x39, x53, x61) + var x64 uint64 + var x65 fiat_pasta_fp_uint1 + x64, x65 = fiat_pasta_fp_addcarryx_u64(uint64(x40), x55, x63) + var x66 uint64 + _, x66 = bits.Mul64(x56, 0x992d30ecffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x66, 0x4000000000000000) + var x70 uint64 + var x71 uint64 + x71, x70 = bits.Mul64(x66, 0x224698fc094cf91b) + var x72 uint64 + var x73 uint64 + x73, x72 = bits.Mul64(x66, 0x992d30ed00000001) + var x74 uint64 + var x75 fiat_pasta_fp_uint1 + x74, x75 = fiat_pasta_fp_addcarryx_u64(x73, x70, 0x0) + x76 := (uint64(x75) + x71) + var x78 fiat_pasta_fp_uint1 + _, x78 = fiat_pasta_fp_addcarryx_u64(x56, x72, 0x0) + var x79 uint64 + var x80 fiat_pasta_fp_uint1 + x79, x80 = fiat_pasta_fp_addcarryx_u64(x58, x74, x78) + var x81 uint64 + var x82 fiat_pasta_fp_uint1 + x81, x82 = fiat_pasta_fp_addcarryx_u64(x60, x76, x80) + var x83 uint64 + var x84 fiat_pasta_fp_uint1 + x83, x84 = fiat_pasta_fp_addcarryx_u64(x62, x68, x82) + var x85 uint64 + var x86 fiat_pasta_fp_uint1 + x85, x86 = fiat_pasta_fp_addcarryx_u64(x64, x69, x84) + x87 := (uint64(x86) + uint64(x65)) + var x88 uint64 + var x89 uint64 + x89, x88 = bits.Mul64(x2, arg1[3]) + var x90 uint64 + var x91 uint64 + x91, x90 = bits.Mul64(x2, arg1[2]) + var x92 uint64 + var x93 uint64 + x93, x92 = bits.Mul64(x2, arg1[1]) + var x94 uint64 + var x95 uint64 + x95, x94 = bits.Mul64(x2, arg1[0]) + var x96 uint64 + var x97 fiat_pasta_fp_uint1 + x96, x97 = fiat_pasta_fp_addcarryx_u64(x95, x92, 0x0) + var x98 uint64 + var x99 fiat_pasta_fp_uint1 + x98, x99 = fiat_pasta_fp_addcarryx_u64(x93, x90, x97) + var x100 uint64 + var x101 fiat_pasta_fp_uint1 + x100, x101 = fiat_pasta_fp_addcarryx_u64(x91, x88, x99) + x102 := (uint64(x101) + x89) + var x103 uint64 + var x104 fiat_pasta_fp_uint1 + x103, x104 = fiat_pasta_fp_addcarryx_u64(x79, x94, 0x0) + var x105 uint64 + var x106 fiat_pasta_fp_uint1 + x105, x106 = fiat_pasta_fp_addcarryx_u64(x81, x96, x104) + var x107 uint64 + var x108 fiat_pasta_fp_uint1 + x107, x108 = fiat_pasta_fp_addcarryx_u64(x83, x98, x106) + var x109 uint64 + var x110 fiat_pasta_fp_uint1 + x109, x110 = fiat_pasta_fp_addcarryx_u64(x85, x100, x108) + var x111 uint64 + var x112 fiat_pasta_fp_uint1 + x111, x112 = fiat_pasta_fp_addcarryx_u64(x87, x102, x110) + var x113 uint64 + _, x113 = bits.Mul64(x103, 0x992d30ecffffffff) + var x115 uint64 + var x116 uint64 + x116, x115 = bits.Mul64(x113, 0x4000000000000000) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x113, 0x224698fc094cf91b) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x113, 0x992d30ed00000001) + var x121 uint64 + var x122 fiat_pasta_fp_uint1 + x121, x122 = fiat_pasta_fp_addcarryx_u64(x120, x117, 0x0) + x123 := (uint64(x122) + x118) + var x125 fiat_pasta_fp_uint1 + _, x125 = fiat_pasta_fp_addcarryx_u64(x103, x119, 0x0) + var x126 uint64 + var x127 fiat_pasta_fp_uint1 + x126, x127 = fiat_pasta_fp_addcarryx_u64(x105, x121, x125) + var x128 uint64 + var x129 fiat_pasta_fp_uint1 + x128, x129 = fiat_pasta_fp_addcarryx_u64(x107, x123, x127) + var x130 uint64 + var x131 fiat_pasta_fp_uint1 + x130, x131 = fiat_pasta_fp_addcarryx_u64(x109, x115, x129) + var x132 uint64 + var x133 fiat_pasta_fp_uint1 + x132, x133 = fiat_pasta_fp_addcarryx_u64(x111, x116, x131) + x134 := (uint64(x133) + uint64(x112)) + var x135 uint64 + var x136 uint64 + x136, x135 = bits.Mul64(x3, arg1[3]) + var x137 uint64 + var x138 uint64 + x138, x137 = bits.Mul64(x3, arg1[2]) + var x139 uint64 + var x140 uint64 + x140, x139 = bits.Mul64(x3, arg1[1]) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x3, arg1[0]) + var x143 uint64 + var x144 fiat_pasta_fp_uint1 + x143, x144 = fiat_pasta_fp_addcarryx_u64(x142, x139, 0x0) + var x145 uint64 + var x146 fiat_pasta_fp_uint1 + x145, x146 = fiat_pasta_fp_addcarryx_u64(x140, x137, x144) + var x147 uint64 + var x148 fiat_pasta_fp_uint1 + x147, x148 = fiat_pasta_fp_addcarryx_u64(x138, x135, x146) + x149 := (uint64(x148) + x136) + var x150 uint64 + var x151 fiat_pasta_fp_uint1 + x150, x151 = fiat_pasta_fp_addcarryx_u64(x126, x141, 0x0) + var x152 uint64 + var x153 fiat_pasta_fp_uint1 + x152, x153 = fiat_pasta_fp_addcarryx_u64(x128, x143, x151) + var x154 uint64 + var x155 fiat_pasta_fp_uint1 + x154, x155 = fiat_pasta_fp_addcarryx_u64(x130, x145, x153) + var x156 uint64 + var x157 fiat_pasta_fp_uint1 + x156, x157 = fiat_pasta_fp_addcarryx_u64(x132, x147, x155) + var x158 uint64 + var x159 fiat_pasta_fp_uint1 + x158, x159 = fiat_pasta_fp_addcarryx_u64(x134, x149, x157) + var x160 uint64 + _, x160 = bits.Mul64(x150, 0x992d30ecffffffff) + var x162 uint64 + var x163 uint64 + x163, x162 = bits.Mul64(x160, 0x4000000000000000) + var x164 uint64 + var x165 uint64 + x165, x164 = bits.Mul64(x160, 0x224698fc094cf91b) + var x166 uint64 + var x167 uint64 + x167, x166 = bits.Mul64(x160, 0x992d30ed00000001) + var x168 uint64 + var x169 fiat_pasta_fp_uint1 + x168, x169 = fiat_pasta_fp_addcarryx_u64(x167, x164, 0x0) + x170 := (uint64(x169) + x165) + var x172 fiat_pasta_fp_uint1 + _, x172 = fiat_pasta_fp_addcarryx_u64(x150, x166, 0x0) + var x173 uint64 + var x174 fiat_pasta_fp_uint1 + x173, x174 = fiat_pasta_fp_addcarryx_u64(x152, x168, x172) + var x175 uint64 + var x176 fiat_pasta_fp_uint1 + x175, x176 = fiat_pasta_fp_addcarryx_u64(x154, x170, x174) + var x177 uint64 + var x178 fiat_pasta_fp_uint1 + x177, x178 = fiat_pasta_fp_addcarryx_u64(x156, x162, x176) + var x179 uint64 + var x180 fiat_pasta_fp_uint1 + x179, x180 = fiat_pasta_fp_addcarryx_u64(x158, x163, x178) + x181 := (uint64(x180) + uint64(x159)) + var x182 uint64 + var x183 fiat_pasta_fp_uint1 + x182, x183 = fiat_pasta_fp_subborrowx_u64(x173, 0x992d30ed00000001, 0x0) + var x184 uint64 + var x185 fiat_pasta_fp_uint1 + x184, x185 = fiat_pasta_fp_subborrowx_u64(x175, 0x224698fc094cf91b, x183) + var x186 uint64 + var x187 fiat_pasta_fp_uint1 + x186, x187 = fiat_pasta_fp_subborrowx_u64(x177, uint64(0x0), x185) + var x188 uint64 + var x189 fiat_pasta_fp_uint1 + x188, x189 = fiat_pasta_fp_subborrowx_u64(x179, 0x4000000000000000, x187) + var x191 fiat_pasta_fp_uint1 + _, x191 = fiat_pasta_fp_subborrowx_u64(x181, uint64(0x0), x189) + var x192 uint64 + fiat_pasta_fp_cmovznz_u64(&x192, x191, x182, x173) + var x193 uint64 + fiat_pasta_fp_cmovznz_u64(&x193, x191, x184, x175) + var x194 uint64 + fiat_pasta_fp_cmovznz_u64(&x194, x191, x186, x177) + var x195 uint64 + fiat_pasta_fp_cmovznz_u64(&x195, x191, x188, x179) + out1[0] = x192 + out1[1] = x193 + out1[2] = x194 + out1[3] = x195 +} + +// The function fiat_pasta_fp_add adds two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fp_add(out1 *fiat_pasta_fp_montgomery_domain_field_element, arg1 *fiat_pasta_fp_montgomery_domain_field_element, arg2 *fiat_pasta_fp_montgomery_domain_field_element) { + var x1 uint64 + var x2 fiat_pasta_fp_uint1 + x1, x2 = fiat_pasta_fp_addcarryx_u64(arg1[0], arg2[0], 0x0) + var x3 uint64 + var x4 fiat_pasta_fp_uint1 + x3, x4 = fiat_pasta_fp_addcarryx_u64(arg1[1], arg2[1], x2) + var x5 uint64 + var x6 fiat_pasta_fp_uint1 + x5, x6 = fiat_pasta_fp_addcarryx_u64(arg1[2], arg2[2], x4) + var x7 uint64 + var x8 fiat_pasta_fp_uint1 + x7, x8 = fiat_pasta_fp_addcarryx_u64(arg1[3], arg2[3], x6) + var x9 uint64 + var x10 fiat_pasta_fp_uint1 + x9, x10 = fiat_pasta_fp_subborrowx_u64(x1, 0x992d30ed00000001, 0x0) + var x11 uint64 + var x12 fiat_pasta_fp_uint1 + x11, x12 = fiat_pasta_fp_subborrowx_u64(x3, 0x224698fc094cf91b, x10) + var x13 uint64 + var x14 fiat_pasta_fp_uint1 + x13, x14 = fiat_pasta_fp_subborrowx_u64(x5, uint64(0x0), x12) + var x15 uint64 + var x16 fiat_pasta_fp_uint1 + x15, x16 = fiat_pasta_fp_subborrowx_u64(x7, 0x4000000000000000, x14) + var x18 fiat_pasta_fp_uint1 + _, x18 = fiat_pasta_fp_subborrowx_u64(uint64(x8), uint64(0x0), x16) + var x19 uint64 + fiat_pasta_fp_cmovznz_u64(&x19, x18, x9, x1) + var x20 uint64 + fiat_pasta_fp_cmovznz_u64(&x20, x18, x11, x3) + var x21 uint64 + fiat_pasta_fp_cmovznz_u64(&x21, x18, x13, x5) + var x22 uint64 + fiat_pasta_fp_cmovznz_u64(&x22, x18, x15, x7) + out1[0] = x19 + out1[1] = x20 + out1[2] = x21 + out1[3] = x22 +} + +// The function fiat_pasta_fp_sub subtracts two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fp_sub(out1 *fiat_pasta_fp_montgomery_domain_field_element, arg1 *fiat_pasta_fp_montgomery_domain_field_element, arg2 *fiat_pasta_fp_montgomery_domain_field_element) { + var x1 uint64 + var x2 fiat_pasta_fp_uint1 + x1, x2 = fiat_pasta_fp_subborrowx_u64(arg1[0], arg2[0], 0x0) + var x3 uint64 + var x4 fiat_pasta_fp_uint1 + x3, x4 = fiat_pasta_fp_subborrowx_u64(arg1[1], arg2[1], x2) + var x5 uint64 + var x6 fiat_pasta_fp_uint1 + x5, x6 = fiat_pasta_fp_subborrowx_u64(arg1[2], arg2[2], x4) + var x7 uint64 + var x8 fiat_pasta_fp_uint1 + x7, x8 = fiat_pasta_fp_subborrowx_u64(arg1[3], arg2[3], x6) + var x9 uint64 + fiat_pasta_fp_cmovznz_u64(&x9, x8, uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 fiat_pasta_fp_uint1 + x10, x11 = fiat_pasta_fp_addcarryx_u64(x1, (x9 & 0x992d30ed00000001), 0x0) + var x12 uint64 + var x13 fiat_pasta_fp_uint1 + x12, x13 = fiat_pasta_fp_addcarryx_u64(x3, (x9 & 0x224698fc094cf91b), x11) + var x14 uint64 + var x15 fiat_pasta_fp_uint1 + x14, x15 = fiat_pasta_fp_addcarryx_u64(x5, uint64(0x0), x13) + var x16 uint64 + x16, _ = fiat_pasta_fp_addcarryx_u64(x7, (x9 & 0x4000000000000000), x15) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// The function fiat_pasta_fp_opp negates a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fp_opp(out1 *fiat_pasta_fp_montgomery_domain_field_element, arg1 *fiat_pasta_fp_montgomery_domain_field_element) { + var x1 uint64 + var x2 fiat_pasta_fp_uint1 + x1, x2 = fiat_pasta_fp_subborrowx_u64(uint64(0x0), arg1[0], 0x0) + var x3 uint64 + var x4 fiat_pasta_fp_uint1 + x3, x4 = fiat_pasta_fp_subborrowx_u64(uint64(0x0), arg1[1], x2) + var x5 uint64 + var x6 fiat_pasta_fp_uint1 + x5, x6 = fiat_pasta_fp_subborrowx_u64(uint64(0x0), arg1[2], x4) + var x7 uint64 + var x8 fiat_pasta_fp_uint1 + x7, x8 = fiat_pasta_fp_subborrowx_u64(uint64(0x0), arg1[3], x6) + var x9 uint64 + fiat_pasta_fp_cmovznz_u64(&x9, x8, uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 fiat_pasta_fp_uint1 + x10, x11 = fiat_pasta_fp_addcarryx_u64(x1, (x9 & 0x992d30ed00000001), 0x0) + var x12 uint64 + var x13 fiat_pasta_fp_uint1 + x12, x13 = fiat_pasta_fp_addcarryx_u64(x3, (x9 & 0x224698fc094cf91b), x11) + var x14 uint64 + var x15 fiat_pasta_fp_uint1 + x14, x15 = fiat_pasta_fp_addcarryx_u64(x5, uint64(0x0), x13) + var x16 uint64 + x16, _ = fiat_pasta_fp_addcarryx_u64(x7, (x9 & 0x4000000000000000), x15) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// The function fiat_pasta_fp_from_montgomery translates a field element out of the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fp_from_montgomery(out1 *fiat_pasta_fp_non_montgomery_domain_field_element, arg1 *fiat_pasta_fp_montgomery_domain_field_element) { + x1 := arg1[0] + var x2 uint64 + _, x2 = bits.Mul64(x1, 0x992d30ecffffffff) + var x4 uint64 + var x5 uint64 + x5, x4 = bits.Mul64(x2, 0x4000000000000000) + var x6 uint64 + var x7 uint64 + x7, x6 = bits.Mul64(x2, 0x224698fc094cf91b) + var x8 uint64 + var x9 uint64 + x9, x8 = bits.Mul64(x2, 0x992d30ed00000001) + var x10 uint64 + var x11 fiat_pasta_fp_uint1 + x10, x11 = fiat_pasta_fp_addcarryx_u64(x9, x6, 0x0) + var x13 fiat_pasta_fp_uint1 + _, x13 = fiat_pasta_fp_addcarryx_u64(x1, x8, 0x0) + var x14 uint64 + var x15 fiat_pasta_fp_uint1 + x14, x15 = fiat_pasta_fp_addcarryx_u64(uint64(0x0), x10, x13) + var x16 uint64 + var x17 fiat_pasta_fp_uint1 + x16, x17 = fiat_pasta_fp_addcarryx_u64(x14, arg1[1], 0x0) + var x18 uint64 + _, x18 = bits.Mul64(x16, 0x992d30ecffffffff) + var x20 uint64 + var x21 uint64 + x21, x20 = bits.Mul64(x18, 0x4000000000000000) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x18, 0x224698fc094cf91b) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x18, 0x992d30ed00000001) + var x26 uint64 + var x27 fiat_pasta_fp_uint1 + x26, x27 = fiat_pasta_fp_addcarryx_u64(x25, x22, 0x0) + var x29 fiat_pasta_fp_uint1 + _, x29 = fiat_pasta_fp_addcarryx_u64(x16, x24, 0x0) + var x30 uint64 + var x31 fiat_pasta_fp_uint1 + x30, x31 = fiat_pasta_fp_addcarryx_u64((uint64(x17) + (uint64(x15) + (uint64(x11) + x7))), x26, x29) + var x32 uint64 + var x33 fiat_pasta_fp_uint1 + x32, x33 = fiat_pasta_fp_addcarryx_u64(x4, (uint64(x27) + x23), x31) + var x34 uint64 + var x35 fiat_pasta_fp_uint1 + x34, x35 = fiat_pasta_fp_addcarryx_u64(x5, x20, x33) + var x36 uint64 + var x37 fiat_pasta_fp_uint1 + x36, x37 = fiat_pasta_fp_addcarryx_u64(x30, arg1[2], 0x0) + var x38 uint64 + var x39 fiat_pasta_fp_uint1 + x38, x39 = fiat_pasta_fp_addcarryx_u64(x32, uint64(0x0), x37) + var x40 uint64 + var x41 fiat_pasta_fp_uint1 + x40, x41 = fiat_pasta_fp_addcarryx_u64(x34, uint64(0x0), x39) + var x42 uint64 + _, x42 = bits.Mul64(x36, 0x992d30ecffffffff) + var x44 uint64 + var x45 uint64 + x45, x44 = bits.Mul64(x42, 0x4000000000000000) + var x46 uint64 + var x47 uint64 + x47, x46 = bits.Mul64(x42, 0x224698fc094cf91b) + var x48 uint64 + var x49 uint64 + x49, x48 = bits.Mul64(x42, 0x992d30ed00000001) + var x50 uint64 + var x51 fiat_pasta_fp_uint1 + x50, x51 = fiat_pasta_fp_addcarryx_u64(x49, x46, 0x0) + var x53 fiat_pasta_fp_uint1 + _, x53 = fiat_pasta_fp_addcarryx_u64(x36, x48, 0x0) + var x54 uint64 + var x55 fiat_pasta_fp_uint1 + x54, x55 = fiat_pasta_fp_addcarryx_u64(x38, x50, x53) + var x56 uint64 + var x57 fiat_pasta_fp_uint1 + x56, x57 = fiat_pasta_fp_addcarryx_u64(x40, (uint64(x51) + x47), x55) + var x58 uint64 + var x59 fiat_pasta_fp_uint1 + x58, x59 = fiat_pasta_fp_addcarryx_u64((uint64(x41) + (uint64(x35) + x21)), x44, x57) + var x60 uint64 + var x61 fiat_pasta_fp_uint1 + x60, x61 = fiat_pasta_fp_addcarryx_u64(x54, arg1[3], 0x0) + var x62 uint64 + var x63 fiat_pasta_fp_uint1 + x62, x63 = fiat_pasta_fp_addcarryx_u64(x56, uint64(0x0), x61) + var x64 uint64 + var x65 fiat_pasta_fp_uint1 + x64, x65 = fiat_pasta_fp_addcarryx_u64(x58, uint64(0x0), x63) + var x66 uint64 + _, x66 = bits.Mul64(x60, 0x992d30ecffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x66, 0x4000000000000000) + var x70 uint64 + var x71 uint64 + x71, x70 = bits.Mul64(x66, 0x224698fc094cf91b) + var x72 uint64 + var x73 uint64 + x73, x72 = bits.Mul64(x66, 0x992d30ed00000001) + var x74 uint64 + var x75 fiat_pasta_fp_uint1 + x74, x75 = fiat_pasta_fp_addcarryx_u64(x73, x70, 0x0) + var x77 fiat_pasta_fp_uint1 + _, x77 = fiat_pasta_fp_addcarryx_u64(x60, x72, 0x0) + var x78 uint64 + var x79 fiat_pasta_fp_uint1 + x78, x79 = fiat_pasta_fp_addcarryx_u64(x62, x74, x77) + var x80 uint64 + var x81 fiat_pasta_fp_uint1 + x80, x81 = fiat_pasta_fp_addcarryx_u64(x64, (uint64(x75) + x71), x79) + var x82 uint64 + var x83 fiat_pasta_fp_uint1 + x82, x83 = fiat_pasta_fp_addcarryx_u64((uint64(x65) + (uint64(x59) + x45)), x68, x81) + x84 := (uint64(x83) + x69) + var x85 uint64 + var x86 fiat_pasta_fp_uint1 + x85, x86 = fiat_pasta_fp_subborrowx_u64(x78, 0x992d30ed00000001, 0x0) + var x87 uint64 + var x88 fiat_pasta_fp_uint1 + x87, x88 = fiat_pasta_fp_subborrowx_u64(x80, 0x224698fc094cf91b, x86) + var x89 uint64 + var x90 fiat_pasta_fp_uint1 + x89, x90 = fiat_pasta_fp_subborrowx_u64(x82, uint64(0x0), x88) + var x91 uint64 + var x92 fiat_pasta_fp_uint1 + x91, x92 = fiat_pasta_fp_subborrowx_u64(x84, 0x4000000000000000, x90) + var x94 fiat_pasta_fp_uint1 + _, x94 = fiat_pasta_fp_subborrowx_u64(uint64(0x0), uint64(0x0), x92) + var x95 uint64 + fiat_pasta_fp_cmovznz_u64(&x95, x94, x85, x78) + var x96 uint64 + fiat_pasta_fp_cmovznz_u64(&x96, x94, x87, x80) + var x97 uint64 + fiat_pasta_fp_cmovznz_u64(&x97, x94, x89, x82) + var x98 uint64 + fiat_pasta_fp_cmovznz_u64(&x98, x94, x91, x84) + out1[0] = x95 + out1[1] = x96 + out1[2] = x97 + out1[3] = x98 +} + +// The function fiat_pasta_fp_to_montgomery translates a field element into the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = eval arg1 mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fp_to_montgomery(out1 *fiat_pasta_fp_montgomery_domain_field_element, arg1 *fiat_pasta_fp_non_montgomery_domain_field_element) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, 0x96d41af7b9cb714) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, 0x7797a99bc3c95d18) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, 0xd7d30dbd8b0de0e7) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, 0x8c78ecb30000000f) + var x13 uint64 + var x14 fiat_pasta_fp_uint1 + x13, x14 = fiat_pasta_fp_addcarryx_u64(x12, x9, 0x0) + var x15 uint64 + var x16 fiat_pasta_fp_uint1 + x15, x16 = fiat_pasta_fp_addcarryx_u64(x10, x7, x14) + var x17 uint64 + var x18 fiat_pasta_fp_uint1 + x17, x18 = fiat_pasta_fp_addcarryx_u64(x8, x5, x16) + var x19 uint64 + _, x19 = bits.Mul64(x11, 0x992d30ecffffffff) + var x21 uint64 + var x22 uint64 + x22, x21 = bits.Mul64(x19, 0x4000000000000000) + var x23 uint64 + var x24 uint64 + x24, x23 = bits.Mul64(x19, 0x224698fc094cf91b) + var x25 uint64 + var x26 uint64 + x26, x25 = bits.Mul64(x19, 0x992d30ed00000001) + var x27 uint64 + var x28 fiat_pasta_fp_uint1 + x27, x28 = fiat_pasta_fp_addcarryx_u64(x26, x23, 0x0) + var x30 fiat_pasta_fp_uint1 + _, x30 = fiat_pasta_fp_addcarryx_u64(x11, x25, 0x0) + var x31 uint64 + var x32 fiat_pasta_fp_uint1 + x31, x32 = fiat_pasta_fp_addcarryx_u64(x13, x27, x30) + var x33 uint64 + var x34 fiat_pasta_fp_uint1 + x33, x34 = fiat_pasta_fp_addcarryx_u64(x15, (uint64(x28) + x24), x32) + var x35 uint64 + var x36 fiat_pasta_fp_uint1 + x35, x36 = fiat_pasta_fp_addcarryx_u64(x17, x21, x34) + var x37 uint64 + var x38 uint64 + x38, x37 = bits.Mul64(x1, 0x96d41af7b9cb714) + var x39 uint64 + var x40 uint64 + x40, x39 = bits.Mul64(x1, 0x7797a99bc3c95d18) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, 0xd7d30dbd8b0de0e7) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, 0x8c78ecb30000000f) + var x45 uint64 + var x46 fiat_pasta_fp_uint1 + x45, x46 = fiat_pasta_fp_addcarryx_u64(x44, x41, 0x0) + var x47 uint64 + var x48 fiat_pasta_fp_uint1 + x47, x48 = fiat_pasta_fp_addcarryx_u64(x42, x39, x46) + var x49 uint64 + var x50 fiat_pasta_fp_uint1 + x49, x50 = fiat_pasta_fp_addcarryx_u64(x40, x37, x48) + var x51 uint64 + var x52 fiat_pasta_fp_uint1 + x51, x52 = fiat_pasta_fp_addcarryx_u64(x31, x43, 0x0) + var x53 uint64 + var x54 fiat_pasta_fp_uint1 + x53, x54 = fiat_pasta_fp_addcarryx_u64(x33, x45, x52) + var x55 uint64 + var x56 fiat_pasta_fp_uint1 + x55, x56 = fiat_pasta_fp_addcarryx_u64(x35, x47, x54) + var x57 uint64 + var x58 fiat_pasta_fp_uint1 + x57, x58 = fiat_pasta_fp_addcarryx_u64(((uint64(x36) + (uint64(x18) + x6)) + x22), x49, x56) + var x59 uint64 + _, x59 = bits.Mul64(x51, 0x992d30ecffffffff) + var x61 uint64 + var x62 uint64 + x62, x61 = bits.Mul64(x59, 0x4000000000000000) + var x63 uint64 + var x64 uint64 + x64, x63 = bits.Mul64(x59, 0x224698fc094cf91b) + var x65 uint64 + var x66 uint64 + x66, x65 = bits.Mul64(x59, 0x992d30ed00000001) + var x67 uint64 + var x68 fiat_pasta_fp_uint1 + x67, x68 = fiat_pasta_fp_addcarryx_u64(x66, x63, 0x0) + var x70 fiat_pasta_fp_uint1 + _, x70 = fiat_pasta_fp_addcarryx_u64(x51, x65, 0x0) + var x71 uint64 + var x72 fiat_pasta_fp_uint1 + x71, x72 = fiat_pasta_fp_addcarryx_u64(x53, x67, x70) + var x73 uint64 + var x74 fiat_pasta_fp_uint1 + x73, x74 = fiat_pasta_fp_addcarryx_u64(x55, (uint64(x68) + x64), x72) + var x75 uint64 + var x76 fiat_pasta_fp_uint1 + x75, x76 = fiat_pasta_fp_addcarryx_u64(x57, x61, x74) + var x77 uint64 + var x78 uint64 + x78, x77 = bits.Mul64(x2, 0x96d41af7b9cb714) + var x79 uint64 + var x80 uint64 + x80, x79 = bits.Mul64(x2, 0x7797a99bc3c95d18) + var x81 uint64 + var x82 uint64 + x82, x81 = bits.Mul64(x2, 0xd7d30dbd8b0de0e7) + var x83 uint64 + var x84 uint64 + x84, x83 = bits.Mul64(x2, 0x8c78ecb30000000f) + var x85 uint64 + var x86 fiat_pasta_fp_uint1 + x85, x86 = fiat_pasta_fp_addcarryx_u64(x84, x81, 0x0) + var x87 uint64 + var x88 fiat_pasta_fp_uint1 + x87, x88 = fiat_pasta_fp_addcarryx_u64(x82, x79, x86) + var x89 uint64 + var x90 fiat_pasta_fp_uint1 + x89, x90 = fiat_pasta_fp_addcarryx_u64(x80, x77, x88) + var x91 uint64 + var x92 fiat_pasta_fp_uint1 + x91, x92 = fiat_pasta_fp_addcarryx_u64(x71, x83, 0x0) + var x93 uint64 + var x94 fiat_pasta_fp_uint1 + x93, x94 = fiat_pasta_fp_addcarryx_u64(x73, x85, x92) + var x95 uint64 + var x96 fiat_pasta_fp_uint1 + x95, x96 = fiat_pasta_fp_addcarryx_u64(x75, x87, x94) + var x97 uint64 + var x98 fiat_pasta_fp_uint1 + x97, x98 = fiat_pasta_fp_addcarryx_u64(((uint64(x76) + (uint64(x58) + (uint64(x50) + x38))) + x62), x89, x96) + var x99 uint64 + _, x99 = bits.Mul64(x91, 0x992d30ecffffffff) + var x101 uint64 + var x102 uint64 + x102, x101 = bits.Mul64(x99, 0x4000000000000000) + var x103 uint64 + var x104 uint64 + x104, x103 = bits.Mul64(x99, 0x224698fc094cf91b) + var x105 uint64 + var x106 uint64 + x106, x105 = bits.Mul64(x99, 0x992d30ed00000001) + var x107 uint64 + var x108 fiat_pasta_fp_uint1 + x107, x108 = fiat_pasta_fp_addcarryx_u64(x106, x103, 0x0) + var x110 fiat_pasta_fp_uint1 + _, x110 = fiat_pasta_fp_addcarryx_u64(x91, x105, 0x0) + var x111 uint64 + var x112 fiat_pasta_fp_uint1 + x111, x112 = fiat_pasta_fp_addcarryx_u64(x93, x107, x110) + var x113 uint64 + var x114 fiat_pasta_fp_uint1 + x113, x114 = fiat_pasta_fp_addcarryx_u64(x95, (uint64(x108) + x104), x112) + var x115 uint64 + var x116 fiat_pasta_fp_uint1 + x115, x116 = fiat_pasta_fp_addcarryx_u64(x97, x101, x114) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x3, 0x96d41af7b9cb714) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x3, 0x7797a99bc3c95d18) + var x121 uint64 + var x122 uint64 + x122, x121 = bits.Mul64(x3, 0xd7d30dbd8b0de0e7) + var x123 uint64 + var x124 uint64 + x124, x123 = bits.Mul64(x3, 0x8c78ecb30000000f) + var x125 uint64 + var x126 fiat_pasta_fp_uint1 + x125, x126 = fiat_pasta_fp_addcarryx_u64(x124, x121, 0x0) + var x127 uint64 + var x128 fiat_pasta_fp_uint1 + x127, x128 = fiat_pasta_fp_addcarryx_u64(x122, x119, x126) + var x129 uint64 + var x130 fiat_pasta_fp_uint1 + x129, x130 = fiat_pasta_fp_addcarryx_u64(x120, x117, x128) + var x131 uint64 + var x132 fiat_pasta_fp_uint1 + x131, x132 = fiat_pasta_fp_addcarryx_u64(x111, x123, 0x0) + var x133 uint64 + var x134 fiat_pasta_fp_uint1 + x133, x134 = fiat_pasta_fp_addcarryx_u64(x113, x125, x132) + var x135 uint64 + var x136 fiat_pasta_fp_uint1 + x135, x136 = fiat_pasta_fp_addcarryx_u64(x115, x127, x134) + var x137 uint64 + var x138 fiat_pasta_fp_uint1 + x137, x138 = fiat_pasta_fp_addcarryx_u64(((uint64(x116) + (uint64(x98) + (uint64(x90) + x78))) + x102), x129, x136) + var x139 uint64 + _, x139 = bits.Mul64(x131, 0x992d30ecffffffff) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x139, 0x4000000000000000) + var x143 uint64 + var x144 uint64 + x144, x143 = bits.Mul64(x139, 0x224698fc094cf91b) + var x145 uint64 + var x146 uint64 + x146, x145 = bits.Mul64(x139, 0x992d30ed00000001) + var x147 uint64 + var x148 fiat_pasta_fp_uint1 + x147, x148 = fiat_pasta_fp_addcarryx_u64(x146, x143, 0x0) + var x150 fiat_pasta_fp_uint1 + _, x150 = fiat_pasta_fp_addcarryx_u64(x131, x145, 0x0) + var x151 uint64 + var x152 fiat_pasta_fp_uint1 + x151, x152 = fiat_pasta_fp_addcarryx_u64(x133, x147, x150) + var x153 uint64 + var x154 fiat_pasta_fp_uint1 + x153, x154 = fiat_pasta_fp_addcarryx_u64(x135, (uint64(x148) + x144), x152) + var x155 uint64 + var x156 fiat_pasta_fp_uint1 + x155, x156 = fiat_pasta_fp_addcarryx_u64(x137, x141, x154) + x157 := ((uint64(x156) + (uint64(x138) + (uint64(x130) + x118))) + x142) + var x158 uint64 + var x159 fiat_pasta_fp_uint1 + x158, x159 = fiat_pasta_fp_subborrowx_u64(x151, 0x992d30ed00000001, 0x0) + var x160 uint64 + var x161 fiat_pasta_fp_uint1 + x160, x161 = fiat_pasta_fp_subborrowx_u64(x153, 0x224698fc094cf91b, x159) + var x162 uint64 + var x163 fiat_pasta_fp_uint1 + x162, x163 = fiat_pasta_fp_subborrowx_u64(x155, uint64(0x0), x161) + var x164 uint64 + var x165 fiat_pasta_fp_uint1 + x164, x165 = fiat_pasta_fp_subborrowx_u64(x157, 0x4000000000000000, x163) + var x167 fiat_pasta_fp_uint1 + _, x167 = fiat_pasta_fp_subborrowx_u64(uint64(0x0), uint64(0x0), x165) + var x168 uint64 + fiat_pasta_fp_cmovznz_u64(&x168, x167, x158, x151) + var x169 uint64 + fiat_pasta_fp_cmovznz_u64(&x169, x167, x160, x153) + var x170 uint64 + fiat_pasta_fp_cmovznz_u64(&x170, x167, x162, x155) + var x171 uint64 + fiat_pasta_fp_cmovznz_u64(&x171, x167, x164, x157) + out1[0] = x168 + out1[1] = x169 + out1[2] = x170 + out1[3] = x171 +} + +// The function fiat_pasta_fp_selectznz is a multi-limb conditional select. +// +// Postconditions: +// +// eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func fiat_pasta_fp_selectznz(out1 *[4]uint64, arg1 fiat_pasta_fp_uint1, arg2 *[4]uint64, arg3 *[4]uint64) { + var x1 uint64 + fiat_pasta_fp_cmovznz_u64(&x1, arg1, arg2[0], arg3[0]) + var x2 uint64 + fiat_pasta_fp_cmovznz_u64(&x2, arg1, arg2[1], arg3[1]) + var x3 uint64 + fiat_pasta_fp_cmovznz_u64(&x3, arg1, arg2[2], arg3[2]) + var x4 uint64 + fiat_pasta_fp_cmovznz_u64(&x4, arg1, arg2[3], arg3[3]) + out1[0] = x1 + out1[1] = x2 + out1[2] = x3 + out1[3] = x4 +} + +// The function fiat_pasta_fp_to_bytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x7fffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] +func fiat_pasta_fp_to_bytes(out1 *[32]uint8, arg1 *[4]uint64) { + x1 := arg1[3] + x2 := arg1[2] + x3 := arg1[1] + x4 := arg1[0] + x5 := (uint8(x4) & 0xff) + x6 := (x4 >> 8) + x7 := (uint8(x6) & 0xff) + x8 := (x6 >> 8) + x9 := (uint8(x8) & 0xff) + x10 := (x8 >> 8) + x11 := (uint8(x10) & 0xff) + x12 := (x10 >> 8) + x13 := (uint8(x12) & 0xff) + x14 := (x12 >> 8) + x15 := (uint8(x14) & 0xff) + x16 := (x14 >> 8) + x17 := (uint8(x16) & 0xff) + x18 := uint8((x16 >> 8)) + x19 := (uint8(x3) & 0xff) + x20 := (x3 >> 8) + x21 := (uint8(x20) & 0xff) + x22 := (x20 >> 8) + x23 := (uint8(x22) & 0xff) + x24 := (x22 >> 8) + x25 := (uint8(x24) & 0xff) + x26 := (x24 >> 8) + x27 := (uint8(x26) & 0xff) + x28 := (x26 >> 8) + x29 := (uint8(x28) & 0xff) + x30 := (x28 >> 8) + x31 := (uint8(x30) & 0xff) + x32 := uint8((x30 >> 8)) + x33 := (uint8(x2) & 0xff) + x34 := (x2 >> 8) + x35 := (uint8(x34) & 0xff) + x36 := (x34 >> 8) + x37 := (uint8(x36) & 0xff) + x38 := (x36 >> 8) + x39 := (uint8(x38) & 0xff) + x40 := (x38 >> 8) + x41 := (uint8(x40) & 0xff) + x42 := (x40 >> 8) + x43 := (uint8(x42) & 0xff) + x44 := (x42 >> 8) + x45 := (uint8(x44) & 0xff) + x46 := uint8((x44 >> 8)) + x47 := (uint8(x1) & 0xff) + x48 := (x1 >> 8) + x49 := (uint8(x48) & 0xff) + x50 := (x48 >> 8) + x51 := (uint8(x50) & 0xff) + x52 := (x50 >> 8) + x53 := (uint8(x52) & 0xff) + x54 := (x52 >> 8) + x55 := (uint8(x54) & 0xff) + x56 := (x54 >> 8) + x57 := (uint8(x56) & 0xff) + x58 := (x56 >> 8) + x59 := (uint8(x58) & 0xff) + x60 := uint8((x58 >> 8)) + out1[0] = x5 + out1[1] = x7 + out1[2] = x9 + out1[3] = x11 + out1[4] = x13 + out1[5] = x15 + out1[6] = x17 + out1[7] = x18 + out1[8] = x19 + out1[9] = x21 + out1[10] = x23 + out1[11] = x25 + out1[12] = x27 + out1[13] = x29 + out1[14] = x31 + out1[15] = x32 + out1[16] = x33 + out1[17] = x35 + out1[18] = x37 + out1[19] = x39 + out1[20] = x41 + out1[21] = x43 + out1[22] = x45 + out1[23] = x46 + out1[24] = x47 + out1[25] = x49 + out1[26] = x51 + out1[27] = x53 + out1[28] = x55 + out1[29] = x57 + out1[30] = x59 + out1[31] = x60 +} + +// The function fiat_pasta_fp_from_bytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ bytes_eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = bytes_eval arg1 mod m +// 0 ≤ eval out1 < m +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x7fffffffffffffff]] +func fiat_pasta_fp_from_bytes(out1 *[4]uint64, arg1 *[32]uint8) { + x1 := (uint64(arg1[31]) << 56) + x2 := (uint64(arg1[30]) << 48) + x3 := (uint64(arg1[29]) << 40) + x4 := (uint64(arg1[28]) << 32) + x5 := (uint64(arg1[27]) << 24) + x6 := (uint64(arg1[26]) << 16) + x7 := (uint64(arg1[25]) << 8) + x8 := arg1[24] + x9 := (uint64(arg1[23]) << 56) + x10 := (uint64(arg1[22]) << 48) + x11 := (uint64(arg1[21]) << 40) + x12 := (uint64(arg1[20]) << 32) + x13 := (uint64(arg1[19]) << 24) + x14 := (uint64(arg1[18]) << 16) + x15 := (uint64(arg1[17]) << 8) + x16 := arg1[16] + x17 := (uint64(arg1[15]) << 56) + x18 := (uint64(arg1[14]) << 48) + x19 := (uint64(arg1[13]) << 40) + x20 := (uint64(arg1[12]) << 32) + x21 := (uint64(arg1[11]) << 24) + x22 := (uint64(arg1[10]) << 16) + x23 := (uint64(arg1[9]) << 8) + x24 := arg1[8] + x25 := (uint64(arg1[7]) << 56) + x26 := (uint64(arg1[6]) << 48) + x27 := (uint64(arg1[5]) << 40) + x28 := (uint64(arg1[4]) << 32) + x29 := (uint64(arg1[3]) << 24) + x30 := (uint64(arg1[2]) << 16) + x31 := (uint64(arg1[1]) << 8) + x32 := arg1[0] + x33 := (x31 + uint64(x32)) + x34 := (x30 + x33) + x35 := (x29 + x34) + x36 := (x28 + x35) + x37 := (x27 + x36) + x38 := (x26 + x37) + x39 := (x25 + x38) + x40 := (x23 + uint64(x24)) + x41 := (x22 + x40) + x42 := (x21 + x41) + x43 := (x20 + x42) + x44 := (x19 + x43) + x45 := (x18 + x44) + x46 := (x17 + x45) + x47 := (x15 + uint64(x16)) + x48 := (x14 + x47) + x49 := (x13 + x48) + x50 := (x12 + x49) + x51 := (x11 + x50) + x52 := (x10 + x51) + x53 := (x9 + x52) + x54 := (x7 + uint64(x8)) + x55 := (x6 + x54) + x56 := (x5 + x55) + x57 := (x4 + x56) + x58 := (x3 + x57) + x59 := (x2 + x58) + x60 := (x1 + x59) + out1[0] = x39 + out1[1] = x46 + out1[2] = x53 + out1[3] = x60 +} diff --git a/pkg/crypto/core/curves/native/pasta/fq/fq.go b/pkg/crypto/core/curves/native/pasta/fq/fq.go new file mode 100755 index 000000000..aa89e5efb --- /dev/null +++ b/pkg/crypto/core/curves/native/pasta/fq/fq.go @@ -0,0 +1,363 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fq + +import ( + "encoding/binary" + "fmt" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +type Fq fiat_pasta_fq_montgomery_domain_field_element + +// r = 2^256 mod p +var r = &Fq{0x5b2b3e9cfffffffd, 0x992c350be3420567, 0xffffffffffffffff, 0x3fffffffffffffff} + +// r2 = 2^512 mod p +var r2 = &Fq{0xfc9678ff0000000f, 0x67bb433d891a16e3, 0x7fae231004ccf590, 0x096d41af7ccfdaa9} + +// r3 = 2^768 mod p +var r3 = &Fq{0x008b421c249dae4c, 0xe13bda50dba41326, 0x88fececb8e15cb63, 0x07dd97a06e6792c8} + +// generator = 5 mod p is a generator of the `p - 1` order multiplicative +// subgroup, or in other words a primitive element of the field. +var generator = &Fq{0x96bc8c8cffffffed, 0x74c2a54b49f7778e, 0xfffffffffffffffd, 0x3fffffffffffffff} + +var s = 32 + +// modulus representation +// p = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 +var modulus = &Fq{0x8c46eb2100000001, 0x224698fc0994a8dd, 0x0000000000000000, 0x4000000000000000} + +var BiModulus = new(big.Int).SetBytes([]byte{ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x46, 0x98, 0xfc, 0x09, 0x94, 0xa8, 0xdd, + 0x8c, 0x46, 0xeb, 0x21, 0x00, 0x00, 0x00, 0x01, +}) + +// Cmp returns -1 if fp < rhs +// 0 if fp == rhs +// 1 if fp > rhs +func (fq *Fq) Cmp(rhs *Fq) int { + gt := 0 + lt := 0 + for i := len(fq) - 1; i >= 0; i-- { + gt |= int((rhs[i]-fq[i])>>63) &^ lt + lt |= int((fq[i]-rhs[i])>>63) &^ gt + } + return gt - lt +} + +// Equal returns true if fp == rhs +func (fq *Fq) Equal(rhs *Fq) bool { + t := fq[0] ^ rhs[0] + t |= fq[1] ^ rhs[1] + t |= fq[2] ^ rhs[2] + t |= fq[3] ^ rhs[3] + return t == 0 +} + +// IsZero returns true if fp == 0 +func (fq *Fq) IsZero() bool { + t := fq[0] + t |= fq[1] + t |= fq[2] + t |= fq[3] + return t == 0 +} + +// IsOne returns true if fp == r +func (fq *Fq) IsOne() bool { + return fq.Equal(r) +} + +// Set fp == rhs +func (fq *Fq) Set(rhs *Fq) *Fq { + fq[0] = rhs[0] + fq[1] = rhs[1] + fq[2] = rhs[2] + fq[3] = rhs[3] + return fq +} + +// SetUint64 sets fp == rhs +func (fq *Fq) SetUint64(rhs uint64) *Fq { + r := &fiat_pasta_fq_non_montgomery_domain_field_element{rhs, 0, 0, 0} + fiat_pasta_fq_to_montgomery((*fiat_pasta_fq_montgomery_domain_field_element)(fq), r) + return fq +} + +func (fq *Fq) SetBool(rhs bool) *Fq { + if rhs { + fq.SetOne() + } else { + fq.SetZero() + } + return fq +} + +// SetOne fp == r +func (fq *Fq) SetOne() *Fq { + return fq.Set(r) +} + +// SetZero fp == 0 +func (fq *Fq) SetZero() *Fq { + fq[0] = 0 + fq[1] = 0 + fq[2] = 0 + fq[3] = 0 + return fq +} + +// SetBytesWide takes 64 bytes as input and treats them as a 512-bit number. +// Attributed to https://github.com/zcash/pasta_curves/blob/main/src/fields/fq.rs#L255 +// We reduce an arbitrary 512-bit number by decomposing it into two 256-bit digits +// with the higher bits multiplied by 2^256. Thus, we perform two reductions +// +// 1. the lower bits are multiplied by r^2, as normal +// 2. the upper bits are multiplied by r^2 * 2^256 = r^3 +// +// and computing their sum in the field. It remains to see that arbitrary 256-bit +// numbers can be placed into Montgomery form safely using the reduction. The +// reduction works so long as the product is less than r=2^256 multiplied by +// the modulus. This holds because for any `c` smaller than the modulus, we have +// that (2^256 - 1)*c is an acceptable product for the reduction. Therefore, the +// reduction always works so long as `c` is in the field; in this case it is either the +// constant `r2` or `r3`. +func (fq *Fq) SetBytesWide(input *[64]byte) *Fq { + d0 := fiat_pasta_fq_montgomery_domain_field_element{ + binary.LittleEndian.Uint64(input[:8]), + binary.LittleEndian.Uint64(input[8:16]), + binary.LittleEndian.Uint64(input[16:24]), + binary.LittleEndian.Uint64(input[24:32]), + } + d1 := fiat_pasta_fq_montgomery_domain_field_element{ + binary.LittleEndian.Uint64(input[32:40]), + binary.LittleEndian.Uint64(input[40:48]), + binary.LittleEndian.Uint64(input[48:56]), + binary.LittleEndian.Uint64(input[56:64]), + } + // Convert to Montgomery form + tv1 := &fiat_pasta_fq_montgomery_domain_field_element{} + tv2 := &fiat_pasta_fq_montgomery_domain_field_element{} + // d0 * r2 + d1 * r3 + fiat_pasta_fq_mul(tv1, &d0, (*fiat_pasta_fq_montgomery_domain_field_element)(r2)) + fiat_pasta_fq_mul(tv2, &d1, (*fiat_pasta_fq_montgomery_domain_field_element)(r3)) + fiat_pasta_fq_add((*fiat_pasta_fq_montgomery_domain_field_element)(fq), tv1, tv2) + return fq +} + +// SetBytes attempts to convert a little endian byte representation +// of a scalar into a `Fq`, failing if input is not canonical +func (fq *Fq) SetBytes(input *[32]byte) (*Fq, error) { + d0 := &Fq{ + binary.LittleEndian.Uint64(input[:8]), + binary.LittleEndian.Uint64(input[8:16]), + binary.LittleEndian.Uint64(input[16:24]), + binary.LittleEndian.Uint64(input[24:32]), + } + if d0.Cmp(modulus) != -1 { + return nil, fmt.Errorf("invalid byte sequence") + } + fiat_pasta_fq_from_bytes((*[4]uint64)(fq), input) + fiat_pasta_fq_to_montgomery((*fiat_pasta_fq_montgomery_domain_field_element)(fq), (*fiat_pasta_fq_non_montgomery_domain_field_element)(fq)) + return fq, nil +} + +// SetBigInt initializes an element from big.Int +// The value is reduced by the modulus +func (fq *Fq) SetBigInt(bi *big.Int) *Fq { + var buffer [32]byte + r := new(big.Int).Set(bi) + r.Mod(r, BiModulus) + r.FillBytes(buffer[:]) + copy(buffer[:], internal.ReverseScalarBytes(buffer[:])) + _, _ = fq.SetBytes(&buffer) + return fq +} + +// SetRaw converts a raw array into a field element +func (fq *Fq) SetRaw(array *[4]uint64) *Fq { + fiat_pasta_fq_to_montgomery((*fiat_pasta_fq_montgomery_domain_field_element)(fq), (*fiat_pasta_fq_non_montgomery_domain_field_element)(array)) + return fq +} + +// Bytes converts this element into a byte representation +// in little endian byte order +func (fq *Fq) Bytes() [32]byte { + var output [32]byte + tv := &fiat_pasta_fq_non_montgomery_domain_field_element{} + fiat_pasta_fq_from_montgomery(tv, (*fiat_pasta_fq_montgomery_domain_field_element)(fq)) + fiat_pasta_fq_to_bytes(&output, (*[4]uint64)(tv)) + return output +} + +// BigInt converts this element into the big.Int struct +func (fq *Fq) BigInt() *big.Int { + buffer := fq.Bytes() + return new(big.Int).SetBytes(internal.ReverseScalarBytes(buffer[:])) +} + +// Double this element +func (fq *Fq) Double(elem *Fq) *Fq { + delem := (*fiat_pasta_fq_montgomery_domain_field_element)(elem) + fiat_pasta_fq_add((*fiat_pasta_fq_montgomery_domain_field_element)(fq), delem, delem) + return fq +} + +// Square this element +func (fq *Fq) Square(elem *Fq) *Fq { + delem := (*fiat_pasta_fq_montgomery_domain_field_element)(elem) + fiat_pasta_fq_square((*fiat_pasta_fq_montgomery_domain_field_element)(fq), delem) + return fq +} + +// Sqrt this element, if it exists. If true, then value +// is a square root. If false, value is a QNR +func (fq *Fq) Sqrt(elem *Fq) (*Fq, bool) { + return fq.tonelliShanks(elem) +} + +// See sqrt_ts_ct at +// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-I.4 +func (fq *Fq) tonelliShanks(elem *Fq) (*Fq, bool) { + // c1 := 32 + // c2 := (q - 1) / (2^c1) + //c2 := [4]uint64{ + // 0x0994a8dd8c46eb21, + // 0x00000000224698fc, + // 0x0000000000000000, + // 0x0000000040000000, + //} + // c3 := (c2 - 1) / 2 + c3 := [4]uint64{ + 0x04ca546ec6237590, + 0x0000000011234c7e, + 0x0000000000000000, + 0x0000000020000000, + } + // c4 := generator + // c5 := new(Fq).pow(&generator, c2) + c5 := &Fq{ + 0x218077428c9942de, + 0xcc49578921b60494, + 0xac2e5d27b2efbee2, + 0xb79fa897f2db056, + } + + z := new(Fq).pow(elem, c3) + t := new(Fq).Square(z) + t.Mul(t, elem) + + z.Mul(z, elem) + + b := new(Fq).Set(t) + c := new(Fq).Set(c5) + flags := map[bool]int{ + true: 1, + false: 0, + } + + for i := s; i >= 2; i-- { + for j := 1; j <= i-2; j++ { + b.Square(b) + } + z.CMove(z, new(Fq).Mul(z, c), flags[!b.IsOne()]) + c.Square(c) + t.CMove(t, new(Fq).Mul(t, c), flags[!b.IsOne()]) + b.Set(t) + } + wasSquare := c.Square(z).Equal(elem) + return fq.Set(z), wasSquare +} + +// Invert this element i.e. compute the multiplicative inverse +// return false, zero if this element is zero +func (fq *Fq) Invert(elem *Fq) (*Fq, bool) { + // computes elem^(p - 2) mod p + exp := [4]uint64{ + 0x8c46eb20ffffffff, + 0x224698fc0994a8dd, + 0x0000000000000000, + 0x4000000000000000, + } + return fq.pow(elem, exp), !elem.IsZero() +} + +// Mul returns the result from multiplying this element by rhs +func (fq *Fq) Mul(lhs, rhs *Fq) *Fq { + dlhs := (*fiat_pasta_fq_montgomery_domain_field_element)(lhs) + drhs := (*fiat_pasta_fq_montgomery_domain_field_element)(rhs) + fiat_pasta_fq_mul((*fiat_pasta_fq_montgomery_domain_field_element)(fq), dlhs, drhs) + return fq +} + +// Sub returns the result from subtracting rhs from this element +func (fq *Fq) Sub(lhs, rhs *Fq) *Fq { + dlhs := (*fiat_pasta_fq_montgomery_domain_field_element)(lhs) + drhs := (*fiat_pasta_fq_montgomery_domain_field_element)(rhs) + fiat_pasta_fq_sub((*fiat_pasta_fq_montgomery_domain_field_element)(fq), dlhs, drhs) + return fq +} + +// Add returns the result from adding rhs to this element +func (fq *Fq) Add(lhs, rhs *Fq) *Fq { + dlhs := (*fiat_pasta_fq_montgomery_domain_field_element)(lhs) + drhs := (*fiat_pasta_fq_montgomery_domain_field_element)(rhs) + fiat_pasta_fq_add((*fiat_pasta_fq_montgomery_domain_field_element)(fq), dlhs, drhs) + return fq +} + +// Neg returns negation of this element +func (fq *Fq) Neg(elem *Fq) *Fq { + delem := (*fiat_pasta_fq_montgomery_domain_field_element)(elem) + fiat_pasta_fq_opp((*fiat_pasta_fq_montgomery_domain_field_element)(fq), delem) + return fq +} + +// Exp exponentiates this element by exp +func (fq *Fq) Exp(base, exp *Fq) *Fq { + // convert exponent to integer form + tv := &fiat_pasta_fq_non_montgomery_domain_field_element{} + fiat_pasta_fq_from_montgomery(tv, (*fiat_pasta_fq_montgomery_domain_field_element)(exp)) + + e := (*[4]uint64)(tv) + return fq.pow(base, *e) +} + +func (fq *Fq) pow(base *Fq, exp [4]uint64) *Fq { + res := new(Fq).SetOne() + tmp := new(Fq) + + for i := len(exp) - 1; i >= 0; i-- { + for j := 63; j >= 0; j-- { + res.Square(res) + tmp.Mul(res, base) + res.CMove(res, tmp, int(exp[i]>>j)&1) + } + } + return fq.Set(res) +} + +// CMove selects lhs if choice == 0 and rhs if choice == 1 +func (fq *Fq) CMove(lhs, rhs *Fq, choice int) *Fq { + dlhs := (*[4]uint64)(lhs) + drhs := (*[4]uint64)(rhs) + fiat_pasta_fq_selectznz((*[4]uint64)(fq), fiat_pasta_fq_uint1(choice), dlhs, drhs) + return fq +} + +// ToRaw converts this element into the a [4]uint64 +func (fq *Fq) ToRaw() [4]uint64 { + res := &fiat_pasta_fq_non_montgomery_domain_field_element{} + fiat_pasta_fq_from_montgomery(res, (*fiat_pasta_fq_montgomery_domain_field_element)(fq)) + return *(*[4]uint64)(res) +} diff --git a/pkg/crypto/core/curves/native/pasta/fq/fq_test.go b/pkg/crypto/core/curves/native/pasta/fq/fq_test.go new file mode 100755 index 000000000..d773e1913 --- /dev/null +++ b/pkg/crypto/core/curves/native/pasta/fq/fq_test.go @@ -0,0 +1,249 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package fq + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFqSetOne(t *testing.T) { + fq := new(Fq).SetOne() + require.NotNil(t, fq) + require.True(t, fq.Equal(r)) +} + +func TestFqSetUint64(t *testing.T) { + act := new(Fq).SetUint64(1 << 60) + require.NotNil(t, act) + // Remember it will be in montgomery form + require.Equal(t, int(act[0]), 0x4c46eb2100000001) +} + +func TestFqAdd(t *testing.T) { + lhs := new(Fq).SetOne() + rhs := new(Fq).SetOne() + exp := new(Fq).SetUint64(2) + res := new(Fq).Add(lhs, rhs) + require.NotNil(t, res) + require.True(t, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + e := l + r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := new(Fq).Add(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqSub(t *testing.T) { + lhs := new(Fq).SetOne() + rhs := new(Fq).SetOne() + exp := new(Fq).SetZero() + res := new(Fq).Sub(lhs, rhs) + require.NotNil(t, res) + require.True(t, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint64() >> 2 + r := rand.Uint64() >> 2 + if l < r { + l, r = r, l + } + e := l - r + lhs.SetUint64(l) + rhs.SetUint64(r) + exp.SetUint64(e) + + a := new(Fq).Sub(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqMul(t *testing.T) { + lhs := new(Fq).SetOne() + rhs := new(Fq).SetOne() + exp := new(Fq).SetOne() + res := new(Fq).Mul(lhs, rhs) + require.NotNil(t, res) + require.True(t, res.Equal(exp)) + + // Fuzz test + for i := 0; i < 25; i++ { + // Divide by 4 to prevent overflow false errors + l := rand.Uint32() + r := rand.Uint32() + e := uint64(l) * uint64(r) + lhs.SetUint64(uint64(l)) + rhs.SetUint64(uint64(r)) + exp.SetUint64(e) + + a := new(Fq).Mul(lhs, rhs) + require.NotNil(t, a) + require.Equal(t, exp, a) + } +} + +func TestFqDouble(t *testing.T) { + a := new(Fq).SetUint64(2) + e := new(Fq).SetUint64(4) + require.Equal(t, e, new(Fq).Double(a)) + + for i := 0; i < 25; i++ { + tv := rand.Uint32() + ttv := uint64(tv) * 2 + a = new(Fq).SetUint64(uint64(tv)) + e = new(Fq).SetUint64(ttv) + require.Equal(t, e, new(Fq).Double(a)) + } +} + +func TestFqSquare(t *testing.T) { + a := new(Fq).SetUint64(4) + e := new(Fq).SetUint64(16) + require.Equal(t, e, a.Square(a)) + + for i := 0; i < 25; i++ { + j := rand.Uint32() + exp := uint64(j) * uint64(j) + e.SetUint64(exp) + a.SetUint64(uint64(j)) + require.Equal(t, e, a.Square(a)) + } +} + +func TestFqNeg(t *testing.T) { + a := new(Fq).SetOne() + a.Neg(a) + e := &Fq{0x311bac8400000004, 0x891a63f02652a376, 0, 0} + require.Equal(t, e, a) + a.Neg(generator) + e = &Fq{0xf58a5e9400000014, 0xad83f3b0bf9d314e, 0x2, 0x0} + require.Equal(t, e, a) +} + +func TestFqExp(t *testing.T) { + e := new(Fq).SetUint64(8) + a := new(Fq).SetUint64(2) + by := new(Fq).SetUint64(3) + require.Equal(t, e, a.Exp(a, by)) +} + +func TestFqSqrt(t *testing.T) { + t1 := new(Fq).SetUint64(2) + t2 := new(Fq).Neg(t1) + t3 := new(Fq).Square(t1) + _, wasSquare := t3.Sqrt(t3) + require.True(t, wasSquare) + require.True(t, t1.Equal(t3) || t2.Equal(t3)) + t1.SetUint64(5) + _, wasSquare = new(Fq).Sqrt(t1) + require.False(t, wasSquare) +} + +func TestFqInvert(t *testing.T) { + twoInv := &Fq{0xc623759080000001, 0x11234c7e04ca546e, 0x0000000000000000, 0x2000000000000000} + fiat_pasta_fq_to_montgomery((*fiat_pasta_fq_montgomery_domain_field_element)(twoInv), (*fiat_pasta_fq_non_montgomery_domain_field_element)(twoInv)) + two := new(Fq).SetUint64(2) + a, inverted := new(Fq).Invert(two) + require.True(t, inverted) + require.Equal(t, a, twoInv) + + rootOfUnity := &Fq{0xa70e2c1102b6d05f, 0x9bb97ea3c106f049, 0x9e5c4dfd492ae26e, 0x2de6a9b8746d3f58} + fiat_pasta_fq_to_montgomery((*fiat_pasta_fq_montgomery_domain_field_element)(rootOfUnity), (*fiat_pasta_fq_non_montgomery_domain_field_element)(rootOfUnity)) + rootOfUnityInv := &Fq{0x57eecda0a84b6836, 0x4ad38b9084b8a80c, 0xf4c8f353124086c1, 0x2235e1a7415bf936} + fiat_pasta_fq_to_montgomery((*fiat_pasta_fq_montgomery_domain_field_element)(rootOfUnityInv), (*fiat_pasta_fq_non_montgomery_domain_field_element)(rootOfUnityInv)) + a, inverted = new(Fq).Invert(rootOfUnity) + require.True(t, inverted) + require.Equal(t, a, rootOfUnityInv) + + lhs := new(Fq).SetUint64(9) + rhs := new(Fq).SetUint64(3) + rhsInv, inverted := new(Fq).Invert(rhs) + require.True(t, inverted) + require.Equal(t, rhs, new(Fq).Mul(lhs, rhsInv)) + + rhs.SetZero() + _, inverted = new(Fq).Invert(rhs) + require.False(t, inverted) +} + +func TestFqCMove(t *testing.T) { + t1 := new(Fq).SetUint64(5) + t2 := new(Fq).SetUint64(10) + require.Equal(t, t1, new(Fq).CMove(t1, t2, 0)) + require.Equal(t, t2, new(Fq).CMove(t1, t2, 1)) +} + +func TestFqBytes(t *testing.T) { + t1 := new(Fq).SetUint64(99) + seq := t1.Bytes() + t2, err := new(Fq).SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + + for i := 0; i < 25; i++ { + t1.SetUint64(rand.Uint64()) + seq = t1.Bytes() + _, err = t2.SetBytes(&seq) + require.NoError(t, err) + require.Equal(t, t1, t2) + } +} + +func TestFqBigInt(t *testing.T) { + t1 := new(Fq).SetBigInt(big.NewInt(9999)) + t2 := new(Fq).SetBigInt(t1.BigInt()) + require.Equal(t, t1, t2) + + e := &Fq{0x7bb1416dea3d6ae3, 0x62f9108a340aa525, 0x303b3f30fcaa477f, 0x11c9ef5422d80a4d} + b := new(big.Int).SetBytes([]byte{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}) + t1.SetBigInt(b) + require.Equal(t, e, t1) + e[0] = 0x1095a9b315c2951e + e[1] = 0xbf4d8871d58a03b8 + e[2] = 0xcfc4c0cf0355b880 + e[3] = 0x2e3610abdd27f5b2 + b.Neg(b) + t1.SetBigInt(b) + require.Equal(t, e, t1) +} + +func TestFqSetBool(t *testing.T) { + require.Equal(t, new(Fq).SetOne(), new(Fq).SetBool(true)) + require.Equal(t, new(Fq).SetZero(), new(Fq).SetBool(false)) +} + +func TestFqSetBytesWide(t *testing.T) { + e := &Fq{0xe22bd0d1b22cc43e, 0x6b84e5b52490a7c8, 0x264262941ac9e229, 0x27dcfdf361ce4254} + fiat_pasta_fq_to_montgomery((*fiat_pasta_fq_montgomery_domain_field_element)(e), (*fiat_pasta_fq_non_montgomery_domain_field_element)(e)) + a := new(Fq).SetBytesWide(&[64]byte{ + 0x69, 0x23, 0x5a, 0x0b, 0xce, 0x0c, 0xa8, 0x64, + 0x3c, 0x78, 0xbc, 0x01, 0x05, 0xef, 0xf2, 0x84, + 0xde, 0xbb, 0x6b, 0xc8, 0x63, 0x5e, 0x6e, 0x69, + 0x62, 0xcc, 0xc6, 0x2d, 0xf5, 0x72, 0x40, 0x92, + 0x28, 0x11, 0xd6, 0xc8, 0x07, 0xa5, 0x88, 0x82, + 0xfe, 0xe3, 0x97, 0xf6, 0x1e, 0xfb, 0x2e, 0x3b, + 0x27, 0x5f, 0x85, 0x06, 0x8d, 0x99, 0xa4, 0x75, + 0xc0, 0x2c, 0x71, 0x69, 0x9e, 0x58, 0xea, 0x52, + }) + require.Equal(t, e, a) +} diff --git a/pkg/crypto/core/curves/native/pasta/fq/pasta_fq.go b/pkg/crypto/core/curves/native/pasta/fq/pasta_fq.go new file mode 100755 index 000000000..b6411c1da --- /dev/null +++ b/pkg/crypto/core/curves/native/pasta/fq/pasta_fq.go @@ -0,0 +1,1467 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Autogenerated: './src/ExtractionOCaml/word_by_word_montgomery' --lang Go pasta_fq 64 '2^254 + 45560315531506369815346746415080538113' +// +// curve description: pasta_fq +// +// machine_wordsize = 64 (from "64") +// +// requested operations: (all) +// +// m = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 (from "2^254 + 45560315531506369815346746415080538113") +// +// +// +// NOTE: In addition to the bounds specified above each function, all +// +// functions synthesized for this Montgomery arithmetic require the +// +// input to be strictly less than the prime modulus (m), and also +// +// require the input to be in the unique saturated representation. +// +// All functions also ensure that these two properties are true of +// +// return values. +// +// +// +// Computed values: +// +// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) +// +// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) +// +// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in +// +// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 + +package fq + +import "math/bits" + +type fiat_pasta_fq_uint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 +type fiat_pasta_fq_int1 int64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 + +// The type fiat_pasta_fq_montgomery_domain_field_element is a field element in the Montgomery domain. +// +// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type fiat_pasta_fq_montgomery_domain_field_element [4]uint64 + +// The type fiat_pasta_fq_non_montgomery_domain_field_element is a field element NOT in the Montgomery domain. +// +// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +type fiat_pasta_fq_non_montgomery_domain_field_element [4]uint64 + +// The function fiat_pasta_fq_addcarryx_u64 is a thin wrapper around bits.Add64 that uses fiat_pasta_fq_uint1 rather than uint64 +func fiat_pasta_fq_addcarryx_u64(x uint64, y uint64, carry fiat_pasta_fq_uint1) (uint64, fiat_pasta_fq_uint1) { + sum, carryOut := bits.Add64(x, y, uint64(carry)) + return sum, fiat_pasta_fq_uint1(carryOut) +} + +// The function fiat_pasta_fq_subborrowx_u64 is a thin wrapper around bits.Sub64 that uses fiat_pasta_fq_uint1 rather than uint64 +func fiat_pasta_fq_subborrowx_u64(x uint64, y uint64, carry fiat_pasta_fq_uint1) (uint64, fiat_pasta_fq_uint1) { + sum, carryOut := bits.Sub64(x, y, uint64(carry)) + return sum, fiat_pasta_fq_uint1(carryOut) +} + +// The function fiat_pasta_fq_cmovznz_u64 is a single-word conditional move. +// +// Postconditions: +// +// out1 = (if arg1 = 0 then arg2 else arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [0x0 ~> 0xffffffffffffffff] +// arg3: [0x0 ~> 0xffffffffffffffff] +// +// Output Bounds: +// +// out1: [0x0 ~> 0xffffffffffffffff] +func fiat_pasta_fq_cmovznz_u64(out1 *uint64, arg1 fiat_pasta_fq_uint1, arg2 uint64, arg3 uint64) { + x1 := arg1 + x2 := (uint64((fiat_pasta_fq_int1(0x0) - fiat_pasta_fq_int1(x1))) & 0xffffffffffffffff) + x3 := ((x2 & arg3) | ((^x2) & arg2)) + *out1 = x3 +} + +// The function fiat_pasta_fq_mul multiplies two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fq_mul(out1 *fiat_pasta_fq_montgomery_domain_field_element, arg1 *fiat_pasta_fq_montgomery_domain_field_element, arg2 *fiat_pasta_fq_montgomery_domain_field_element) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg2[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg2[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg2[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg2[0]) + var x13 uint64 + var x14 fiat_pasta_fq_uint1 + x13, x14 = fiat_pasta_fq_addcarryx_u64(x12, x9, 0x0) + var x15 uint64 + var x16 fiat_pasta_fq_uint1 + x15, x16 = fiat_pasta_fq_addcarryx_u64(x10, x7, x14) + var x17 uint64 + var x18 fiat_pasta_fq_uint1 + x17, x18 = fiat_pasta_fq_addcarryx_u64(x8, x5, x16) + x19 := (uint64(x18) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0x8c46eb20ffffffff) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0x4000000000000000) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0x224698fc0994a8dd) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0x8c46eb2100000001) + var x28 uint64 + var x29 fiat_pasta_fq_uint1 + x28, x29 = fiat_pasta_fq_addcarryx_u64(x27, x24, 0x0) + x30 := (uint64(x29) + x25) + var x32 fiat_pasta_fq_uint1 + _, x32 = fiat_pasta_fq_addcarryx_u64(x11, x26, 0x0) + var x33 uint64 + var x34 fiat_pasta_fq_uint1 + x33, x34 = fiat_pasta_fq_addcarryx_u64(x13, x28, x32) + var x35 uint64 + var x36 fiat_pasta_fq_uint1 + x35, x36 = fiat_pasta_fq_addcarryx_u64(x15, x30, x34) + var x37 uint64 + var x38 fiat_pasta_fq_uint1 + x37, x38 = fiat_pasta_fq_addcarryx_u64(x17, x22, x36) + var x39 uint64 + var x40 fiat_pasta_fq_uint1 + x39, x40 = fiat_pasta_fq_addcarryx_u64(x19, x23, x38) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, arg2[3]) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, arg2[2]) + var x45 uint64 + var x46 uint64 + x46, x45 = bits.Mul64(x1, arg2[1]) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg2[0]) + var x49 uint64 + var x50 fiat_pasta_fq_uint1 + x49, x50 = fiat_pasta_fq_addcarryx_u64(x48, x45, 0x0) + var x51 uint64 + var x52 fiat_pasta_fq_uint1 + x51, x52 = fiat_pasta_fq_addcarryx_u64(x46, x43, x50) + var x53 uint64 + var x54 fiat_pasta_fq_uint1 + x53, x54 = fiat_pasta_fq_addcarryx_u64(x44, x41, x52) + x55 := (uint64(x54) + x42) + var x56 uint64 + var x57 fiat_pasta_fq_uint1 + x56, x57 = fiat_pasta_fq_addcarryx_u64(x33, x47, 0x0) + var x58 uint64 + var x59 fiat_pasta_fq_uint1 + x58, x59 = fiat_pasta_fq_addcarryx_u64(x35, x49, x57) + var x60 uint64 + var x61 fiat_pasta_fq_uint1 + x60, x61 = fiat_pasta_fq_addcarryx_u64(x37, x51, x59) + var x62 uint64 + var x63 fiat_pasta_fq_uint1 + x62, x63 = fiat_pasta_fq_addcarryx_u64(x39, x53, x61) + var x64 uint64 + var x65 fiat_pasta_fq_uint1 + x64, x65 = fiat_pasta_fq_addcarryx_u64(uint64(x40), x55, x63) + var x66 uint64 + _, x66 = bits.Mul64(x56, 0x8c46eb20ffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x66, 0x4000000000000000) + var x70 uint64 + var x71 uint64 + x71, x70 = bits.Mul64(x66, 0x224698fc0994a8dd) + var x72 uint64 + var x73 uint64 + x73, x72 = bits.Mul64(x66, 0x8c46eb2100000001) + var x74 uint64 + var x75 fiat_pasta_fq_uint1 + x74, x75 = fiat_pasta_fq_addcarryx_u64(x73, x70, 0x0) + x76 := (uint64(x75) + x71) + var x78 fiat_pasta_fq_uint1 + _, x78 = fiat_pasta_fq_addcarryx_u64(x56, x72, 0x0) + var x79 uint64 + var x80 fiat_pasta_fq_uint1 + x79, x80 = fiat_pasta_fq_addcarryx_u64(x58, x74, x78) + var x81 uint64 + var x82 fiat_pasta_fq_uint1 + x81, x82 = fiat_pasta_fq_addcarryx_u64(x60, x76, x80) + var x83 uint64 + var x84 fiat_pasta_fq_uint1 + x83, x84 = fiat_pasta_fq_addcarryx_u64(x62, x68, x82) + var x85 uint64 + var x86 fiat_pasta_fq_uint1 + x85, x86 = fiat_pasta_fq_addcarryx_u64(x64, x69, x84) + x87 := (uint64(x86) + uint64(x65)) + var x88 uint64 + var x89 uint64 + x89, x88 = bits.Mul64(x2, arg2[3]) + var x90 uint64 + var x91 uint64 + x91, x90 = bits.Mul64(x2, arg2[2]) + var x92 uint64 + var x93 uint64 + x93, x92 = bits.Mul64(x2, arg2[1]) + var x94 uint64 + var x95 uint64 + x95, x94 = bits.Mul64(x2, arg2[0]) + var x96 uint64 + var x97 fiat_pasta_fq_uint1 + x96, x97 = fiat_pasta_fq_addcarryx_u64(x95, x92, 0x0) + var x98 uint64 + var x99 fiat_pasta_fq_uint1 + x98, x99 = fiat_pasta_fq_addcarryx_u64(x93, x90, x97) + var x100 uint64 + var x101 fiat_pasta_fq_uint1 + x100, x101 = fiat_pasta_fq_addcarryx_u64(x91, x88, x99) + x102 := (uint64(x101) + x89) + var x103 uint64 + var x104 fiat_pasta_fq_uint1 + x103, x104 = fiat_pasta_fq_addcarryx_u64(x79, x94, 0x0) + var x105 uint64 + var x106 fiat_pasta_fq_uint1 + x105, x106 = fiat_pasta_fq_addcarryx_u64(x81, x96, x104) + var x107 uint64 + var x108 fiat_pasta_fq_uint1 + x107, x108 = fiat_pasta_fq_addcarryx_u64(x83, x98, x106) + var x109 uint64 + var x110 fiat_pasta_fq_uint1 + x109, x110 = fiat_pasta_fq_addcarryx_u64(x85, x100, x108) + var x111 uint64 + var x112 fiat_pasta_fq_uint1 + x111, x112 = fiat_pasta_fq_addcarryx_u64(x87, x102, x110) + var x113 uint64 + _, x113 = bits.Mul64(x103, 0x8c46eb20ffffffff) + var x115 uint64 + var x116 uint64 + x116, x115 = bits.Mul64(x113, 0x4000000000000000) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x113, 0x224698fc0994a8dd) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x113, 0x8c46eb2100000001) + var x121 uint64 + var x122 fiat_pasta_fq_uint1 + x121, x122 = fiat_pasta_fq_addcarryx_u64(x120, x117, 0x0) + x123 := (uint64(x122) + x118) + var x125 fiat_pasta_fq_uint1 + _, x125 = fiat_pasta_fq_addcarryx_u64(x103, x119, 0x0) + var x126 uint64 + var x127 fiat_pasta_fq_uint1 + x126, x127 = fiat_pasta_fq_addcarryx_u64(x105, x121, x125) + var x128 uint64 + var x129 fiat_pasta_fq_uint1 + x128, x129 = fiat_pasta_fq_addcarryx_u64(x107, x123, x127) + var x130 uint64 + var x131 fiat_pasta_fq_uint1 + x130, x131 = fiat_pasta_fq_addcarryx_u64(x109, x115, x129) + var x132 uint64 + var x133 fiat_pasta_fq_uint1 + x132, x133 = fiat_pasta_fq_addcarryx_u64(x111, x116, x131) + x134 := (uint64(x133) + uint64(x112)) + var x135 uint64 + var x136 uint64 + x136, x135 = bits.Mul64(x3, arg2[3]) + var x137 uint64 + var x138 uint64 + x138, x137 = bits.Mul64(x3, arg2[2]) + var x139 uint64 + var x140 uint64 + x140, x139 = bits.Mul64(x3, arg2[1]) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x3, arg2[0]) + var x143 uint64 + var x144 fiat_pasta_fq_uint1 + x143, x144 = fiat_pasta_fq_addcarryx_u64(x142, x139, 0x0) + var x145 uint64 + var x146 fiat_pasta_fq_uint1 + x145, x146 = fiat_pasta_fq_addcarryx_u64(x140, x137, x144) + var x147 uint64 + var x148 fiat_pasta_fq_uint1 + x147, x148 = fiat_pasta_fq_addcarryx_u64(x138, x135, x146) + x149 := (uint64(x148) + x136) + var x150 uint64 + var x151 fiat_pasta_fq_uint1 + x150, x151 = fiat_pasta_fq_addcarryx_u64(x126, x141, 0x0) + var x152 uint64 + var x153 fiat_pasta_fq_uint1 + x152, x153 = fiat_pasta_fq_addcarryx_u64(x128, x143, x151) + var x154 uint64 + var x155 fiat_pasta_fq_uint1 + x154, x155 = fiat_pasta_fq_addcarryx_u64(x130, x145, x153) + var x156 uint64 + var x157 fiat_pasta_fq_uint1 + x156, x157 = fiat_pasta_fq_addcarryx_u64(x132, x147, x155) + var x158 uint64 + var x159 fiat_pasta_fq_uint1 + x158, x159 = fiat_pasta_fq_addcarryx_u64(x134, x149, x157) + var x160 uint64 + _, x160 = bits.Mul64(x150, 0x8c46eb20ffffffff) + var x162 uint64 + var x163 uint64 + x163, x162 = bits.Mul64(x160, 0x4000000000000000) + var x164 uint64 + var x165 uint64 + x165, x164 = bits.Mul64(x160, 0x224698fc0994a8dd) + var x166 uint64 + var x167 uint64 + x167, x166 = bits.Mul64(x160, 0x8c46eb2100000001) + var x168 uint64 + var x169 fiat_pasta_fq_uint1 + x168, x169 = fiat_pasta_fq_addcarryx_u64(x167, x164, 0x0) + x170 := (uint64(x169) + x165) + var x172 fiat_pasta_fq_uint1 + _, x172 = fiat_pasta_fq_addcarryx_u64(x150, x166, 0x0) + var x173 uint64 + var x174 fiat_pasta_fq_uint1 + x173, x174 = fiat_pasta_fq_addcarryx_u64(x152, x168, x172) + var x175 uint64 + var x176 fiat_pasta_fq_uint1 + x175, x176 = fiat_pasta_fq_addcarryx_u64(x154, x170, x174) + var x177 uint64 + var x178 fiat_pasta_fq_uint1 + x177, x178 = fiat_pasta_fq_addcarryx_u64(x156, x162, x176) + var x179 uint64 + var x180 fiat_pasta_fq_uint1 + x179, x180 = fiat_pasta_fq_addcarryx_u64(x158, x163, x178) + x181 := (uint64(x180) + uint64(x159)) + var x182 uint64 + var x183 fiat_pasta_fq_uint1 + x182, x183 = fiat_pasta_fq_subborrowx_u64(x173, 0x8c46eb2100000001, 0x0) + var x184 uint64 + var x185 fiat_pasta_fq_uint1 + x184, x185 = fiat_pasta_fq_subborrowx_u64(x175, 0x224698fc0994a8dd, x183) + var x186 uint64 + var x187 fiat_pasta_fq_uint1 + x186, x187 = fiat_pasta_fq_subborrowx_u64(x177, uint64(0x0), x185) + var x188 uint64 + var x189 fiat_pasta_fq_uint1 + x188, x189 = fiat_pasta_fq_subborrowx_u64(x179, 0x4000000000000000, x187) + var x191 fiat_pasta_fq_uint1 + _, x191 = fiat_pasta_fq_subborrowx_u64(x181, uint64(0x0), x189) + var x192 uint64 + fiat_pasta_fq_cmovznz_u64(&x192, x191, x182, x173) + var x193 uint64 + fiat_pasta_fq_cmovznz_u64(&x193, x191, x184, x175) + var x194 uint64 + fiat_pasta_fq_cmovznz_u64(&x194, x191, x186, x177) + var x195 uint64 + fiat_pasta_fq_cmovznz_u64(&x195, x191, x188, x179) + out1[0] = x192 + out1[1] = x193 + out1[2] = x194 + out1[3] = x195 +} + +// The function fiat_pasta_fq_square squares a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fq_square(out1 *fiat_pasta_fq_montgomery_domain_field_element, arg1 *fiat_pasta_fq_montgomery_domain_field_element) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, arg1[3]) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, arg1[2]) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, arg1[1]) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, arg1[0]) + var x13 uint64 + var x14 fiat_pasta_fq_uint1 + x13, x14 = fiat_pasta_fq_addcarryx_u64(x12, x9, 0x0) + var x15 uint64 + var x16 fiat_pasta_fq_uint1 + x15, x16 = fiat_pasta_fq_addcarryx_u64(x10, x7, x14) + var x17 uint64 + var x18 fiat_pasta_fq_uint1 + x17, x18 = fiat_pasta_fq_addcarryx_u64(x8, x5, x16) + x19 := (uint64(x18) + x6) + var x20 uint64 + _, x20 = bits.Mul64(x11, 0x8c46eb20ffffffff) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x20, 0x4000000000000000) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x20, 0x224698fc0994a8dd) + var x26 uint64 + var x27 uint64 + x27, x26 = bits.Mul64(x20, 0x8c46eb2100000001) + var x28 uint64 + var x29 fiat_pasta_fq_uint1 + x28, x29 = fiat_pasta_fq_addcarryx_u64(x27, x24, 0x0) + x30 := (uint64(x29) + x25) + var x32 fiat_pasta_fq_uint1 + _, x32 = fiat_pasta_fq_addcarryx_u64(x11, x26, 0x0) + var x33 uint64 + var x34 fiat_pasta_fq_uint1 + x33, x34 = fiat_pasta_fq_addcarryx_u64(x13, x28, x32) + var x35 uint64 + var x36 fiat_pasta_fq_uint1 + x35, x36 = fiat_pasta_fq_addcarryx_u64(x15, x30, x34) + var x37 uint64 + var x38 fiat_pasta_fq_uint1 + x37, x38 = fiat_pasta_fq_addcarryx_u64(x17, x22, x36) + var x39 uint64 + var x40 fiat_pasta_fq_uint1 + x39, x40 = fiat_pasta_fq_addcarryx_u64(x19, x23, x38) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, arg1[3]) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, arg1[2]) + var x45 uint64 + var x46 uint64 + x46, x45 = bits.Mul64(x1, arg1[1]) + var x47 uint64 + var x48 uint64 + x48, x47 = bits.Mul64(x1, arg1[0]) + var x49 uint64 + var x50 fiat_pasta_fq_uint1 + x49, x50 = fiat_pasta_fq_addcarryx_u64(x48, x45, 0x0) + var x51 uint64 + var x52 fiat_pasta_fq_uint1 + x51, x52 = fiat_pasta_fq_addcarryx_u64(x46, x43, x50) + var x53 uint64 + var x54 fiat_pasta_fq_uint1 + x53, x54 = fiat_pasta_fq_addcarryx_u64(x44, x41, x52) + x55 := (uint64(x54) + x42) + var x56 uint64 + var x57 fiat_pasta_fq_uint1 + x56, x57 = fiat_pasta_fq_addcarryx_u64(x33, x47, 0x0) + var x58 uint64 + var x59 fiat_pasta_fq_uint1 + x58, x59 = fiat_pasta_fq_addcarryx_u64(x35, x49, x57) + var x60 uint64 + var x61 fiat_pasta_fq_uint1 + x60, x61 = fiat_pasta_fq_addcarryx_u64(x37, x51, x59) + var x62 uint64 + var x63 fiat_pasta_fq_uint1 + x62, x63 = fiat_pasta_fq_addcarryx_u64(x39, x53, x61) + var x64 uint64 + var x65 fiat_pasta_fq_uint1 + x64, x65 = fiat_pasta_fq_addcarryx_u64(uint64(x40), x55, x63) + var x66 uint64 + _, x66 = bits.Mul64(x56, 0x8c46eb20ffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x66, 0x4000000000000000) + var x70 uint64 + var x71 uint64 + x71, x70 = bits.Mul64(x66, 0x224698fc0994a8dd) + var x72 uint64 + var x73 uint64 + x73, x72 = bits.Mul64(x66, 0x8c46eb2100000001) + var x74 uint64 + var x75 fiat_pasta_fq_uint1 + x74, x75 = fiat_pasta_fq_addcarryx_u64(x73, x70, 0x0) + x76 := (uint64(x75) + x71) + var x78 fiat_pasta_fq_uint1 + _, x78 = fiat_pasta_fq_addcarryx_u64(x56, x72, 0x0) + var x79 uint64 + var x80 fiat_pasta_fq_uint1 + x79, x80 = fiat_pasta_fq_addcarryx_u64(x58, x74, x78) + var x81 uint64 + var x82 fiat_pasta_fq_uint1 + x81, x82 = fiat_pasta_fq_addcarryx_u64(x60, x76, x80) + var x83 uint64 + var x84 fiat_pasta_fq_uint1 + x83, x84 = fiat_pasta_fq_addcarryx_u64(x62, x68, x82) + var x85 uint64 + var x86 fiat_pasta_fq_uint1 + x85, x86 = fiat_pasta_fq_addcarryx_u64(x64, x69, x84) + x87 := (uint64(x86) + uint64(x65)) + var x88 uint64 + var x89 uint64 + x89, x88 = bits.Mul64(x2, arg1[3]) + var x90 uint64 + var x91 uint64 + x91, x90 = bits.Mul64(x2, arg1[2]) + var x92 uint64 + var x93 uint64 + x93, x92 = bits.Mul64(x2, arg1[1]) + var x94 uint64 + var x95 uint64 + x95, x94 = bits.Mul64(x2, arg1[0]) + var x96 uint64 + var x97 fiat_pasta_fq_uint1 + x96, x97 = fiat_pasta_fq_addcarryx_u64(x95, x92, 0x0) + var x98 uint64 + var x99 fiat_pasta_fq_uint1 + x98, x99 = fiat_pasta_fq_addcarryx_u64(x93, x90, x97) + var x100 uint64 + var x101 fiat_pasta_fq_uint1 + x100, x101 = fiat_pasta_fq_addcarryx_u64(x91, x88, x99) + x102 := (uint64(x101) + x89) + var x103 uint64 + var x104 fiat_pasta_fq_uint1 + x103, x104 = fiat_pasta_fq_addcarryx_u64(x79, x94, 0x0) + var x105 uint64 + var x106 fiat_pasta_fq_uint1 + x105, x106 = fiat_pasta_fq_addcarryx_u64(x81, x96, x104) + var x107 uint64 + var x108 fiat_pasta_fq_uint1 + x107, x108 = fiat_pasta_fq_addcarryx_u64(x83, x98, x106) + var x109 uint64 + var x110 fiat_pasta_fq_uint1 + x109, x110 = fiat_pasta_fq_addcarryx_u64(x85, x100, x108) + var x111 uint64 + var x112 fiat_pasta_fq_uint1 + x111, x112 = fiat_pasta_fq_addcarryx_u64(x87, x102, x110) + var x113 uint64 + _, x113 = bits.Mul64(x103, 0x8c46eb20ffffffff) + var x115 uint64 + var x116 uint64 + x116, x115 = bits.Mul64(x113, 0x4000000000000000) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x113, 0x224698fc0994a8dd) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x113, 0x8c46eb2100000001) + var x121 uint64 + var x122 fiat_pasta_fq_uint1 + x121, x122 = fiat_pasta_fq_addcarryx_u64(x120, x117, 0x0) + x123 := (uint64(x122) + x118) + var x125 fiat_pasta_fq_uint1 + _, x125 = fiat_pasta_fq_addcarryx_u64(x103, x119, 0x0) + var x126 uint64 + var x127 fiat_pasta_fq_uint1 + x126, x127 = fiat_pasta_fq_addcarryx_u64(x105, x121, x125) + var x128 uint64 + var x129 fiat_pasta_fq_uint1 + x128, x129 = fiat_pasta_fq_addcarryx_u64(x107, x123, x127) + var x130 uint64 + var x131 fiat_pasta_fq_uint1 + x130, x131 = fiat_pasta_fq_addcarryx_u64(x109, x115, x129) + var x132 uint64 + var x133 fiat_pasta_fq_uint1 + x132, x133 = fiat_pasta_fq_addcarryx_u64(x111, x116, x131) + x134 := (uint64(x133) + uint64(x112)) + var x135 uint64 + var x136 uint64 + x136, x135 = bits.Mul64(x3, arg1[3]) + var x137 uint64 + var x138 uint64 + x138, x137 = bits.Mul64(x3, arg1[2]) + var x139 uint64 + var x140 uint64 + x140, x139 = bits.Mul64(x3, arg1[1]) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x3, arg1[0]) + var x143 uint64 + var x144 fiat_pasta_fq_uint1 + x143, x144 = fiat_pasta_fq_addcarryx_u64(x142, x139, 0x0) + var x145 uint64 + var x146 fiat_pasta_fq_uint1 + x145, x146 = fiat_pasta_fq_addcarryx_u64(x140, x137, x144) + var x147 uint64 + var x148 fiat_pasta_fq_uint1 + x147, x148 = fiat_pasta_fq_addcarryx_u64(x138, x135, x146) + x149 := (uint64(x148) + x136) + var x150 uint64 + var x151 fiat_pasta_fq_uint1 + x150, x151 = fiat_pasta_fq_addcarryx_u64(x126, x141, 0x0) + var x152 uint64 + var x153 fiat_pasta_fq_uint1 + x152, x153 = fiat_pasta_fq_addcarryx_u64(x128, x143, x151) + var x154 uint64 + var x155 fiat_pasta_fq_uint1 + x154, x155 = fiat_pasta_fq_addcarryx_u64(x130, x145, x153) + var x156 uint64 + var x157 fiat_pasta_fq_uint1 + x156, x157 = fiat_pasta_fq_addcarryx_u64(x132, x147, x155) + var x158 uint64 + var x159 fiat_pasta_fq_uint1 + x158, x159 = fiat_pasta_fq_addcarryx_u64(x134, x149, x157) + var x160 uint64 + _, x160 = bits.Mul64(x150, 0x8c46eb20ffffffff) + var x162 uint64 + var x163 uint64 + x163, x162 = bits.Mul64(x160, 0x4000000000000000) + var x164 uint64 + var x165 uint64 + x165, x164 = bits.Mul64(x160, 0x224698fc0994a8dd) + var x166 uint64 + var x167 uint64 + x167, x166 = bits.Mul64(x160, 0x8c46eb2100000001) + var x168 uint64 + var x169 fiat_pasta_fq_uint1 + x168, x169 = fiat_pasta_fq_addcarryx_u64(x167, x164, 0x0) + x170 := (uint64(x169) + x165) + var x172 fiat_pasta_fq_uint1 + _, x172 = fiat_pasta_fq_addcarryx_u64(x150, x166, 0x0) + var x173 uint64 + var x174 fiat_pasta_fq_uint1 + x173, x174 = fiat_pasta_fq_addcarryx_u64(x152, x168, x172) + var x175 uint64 + var x176 fiat_pasta_fq_uint1 + x175, x176 = fiat_pasta_fq_addcarryx_u64(x154, x170, x174) + var x177 uint64 + var x178 fiat_pasta_fq_uint1 + x177, x178 = fiat_pasta_fq_addcarryx_u64(x156, x162, x176) + var x179 uint64 + var x180 fiat_pasta_fq_uint1 + x179, x180 = fiat_pasta_fq_addcarryx_u64(x158, x163, x178) + x181 := (uint64(x180) + uint64(x159)) + var x182 uint64 + var x183 fiat_pasta_fq_uint1 + x182, x183 = fiat_pasta_fq_subborrowx_u64(x173, 0x8c46eb2100000001, 0x0) + var x184 uint64 + var x185 fiat_pasta_fq_uint1 + x184, x185 = fiat_pasta_fq_subborrowx_u64(x175, 0x224698fc0994a8dd, x183) + var x186 uint64 + var x187 fiat_pasta_fq_uint1 + x186, x187 = fiat_pasta_fq_subborrowx_u64(x177, uint64(0x0), x185) + var x188 uint64 + var x189 fiat_pasta_fq_uint1 + x188, x189 = fiat_pasta_fq_subborrowx_u64(x179, 0x4000000000000000, x187) + var x191 fiat_pasta_fq_uint1 + _, x191 = fiat_pasta_fq_subborrowx_u64(x181, uint64(0x0), x189) + var x192 uint64 + fiat_pasta_fq_cmovznz_u64(&x192, x191, x182, x173) + var x193 uint64 + fiat_pasta_fq_cmovznz_u64(&x193, x191, x184, x175) + var x194 uint64 + fiat_pasta_fq_cmovznz_u64(&x194, x191, x186, x177) + var x195 uint64 + fiat_pasta_fq_cmovznz_u64(&x195, x191, x188, x179) + out1[0] = x192 + out1[1] = x193 + out1[2] = x194 + out1[3] = x195 +} + +// The function fiat_pasta_fq_add adds two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fq_add(out1 *fiat_pasta_fq_montgomery_domain_field_element, arg1 *fiat_pasta_fq_montgomery_domain_field_element, arg2 *fiat_pasta_fq_montgomery_domain_field_element) { + var x1 uint64 + var x2 fiat_pasta_fq_uint1 + x1, x2 = fiat_pasta_fq_addcarryx_u64(arg1[0], arg2[0], 0x0) + var x3 uint64 + var x4 fiat_pasta_fq_uint1 + x3, x4 = fiat_pasta_fq_addcarryx_u64(arg1[1], arg2[1], x2) + var x5 uint64 + var x6 fiat_pasta_fq_uint1 + x5, x6 = fiat_pasta_fq_addcarryx_u64(arg1[2], arg2[2], x4) + var x7 uint64 + var x8 fiat_pasta_fq_uint1 + x7, x8 = fiat_pasta_fq_addcarryx_u64(arg1[3], arg2[3], x6) + var x9 uint64 + var x10 fiat_pasta_fq_uint1 + x9, x10 = fiat_pasta_fq_subborrowx_u64(x1, 0x8c46eb2100000001, 0x0) + var x11 uint64 + var x12 fiat_pasta_fq_uint1 + x11, x12 = fiat_pasta_fq_subborrowx_u64(x3, 0x224698fc0994a8dd, x10) + var x13 uint64 + var x14 fiat_pasta_fq_uint1 + x13, x14 = fiat_pasta_fq_subborrowx_u64(x5, uint64(0x0), x12) + var x15 uint64 + var x16 fiat_pasta_fq_uint1 + x15, x16 = fiat_pasta_fq_subborrowx_u64(x7, 0x4000000000000000, x14) + var x18 fiat_pasta_fq_uint1 + _, x18 = fiat_pasta_fq_subborrowx_u64(uint64(x8), uint64(0x0), x16) + var x19 uint64 + fiat_pasta_fq_cmovznz_u64(&x19, x18, x9, x1) + var x20 uint64 + fiat_pasta_fq_cmovznz_u64(&x20, x18, x11, x3) + var x21 uint64 + fiat_pasta_fq_cmovznz_u64(&x21, x18, x13, x5) + var x22 uint64 + fiat_pasta_fq_cmovznz_u64(&x22, x18, x15, x7) + out1[0] = x19 + out1[1] = x20 + out1[2] = x21 + out1[3] = x22 +} + +// The function fiat_pasta_fq_sub subtracts two field elements in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// 0 ≤ eval arg2 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fq_sub(out1 *fiat_pasta_fq_montgomery_domain_field_element, arg1 *fiat_pasta_fq_montgomery_domain_field_element, arg2 *fiat_pasta_fq_montgomery_domain_field_element) { + var x1 uint64 + var x2 fiat_pasta_fq_uint1 + x1, x2 = fiat_pasta_fq_subborrowx_u64(arg1[0], arg2[0], 0x0) + var x3 uint64 + var x4 fiat_pasta_fq_uint1 + x3, x4 = fiat_pasta_fq_subborrowx_u64(arg1[1], arg2[1], x2) + var x5 uint64 + var x6 fiat_pasta_fq_uint1 + x5, x6 = fiat_pasta_fq_subborrowx_u64(arg1[2], arg2[2], x4) + var x7 uint64 + var x8 fiat_pasta_fq_uint1 + x7, x8 = fiat_pasta_fq_subborrowx_u64(arg1[3], arg2[3], x6) + var x9 uint64 + fiat_pasta_fq_cmovznz_u64(&x9, x8, uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 fiat_pasta_fq_uint1 + x10, x11 = fiat_pasta_fq_addcarryx_u64(x1, (x9 & 0x8c46eb2100000001), 0x0) + var x12 uint64 + var x13 fiat_pasta_fq_uint1 + x12, x13 = fiat_pasta_fq_addcarryx_u64(x3, (x9 & 0x224698fc0994a8dd), x11) + var x14 uint64 + var x15 fiat_pasta_fq_uint1 + x14, x15 = fiat_pasta_fq_addcarryx_u64(x5, uint64(0x0), x13) + var x16 uint64 + x16, _ = fiat_pasta_fq_addcarryx_u64(x7, (x9 & 0x4000000000000000), x15) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// The function fiat_pasta_fq_opp negates a field element in the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fq_opp(out1 *fiat_pasta_fq_montgomery_domain_field_element, arg1 *fiat_pasta_fq_montgomery_domain_field_element) { + var x1 uint64 + var x2 fiat_pasta_fq_uint1 + x1, x2 = fiat_pasta_fq_subborrowx_u64(uint64(0x0), arg1[0], 0x0) + var x3 uint64 + var x4 fiat_pasta_fq_uint1 + x3, x4 = fiat_pasta_fq_subborrowx_u64(uint64(0x0), arg1[1], x2) + var x5 uint64 + var x6 fiat_pasta_fq_uint1 + x5, x6 = fiat_pasta_fq_subborrowx_u64(uint64(0x0), arg1[2], x4) + var x7 uint64 + var x8 fiat_pasta_fq_uint1 + x7, x8 = fiat_pasta_fq_subborrowx_u64(uint64(0x0), arg1[3], x6) + var x9 uint64 + fiat_pasta_fq_cmovznz_u64(&x9, x8, uint64(0x0), 0xffffffffffffffff) + var x10 uint64 + var x11 fiat_pasta_fq_uint1 + x10, x11 = fiat_pasta_fq_addcarryx_u64(x1, (x9 & 0x8c46eb2100000001), 0x0) + var x12 uint64 + var x13 fiat_pasta_fq_uint1 + x12, x13 = fiat_pasta_fq_addcarryx_u64(x3, (x9 & 0x224698fc0994a8dd), x11) + var x14 uint64 + var x15 fiat_pasta_fq_uint1 + x14, x15 = fiat_pasta_fq_addcarryx_u64(x5, uint64(0x0), x13) + var x16 uint64 + x16, _ = fiat_pasta_fq_addcarryx_u64(x7, (x9 & 0x4000000000000000), x15) + out1[0] = x10 + out1[1] = x12 + out1[2] = x14 + out1[3] = x16 +} + +// The function fiat_pasta_fq_from_montgomery translates a field element out of the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fq_from_montgomery(out1 *fiat_pasta_fq_non_montgomery_domain_field_element, arg1 *fiat_pasta_fq_montgomery_domain_field_element) { + x1 := arg1[0] + var x2 uint64 + _, x2 = bits.Mul64(x1, 0x8c46eb20ffffffff) + var x4 uint64 + var x5 uint64 + x5, x4 = bits.Mul64(x2, 0x4000000000000000) + var x6 uint64 + var x7 uint64 + x7, x6 = bits.Mul64(x2, 0x224698fc0994a8dd) + var x8 uint64 + var x9 uint64 + x9, x8 = bits.Mul64(x2, 0x8c46eb2100000001) + var x10 uint64 + var x11 fiat_pasta_fq_uint1 + x10, x11 = fiat_pasta_fq_addcarryx_u64(x9, x6, 0x0) + var x13 fiat_pasta_fq_uint1 + _, x13 = fiat_pasta_fq_addcarryx_u64(x1, x8, 0x0) + var x14 uint64 + var x15 fiat_pasta_fq_uint1 + x14, x15 = fiat_pasta_fq_addcarryx_u64(uint64(0x0), x10, x13) + var x16 uint64 + var x17 fiat_pasta_fq_uint1 + x16, x17 = fiat_pasta_fq_addcarryx_u64(x14, arg1[1], 0x0) + var x18 uint64 + _, x18 = bits.Mul64(x16, 0x8c46eb20ffffffff) + var x20 uint64 + var x21 uint64 + x21, x20 = bits.Mul64(x18, 0x4000000000000000) + var x22 uint64 + var x23 uint64 + x23, x22 = bits.Mul64(x18, 0x224698fc0994a8dd) + var x24 uint64 + var x25 uint64 + x25, x24 = bits.Mul64(x18, 0x8c46eb2100000001) + var x26 uint64 + var x27 fiat_pasta_fq_uint1 + x26, x27 = fiat_pasta_fq_addcarryx_u64(x25, x22, 0x0) + var x29 fiat_pasta_fq_uint1 + _, x29 = fiat_pasta_fq_addcarryx_u64(x16, x24, 0x0) + var x30 uint64 + var x31 fiat_pasta_fq_uint1 + x30, x31 = fiat_pasta_fq_addcarryx_u64((uint64(x17) + (uint64(x15) + (uint64(x11) + x7))), x26, x29) + var x32 uint64 + var x33 fiat_pasta_fq_uint1 + x32, x33 = fiat_pasta_fq_addcarryx_u64(x4, (uint64(x27) + x23), x31) + var x34 uint64 + var x35 fiat_pasta_fq_uint1 + x34, x35 = fiat_pasta_fq_addcarryx_u64(x5, x20, x33) + var x36 uint64 + var x37 fiat_pasta_fq_uint1 + x36, x37 = fiat_pasta_fq_addcarryx_u64(x30, arg1[2], 0x0) + var x38 uint64 + var x39 fiat_pasta_fq_uint1 + x38, x39 = fiat_pasta_fq_addcarryx_u64(x32, uint64(0x0), x37) + var x40 uint64 + var x41 fiat_pasta_fq_uint1 + x40, x41 = fiat_pasta_fq_addcarryx_u64(x34, uint64(0x0), x39) + var x42 uint64 + _, x42 = bits.Mul64(x36, 0x8c46eb20ffffffff) + var x44 uint64 + var x45 uint64 + x45, x44 = bits.Mul64(x42, 0x4000000000000000) + var x46 uint64 + var x47 uint64 + x47, x46 = bits.Mul64(x42, 0x224698fc0994a8dd) + var x48 uint64 + var x49 uint64 + x49, x48 = bits.Mul64(x42, 0x8c46eb2100000001) + var x50 uint64 + var x51 fiat_pasta_fq_uint1 + x50, x51 = fiat_pasta_fq_addcarryx_u64(x49, x46, 0x0) + var x53 fiat_pasta_fq_uint1 + _, x53 = fiat_pasta_fq_addcarryx_u64(x36, x48, 0x0) + var x54 uint64 + var x55 fiat_pasta_fq_uint1 + x54, x55 = fiat_pasta_fq_addcarryx_u64(x38, x50, x53) + var x56 uint64 + var x57 fiat_pasta_fq_uint1 + x56, x57 = fiat_pasta_fq_addcarryx_u64(x40, (uint64(x51) + x47), x55) + var x58 uint64 + var x59 fiat_pasta_fq_uint1 + x58, x59 = fiat_pasta_fq_addcarryx_u64((uint64(x41) + (uint64(x35) + x21)), x44, x57) + var x60 uint64 + var x61 fiat_pasta_fq_uint1 + x60, x61 = fiat_pasta_fq_addcarryx_u64(x54, arg1[3], 0x0) + var x62 uint64 + var x63 fiat_pasta_fq_uint1 + x62, x63 = fiat_pasta_fq_addcarryx_u64(x56, uint64(0x0), x61) + var x64 uint64 + var x65 fiat_pasta_fq_uint1 + x64, x65 = fiat_pasta_fq_addcarryx_u64(x58, uint64(0x0), x63) + var x66 uint64 + _, x66 = bits.Mul64(x60, 0x8c46eb20ffffffff) + var x68 uint64 + var x69 uint64 + x69, x68 = bits.Mul64(x66, 0x4000000000000000) + var x70 uint64 + var x71 uint64 + x71, x70 = bits.Mul64(x66, 0x224698fc0994a8dd) + var x72 uint64 + var x73 uint64 + x73, x72 = bits.Mul64(x66, 0x8c46eb2100000001) + var x74 uint64 + var x75 fiat_pasta_fq_uint1 + x74, x75 = fiat_pasta_fq_addcarryx_u64(x73, x70, 0x0) + var x77 fiat_pasta_fq_uint1 + _, x77 = fiat_pasta_fq_addcarryx_u64(x60, x72, 0x0) + var x78 uint64 + var x79 fiat_pasta_fq_uint1 + x78, x79 = fiat_pasta_fq_addcarryx_u64(x62, x74, x77) + var x80 uint64 + var x81 fiat_pasta_fq_uint1 + x80, x81 = fiat_pasta_fq_addcarryx_u64(x64, (uint64(x75) + x71), x79) + var x82 uint64 + var x83 fiat_pasta_fq_uint1 + x82, x83 = fiat_pasta_fq_addcarryx_u64((uint64(x65) + (uint64(x59) + x45)), x68, x81) + x84 := (uint64(x83) + x69) + var x85 uint64 + var x86 fiat_pasta_fq_uint1 + x85, x86 = fiat_pasta_fq_subborrowx_u64(x78, 0x8c46eb2100000001, 0x0) + var x87 uint64 + var x88 fiat_pasta_fq_uint1 + x87, x88 = fiat_pasta_fq_subborrowx_u64(x80, 0x224698fc0994a8dd, x86) + var x89 uint64 + var x90 fiat_pasta_fq_uint1 + x89, x90 = fiat_pasta_fq_subborrowx_u64(x82, uint64(0x0), x88) + var x91 uint64 + var x92 fiat_pasta_fq_uint1 + x91, x92 = fiat_pasta_fq_subborrowx_u64(x84, 0x4000000000000000, x90) + var x94 fiat_pasta_fq_uint1 + _, x94 = fiat_pasta_fq_subborrowx_u64(uint64(0x0), uint64(0x0), x92) + var x95 uint64 + fiat_pasta_fq_cmovznz_u64(&x95, x94, x85, x78) + var x96 uint64 + fiat_pasta_fq_cmovznz_u64(&x96, x94, x87, x80) + var x97 uint64 + fiat_pasta_fq_cmovznz_u64(&x97, x94, x89, x82) + var x98 uint64 + fiat_pasta_fq_cmovznz_u64(&x98, x94, x91, x84) + out1[0] = x95 + out1[1] = x96 + out1[2] = x97 + out1[3] = x98 +} + +// The function fiat_pasta_fq_to_montgomery translates a field element into the Montgomery domain. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// eval (from_montgomery out1) mod m = eval arg1 mod m +// 0 ≤ eval out1 < m +func fiat_pasta_fq_to_montgomery(out1 *fiat_pasta_fq_montgomery_domain_field_element, arg1 *fiat_pasta_fq_non_montgomery_domain_field_element) { + x1 := arg1[1] + x2 := arg1[2] + x3 := arg1[3] + x4 := arg1[0] + var x5 uint64 + var x6 uint64 + x6, x5 = bits.Mul64(x4, 0x96d41af7ccfdaa9) + var x7 uint64 + var x8 uint64 + x8, x7 = bits.Mul64(x4, 0x7fae231004ccf590) + var x9 uint64 + var x10 uint64 + x10, x9 = bits.Mul64(x4, 0x67bb433d891a16e3) + var x11 uint64 + var x12 uint64 + x12, x11 = bits.Mul64(x4, 0xfc9678ff0000000f) + var x13 uint64 + var x14 fiat_pasta_fq_uint1 + x13, x14 = fiat_pasta_fq_addcarryx_u64(x12, x9, 0x0) + var x15 uint64 + var x16 fiat_pasta_fq_uint1 + x15, x16 = fiat_pasta_fq_addcarryx_u64(x10, x7, x14) + var x17 uint64 + var x18 fiat_pasta_fq_uint1 + x17, x18 = fiat_pasta_fq_addcarryx_u64(x8, x5, x16) + var x19 uint64 + _, x19 = bits.Mul64(x11, 0x8c46eb20ffffffff) + var x21 uint64 + var x22 uint64 + x22, x21 = bits.Mul64(x19, 0x4000000000000000) + var x23 uint64 + var x24 uint64 + x24, x23 = bits.Mul64(x19, 0x224698fc0994a8dd) + var x25 uint64 + var x26 uint64 + x26, x25 = bits.Mul64(x19, 0x8c46eb2100000001) + var x27 uint64 + var x28 fiat_pasta_fq_uint1 + x27, x28 = fiat_pasta_fq_addcarryx_u64(x26, x23, 0x0) + var x30 fiat_pasta_fq_uint1 + _, x30 = fiat_pasta_fq_addcarryx_u64(x11, x25, 0x0) + var x31 uint64 + var x32 fiat_pasta_fq_uint1 + x31, x32 = fiat_pasta_fq_addcarryx_u64(x13, x27, x30) + var x33 uint64 + var x34 fiat_pasta_fq_uint1 + x33, x34 = fiat_pasta_fq_addcarryx_u64(x15, (uint64(x28) + x24), x32) + var x35 uint64 + var x36 fiat_pasta_fq_uint1 + x35, x36 = fiat_pasta_fq_addcarryx_u64(x17, x21, x34) + var x37 uint64 + var x38 uint64 + x38, x37 = bits.Mul64(x1, 0x96d41af7ccfdaa9) + var x39 uint64 + var x40 uint64 + x40, x39 = bits.Mul64(x1, 0x7fae231004ccf590) + var x41 uint64 + var x42 uint64 + x42, x41 = bits.Mul64(x1, 0x67bb433d891a16e3) + var x43 uint64 + var x44 uint64 + x44, x43 = bits.Mul64(x1, 0xfc9678ff0000000f) + var x45 uint64 + var x46 fiat_pasta_fq_uint1 + x45, x46 = fiat_pasta_fq_addcarryx_u64(x44, x41, 0x0) + var x47 uint64 + var x48 fiat_pasta_fq_uint1 + x47, x48 = fiat_pasta_fq_addcarryx_u64(x42, x39, x46) + var x49 uint64 + var x50 fiat_pasta_fq_uint1 + x49, x50 = fiat_pasta_fq_addcarryx_u64(x40, x37, x48) + var x51 uint64 + var x52 fiat_pasta_fq_uint1 + x51, x52 = fiat_pasta_fq_addcarryx_u64(x31, x43, 0x0) + var x53 uint64 + var x54 fiat_pasta_fq_uint1 + x53, x54 = fiat_pasta_fq_addcarryx_u64(x33, x45, x52) + var x55 uint64 + var x56 fiat_pasta_fq_uint1 + x55, x56 = fiat_pasta_fq_addcarryx_u64(x35, x47, x54) + var x57 uint64 + var x58 fiat_pasta_fq_uint1 + x57, x58 = fiat_pasta_fq_addcarryx_u64(((uint64(x36) + (uint64(x18) + x6)) + x22), x49, x56) + var x59 uint64 + _, x59 = bits.Mul64(x51, 0x8c46eb20ffffffff) + var x61 uint64 + var x62 uint64 + x62, x61 = bits.Mul64(x59, 0x4000000000000000) + var x63 uint64 + var x64 uint64 + x64, x63 = bits.Mul64(x59, 0x224698fc0994a8dd) + var x65 uint64 + var x66 uint64 + x66, x65 = bits.Mul64(x59, 0x8c46eb2100000001) + var x67 uint64 + var x68 fiat_pasta_fq_uint1 + x67, x68 = fiat_pasta_fq_addcarryx_u64(x66, x63, 0x0) + var x70 fiat_pasta_fq_uint1 + _, x70 = fiat_pasta_fq_addcarryx_u64(x51, x65, 0x0) + var x71 uint64 + var x72 fiat_pasta_fq_uint1 + x71, x72 = fiat_pasta_fq_addcarryx_u64(x53, x67, x70) + var x73 uint64 + var x74 fiat_pasta_fq_uint1 + x73, x74 = fiat_pasta_fq_addcarryx_u64(x55, (uint64(x68) + x64), x72) + var x75 uint64 + var x76 fiat_pasta_fq_uint1 + x75, x76 = fiat_pasta_fq_addcarryx_u64(x57, x61, x74) + var x77 uint64 + var x78 uint64 + x78, x77 = bits.Mul64(x2, 0x96d41af7ccfdaa9) + var x79 uint64 + var x80 uint64 + x80, x79 = bits.Mul64(x2, 0x7fae231004ccf590) + var x81 uint64 + var x82 uint64 + x82, x81 = bits.Mul64(x2, 0x67bb433d891a16e3) + var x83 uint64 + var x84 uint64 + x84, x83 = bits.Mul64(x2, 0xfc9678ff0000000f) + var x85 uint64 + var x86 fiat_pasta_fq_uint1 + x85, x86 = fiat_pasta_fq_addcarryx_u64(x84, x81, 0x0) + var x87 uint64 + var x88 fiat_pasta_fq_uint1 + x87, x88 = fiat_pasta_fq_addcarryx_u64(x82, x79, x86) + var x89 uint64 + var x90 fiat_pasta_fq_uint1 + x89, x90 = fiat_pasta_fq_addcarryx_u64(x80, x77, x88) + var x91 uint64 + var x92 fiat_pasta_fq_uint1 + x91, x92 = fiat_pasta_fq_addcarryx_u64(x71, x83, 0x0) + var x93 uint64 + var x94 fiat_pasta_fq_uint1 + x93, x94 = fiat_pasta_fq_addcarryx_u64(x73, x85, x92) + var x95 uint64 + var x96 fiat_pasta_fq_uint1 + x95, x96 = fiat_pasta_fq_addcarryx_u64(x75, x87, x94) + var x97 uint64 + var x98 fiat_pasta_fq_uint1 + x97, x98 = fiat_pasta_fq_addcarryx_u64(((uint64(x76) + (uint64(x58) + (uint64(x50) + x38))) + x62), x89, x96) + var x99 uint64 + _, x99 = bits.Mul64(x91, 0x8c46eb20ffffffff) + var x101 uint64 + var x102 uint64 + x102, x101 = bits.Mul64(x99, 0x4000000000000000) + var x103 uint64 + var x104 uint64 + x104, x103 = bits.Mul64(x99, 0x224698fc0994a8dd) + var x105 uint64 + var x106 uint64 + x106, x105 = bits.Mul64(x99, 0x8c46eb2100000001) + var x107 uint64 + var x108 fiat_pasta_fq_uint1 + x107, x108 = fiat_pasta_fq_addcarryx_u64(x106, x103, 0x0) + var x110 fiat_pasta_fq_uint1 + _, x110 = fiat_pasta_fq_addcarryx_u64(x91, x105, 0x0) + var x111 uint64 + var x112 fiat_pasta_fq_uint1 + x111, x112 = fiat_pasta_fq_addcarryx_u64(x93, x107, x110) + var x113 uint64 + var x114 fiat_pasta_fq_uint1 + x113, x114 = fiat_pasta_fq_addcarryx_u64(x95, (uint64(x108) + x104), x112) + var x115 uint64 + var x116 fiat_pasta_fq_uint1 + x115, x116 = fiat_pasta_fq_addcarryx_u64(x97, x101, x114) + var x117 uint64 + var x118 uint64 + x118, x117 = bits.Mul64(x3, 0x96d41af7ccfdaa9) + var x119 uint64 + var x120 uint64 + x120, x119 = bits.Mul64(x3, 0x7fae231004ccf590) + var x121 uint64 + var x122 uint64 + x122, x121 = bits.Mul64(x3, 0x67bb433d891a16e3) + var x123 uint64 + var x124 uint64 + x124, x123 = bits.Mul64(x3, 0xfc9678ff0000000f) + var x125 uint64 + var x126 fiat_pasta_fq_uint1 + x125, x126 = fiat_pasta_fq_addcarryx_u64(x124, x121, 0x0) + var x127 uint64 + var x128 fiat_pasta_fq_uint1 + x127, x128 = fiat_pasta_fq_addcarryx_u64(x122, x119, x126) + var x129 uint64 + var x130 fiat_pasta_fq_uint1 + x129, x130 = fiat_pasta_fq_addcarryx_u64(x120, x117, x128) + var x131 uint64 + var x132 fiat_pasta_fq_uint1 + x131, x132 = fiat_pasta_fq_addcarryx_u64(x111, x123, 0x0) + var x133 uint64 + var x134 fiat_pasta_fq_uint1 + x133, x134 = fiat_pasta_fq_addcarryx_u64(x113, x125, x132) + var x135 uint64 + var x136 fiat_pasta_fq_uint1 + x135, x136 = fiat_pasta_fq_addcarryx_u64(x115, x127, x134) + var x137 uint64 + var x138 fiat_pasta_fq_uint1 + x137, x138 = fiat_pasta_fq_addcarryx_u64(((uint64(x116) + (uint64(x98) + (uint64(x90) + x78))) + x102), x129, x136) + var x139 uint64 + _, x139 = bits.Mul64(x131, 0x8c46eb20ffffffff) + var x141 uint64 + var x142 uint64 + x142, x141 = bits.Mul64(x139, 0x4000000000000000) + var x143 uint64 + var x144 uint64 + x144, x143 = bits.Mul64(x139, 0x224698fc0994a8dd) + var x145 uint64 + var x146 uint64 + x146, x145 = bits.Mul64(x139, 0x8c46eb2100000001) + var x147 uint64 + var x148 fiat_pasta_fq_uint1 + x147, x148 = fiat_pasta_fq_addcarryx_u64(x146, x143, 0x0) + var x150 fiat_pasta_fq_uint1 + _, x150 = fiat_pasta_fq_addcarryx_u64(x131, x145, 0x0) + var x151 uint64 + var x152 fiat_pasta_fq_uint1 + x151, x152 = fiat_pasta_fq_addcarryx_u64(x133, x147, x150) + var x153 uint64 + var x154 fiat_pasta_fq_uint1 + x153, x154 = fiat_pasta_fq_addcarryx_u64(x135, (uint64(x148) + x144), x152) + var x155 uint64 + var x156 fiat_pasta_fq_uint1 + x155, x156 = fiat_pasta_fq_addcarryx_u64(x137, x141, x154) + x157 := ((uint64(x156) + (uint64(x138) + (uint64(x130) + x118))) + x142) + var x158 uint64 + var x159 fiat_pasta_fq_uint1 + x158, x159 = fiat_pasta_fq_subborrowx_u64(x151, 0x8c46eb2100000001, 0x0) + var x160 uint64 + var x161 fiat_pasta_fq_uint1 + x160, x161 = fiat_pasta_fq_subborrowx_u64(x153, 0x224698fc0994a8dd, x159) + var x162 uint64 + var x163 fiat_pasta_fq_uint1 + x162, x163 = fiat_pasta_fq_subborrowx_u64(x155, uint64(0x0), x161) + var x164 uint64 + var x165 fiat_pasta_fq_uint1 + x164, x165 = fiat_pasta_fq_subborrowx_u64(x157, 0x4000000000000000, x163) + var x167 fiat_pasta_fq_uint1 + _, x167 = fiat_pasta_fq_subborrowx_u64(uint64(0x0), uint64(0x0), x165) + var x168 uint64 + fiat_pasta_fq_cmovznz_u64(&x168, x167, x158, x151) + var x169 uint64 + fiat_pasta_fq_cmovznz_u64(&x169, x167, x160, x153) + var x170 uint64 + fiat_pasta_fq_cmovznz_u64(&x170, x167, x162, x155) + var x171 uint64 + fiat_pasta_fq_cmovznz_u64(&x171, x167, x164, x157) + out1[0] = x168 + out1[1] = x169 + out1[2] = x170 + out1[3] = x171 +} + +// The function fiat_pasta_fq_selectznz is a multi-limb conditional select. +// +// Postconditions: +// +// eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) +// +// Input Bounds: +// +// arg1: [0x0 ~> 0x1] +// arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] +func fiat_pasta_fq_selectznz(out1 *[4]uint64, arg1 fiat_pasta_fq_uint1, arg2 *[4]uint64, arg3 *[4]uint64) { + var x1 uint64 + fiat_pasta_fq_cmovznz_u64(&x1, arg1, arg2[0], arg3[0]) + var x2 uint64 + fiat_pasta_fq_cmovznz_u64(&x2, arg1, arg2[1], arg3[1]) + var x3 uint64 + fiat_pasta_fq_cmovznz_u64(&x3, arg1, arg2[2], arg3[2]) + var x4 uint64 + fiat_pasta_fq_cmovznz_u64(&x4, arg1, arg2[3], arg3[3]) + out1[0] = x1 + out1[1] = x2 + out1[2] = x3 + out1[3] = x4 +} + +// The function fiat_pasta_fq_to_bytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ eval arg1 < m +// +// Postconditions: +// +// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x7fffffffffffffff]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] +func fiat_pasta_fq_to_bytes(out1 *[32]uint8, arg1 *[4]uint64) { + x1 := arg1[3] + x2 := arg1[2] + x3 := arg1[1] + x4 := arg1[0] + x5 := (uint8(x4) & 0xff) + x6 := (x4 >> 8) + x7 := (uint8(x6) & 0xff) + x8 := (x6 >> 8) + x9 := (uint8(x8) & 0xff) + x10 := (x8 >> 8) + x11 := (uint8(x10) & 0xff) + x12 := (x10 >> 8) + x13 := (uint8(x12) & 0xff) + x14 := (x12 >> 8) + x15 := (uint8(x14) & 0xff) + x16 := (x14 >> 8) + x17 := (uint8(x16) & 0xff) + x18 := uint8((x16 >> 8)) + x19 := (uint8(x3) & 0xff) + x20 := (x3 >> 8) + x21 := (uint8(x20) & 0xff) + x22 := (x20 >> 8) + x23 := (uint8(x22) & 0xff) + x24 := (x22 >> 8) + x25 := (uint8(x24) & 0xff) + x26 := (x24 >> 8) + x27 := (uint8(x26) & 0xff) + x28 := (x26 >> 8) + x29 := (uint8(x28) & 0xff) + x30 := (x28 >> 8) + x31 := (uint8(x30) & 0xff) + x32 := uint8((x30 >> 8)) + x33 := (uint8(x2) & 0xff) + x34 := (x2 >> 8) + x35 := (uint8(x34) & 0xff) + x36 := (x34 >> 8) + x37 := (uint8(x36) & 0xff) + x38 := (x36 >> 8) + x39 := (uint8(x38) & 0xff) + x40 := (x38 >> 8) + x41 := (uint8(x40) & 0xff) + x42 := (x40 >> 8) + x43 := (uint8(x42) & 0xff) + x44 := (x42 >> 8) + x45 := (uint8(x44) & 0xff) + x46 := uint8((x44 >> 8)) + x47 := (uint8(x1) & 0xff) + x48 := (x1 >> 8) + x49 := (uint8(x48) & 0xff) + x50 := (x48 >> 8) + x51 := (uint8(x50) & 0xff) + x52 := (x50 >> 8) + x53 := (uint8(x52) & 0xff) + x54 := (x52 >> 8) + x55 := (uint8(x54) & 0xff) + x56 := (x54 >> 8) + x57 := (uint8(x56) & 0xff) + x58 := (x56 >> 8) + x59 := (uint8(x58) & 0xff) + x60 := uint8((x58 >> 8)) + out1[0] = x5 + out1[1] = x7 + out1[2] = x9 + out1[3] = x11 + out1[4] = x13 + out1[5] = x15 + out1[6] = x17 + out1[7] = x18 + out1[8] = x19 + out1[9] = x21 + out1[10] = x23 + out1[11] = x25 + out1[12] = x27 + out1[13] = x29 + out1[14] = x31 + out1[15] = x32 + out1[16] = x33 + out1[17] = x35 + out1[18] = x37 + out1[19] = x39 + out1[20] = x41 + out1[21] = x43 + out1[22] = x45 + out1[23] = x46 + out1[24] = x47 + out1[25] = x49 + out1[26] = x51 + out1[27] = x53 + out1[28] = x55 + out1[29] = x57 + out1[30] = x59 + out1[31] = x60 +} + +// The function fiat_pasta_fq_from_bytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. +// +// Preconditions: +// +// 0 ≤ bytes_eval arg1 < m +// +// Postconditions: +// +// eval out1 mod m = bytes_eval arg1 mod m +// 0 ≤ eval out1 < m +// +// Input Bounds: +// +// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] +// +// Output Bounds: +// +// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x7fffffffffffffff]] +func fiat_pasta_fq_from_bytes(out1 *[4]uint64, arg1 *[32]uint8) { + x1 := (uint64(arg1[31]) << 56) + x2 := (uint64(arg1[30]) << 48) + x3 := (uint64(arg1[29]) << 40) + x4 := (uint64(arg1[28]) << 32) + x5 := (uint64(arg1[27]) << 24) + x6 := (uint64(arg1[26]) << 16) + x7 := (uint64(arg1[25]) << 8) + x8 := arg1[24] + x9 := (uint64(arg1[23]) << 56) + x10 := (uint64(arg1[22]) << 48) + x11 := (uint64(arg1[21]) << 40) + x12 := (uint64(arg1[20]) << 32) + x13 := (uint64(arg1[19]) << 24) + x14 := (uint64(arg1[18]) << 16) + x15 := (uint64(arg1[17]) << 8) + x16 := arg1[16] + x17 := (uint64(arg1[15]) << 56) + x18 := (uint64(arg1[14]) << 48) + x19 := (uint64(arg1[13]) << 40) + x20 := (uint64(arg1[12]) << 32) + x21 := (uint64(arg1[11]) << 24) + x22 := (uint64(arg1[10]) << 16) + x23 := (uint64(arg1[9]) << 8) + x24 := arg1[8] + x25 := (uint64(arg1[7]) << 56) + x26 := (uint64(arg1[6]) << 48) + x27 := (uint64(arg1[5]) << 40) + x28 := (uint64(arg1[4]) << 32) + x29 := (uint64(arg1[3]) << 24) + x30 := (uint64(arg1[2]) << 16) + x31 := (uint64(arg1[1]) << 8) + x32 := arg1[0] + x33 := (x31 + uint64(x32)) + x34 := (x30 + x33) + x35 := (x29 + x34) + x36 := (x28 + x35) + x37 := (x27 + x36) + x38 := (x26 + x37) + x39 := (x25 + x38) + x40 := (x23 + uint64(x24)) + x41 := (x22 + x40) + x42 := (x21 + x41) + x43 := (x20 + x42) + x44 := (x19 + x43) + x45 := (x18 + x44) + x46 := (x17 + x45) + x47 := (x15 + uint64(x16)) + x48 := (x14 + x47) + x49 := (x13 + x48) + x50 := (x12 + x49) + x51 := (x11 + x50) + x52 := (x10 + x51) + x53 := (x9 + x52) + x54 := (x7 + uint64(x8)) + x55 := (x6 + x54) + x56 := (x5 + x55) + x57 := (x4 + x56) + x58 := (x3 + x57) + x59 := (x2 + x58) + x60 := (x1 + x59) + out1[0] = x39 + out1[1] = x46 + out1[2] = x53 + out1[3] = x60 +} diff --git a/pkg/crypto/core/curves/native/pasta/pallas.go b/pkg/crypto/core/curves/native/pasta/pallas.go new file mode 100755 index 000000000..d90bc3d9d --- /dev/null +++ b/pkg/crypto/core/curves/native/pasta/pallas.go @@ -0,0 +1,7 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package pasta diff --git a/pkg/crypto/core/curves/native/point.go b/pkg/crypto/core/curves/native/point.go new file mode 100755 index 000000000..bf11d2bdc --- /dev/null +++ b/pkg/crypto/core/curves/native/point.go @@ -0,0 +1,468 @@ +package native + +import ( + "crypto/sha256" + "crypto/sha512" + "fmt" + "hash" + "io" + "math/big" + + "github.com/pkg/errors" + "golang.org/x/crypto/blake2b" + "golang.org/x/crypto/sha3" +) + +// EllipticPointHashType is to indicate which expand operation is used +// for hash to curve operations +type EllipticPointHashType uint + +// EllipticPointHashName is to indicate the hash function is used +// for hash to curve operations +type EllipticPointHashName uint + +const ( + // XMD - use ExpandMsgXmd + XMD EllipticPointHashType = iota + // XOF - use ExpandMsgXof + XOF +) + +const ( + SHA256 EllipticPointHashName = iota + SHA512 + SHA3_256 + SHA3_384 + SHA3_512 + BLAKE2B + SHAKE128 + SHAKE256 +) + +// EllipticPoint represents a Weierstrauss elliptic curve point +type EllipticPoint struct { + X *Field + Y *Field + Z *Field + Params *EllipticPointParams + Arithmetic EllipticPointArithmetic +} + +// EllipticPointParams are the Weierstrauss curve parameters +// such as the name, the coefficients the generator point, +// and the prime bit size +type EllipticPointParams struct { + Name string + A *Field + B *Field + Gx *Field + Gy *Field + BitSize int +} + +// EllipticPointHasher is the type of hashing methods for +// hashing byte sequences to curve point. +type EllipticPointHasher struct { + name EllipticPointHashName + hashType EllipticPointHashType + xmd hash.Hash + xof sha3.ShakeHash +} + +// Name returns the hash name for this hasher +func (e *EllipticPointHasher) Name() string { + return e.name.String() +} + +// Type returns the hash type for this hasher +func (e *EllipticPointHasher) Type() EllipticPointHashType { + return e.hashType +} + +// Xmd returns the hash method for ExpandMsgXmd +func (e *EllipticPointHasher) Xmd() hash.Hash { + return e.xmd +} + +// Xof returns the hash method for ExpandMsgXof +func (e *EllipticPointHasher) Xof() sha3.ShakeHash { + return e.xof +} + +// EllipticPointHasherSha256 creates a point hasher that uses Sha256 +func EllipticPointHasherSha256() *EllipticPointHasher { + return &EllipticPointHasher{ + name: SHA256, + hashType: XMD, + xmd: sha256.New(), + } +} + +// EllipticPointHasherSha512 creates a point hasher that uses Sha512 +func EllipticPointHasherSha512() *EllipticPointHasher { + return &EllipticPointHasher{ + name: SHA512, + hashType: XMD, + xmd: sha512.New(), + } +} + +// EllipticPointHasherSha3256 creates a point hasher that uses Sha3256 +func EllipticPointHasherSha3256() *EllipticPointHasher { + return &EllipticPointHasher{ + name: SHA3_256, + hashType: XMD, + xmd: sha3.New256(), + } +} + +// EllipticPointHasherSha3384 creates a point hasher that uses Sha3384 +func EllipticPointHasherSha3384() *EllipticPointHasher { + return &EllipticPointHasher{ + name: SHA3_384, + hashType: XMD, + xmd: sha3.New384(), + } +} + +// EllipticPointHasherSha3512 creates a point hasher that uses Sha3512 +func EllipticPointHasherSha3512() *EllipticPointHasher { + return &EllipticPointHasher{ + name: SHA3_512, + hashType: XMD, + xmd: sha3.New512(), + } +} + +// EllipticPointHasherBlake2b creates a point hasher that uses Blake2b +func EllipticPointHasherBlake2b() *EllipticPointHasher { + h, _ := blake2b.New(64, []byte{}) + return &EllipticPointHasher{ + name: BLAKE2B, + hashType: XMD, + xmd: h, + } +} + +// EllipticPointHasherShake128 creates a point hasher that uses Shake128 +func EllipticPointHasherShake128() *EllipticPointHasher { + return &EllipticPointHasher{ + name: SHAKE128, + hashType: XOF, + xof: sha3.NewShake128(), + } +} + +// EllipticPointHasherShake256 creates a point hasher that uses Shake256 +func EllipticPointHasherShake256() *EllipticPointHasher { + return &EllipticPointHasher{ + name: SHAKE128, + hashType: XOF, + xof: sha3.NewShake256(), + } +} + +// EllipticPointArithmetic are the methods that specific curves +// need to implement for higher abstractions to wrap the point +type EllipticPointArithmetic interface { + // Hash a byte sequence to the curve using the specified hasher + // and dst and store the result in out + Hash(out *EllipticPoint, hasher *EllipticPointHasher, bytes, dst []byte) error + // Double arg and store the result in out + Double(out, arg *EllipticPoint) + // Add arg1 with arg2 and store the result in out + Add(out, arg1, arg2 *EllipticPoint) + // IsOnCurve tests arg if it represents a valid point on the curve + IsOnCurve(arg *EllipticPoint) bool + // ToAffine converts arg to affine coordinates storing the result in out + ToAffine(out, arg *EllipticPoint) + // RhsEq computes the right-hand side of the ecc equation + RhsEq(out, x *Field) +} + +func (t EllipticPointHashType) String() string { + switch t { + case XMD: + return "XMD" + case XOF: + return "XOF" + } + return "unknown" +} + +func (n EllipticPointHashName) String() string { + switch n { + case SHA256: + return "SHA-256" + case SHA512: + return "SHA-512" + case SHA3_256: + return "SHA3-256" + case SHA3_384: + return "SHA3-384" + case SHA3_512: + return "SHA3-512" + case BLAKE2B: + return "BLAKE2b" + case SHAKE128: + return "SHAKE-128" + case SHAKE256: + return "SHAKE-256" + } + return "unknown" +} + +// Random creates a random point on the curve +// from the specified reader +func (p *EllipticPoint) Random(reader io.Reader) (*EllipticPoint, error) { + var seed [WideFieldBytes]byte + n, err := reader.Read(seed[:]) + if err != nil { + return nil, errors.Wrap(err, "random could not read from stream") + } + if n != WideFieldBytes { + return nil, fmt.Errorf("insufficient bytes read %d when %d are needed", n, WideFieldBytes) + } + dst := []byte(fmt.Sprintf("%s_XMD:SHA-256_SSWU_RO_", p.Params.Name)) + err = p.Arithmetic.Hash(p, EllipticPointHasherSha256(), seed[:], dst) + if err != nil { + return nil, errors.Wrap(err, "ecc hash failed") + } + return p, nil +} + +// Hash uses the hasher to map bytes to a valid point +func (p *EllipticPoint) Hash(bytes []byte, hasher *EllipticPointHasher) (*EllipticPoint, error) { + dst := []byte(fmt.Sprintf("%s_%s:%s_SSWU_RO_", p.Params.Name, hasher.hashType, hasher.name)) + err := p.Arithmetic.Hash(p, hasher, bytes, dst) + if err != nil { + return nil, errors.Wrap(err, "hash failed") + } + return p, nil +} + +// Identity returns the identity point +func (p *EllipticPoint) Identity() *EllipticPoint { + p.X.SetZero() + p.Y.SetZero() + p.Z.SetZero() + return p +} + +// Generator returns the base point for the curve +func (p *EllipticPoint) Generator() *EllipticPoint { + p.X.Set(p.Params.Gx) + p.Y.Set(p.Params.Gy) + p.Z.SetOne() + return p +} + +// IsIdentity returns true if this point is at infinity +func (p *EllipticPoint) IsIdentity() bool { + return p.Z.IsZero() == 1 +} + +// Double this point +func (p *EllipticPoint) Double(point *EllipticPoint) *EllipticPoint { + p.Set(point) + p.Arithmetic.Double(p, point) + return p +} + +// Neg negates this point +func (p *EllipticPoint) Neg(point *EllipticPoint) *EllipticPoint { + p.Set(point) + p.Y.Neg(p.Y) + return p +} + +// Add adds the two points +func (p *EllipticPoint) Add(lhs, rhs *EllipticPoint) *EllipticPoint { + p.Set(lhs) + p.Arithmetic.Add(p, lhs, rhs) + return p +} + +// Sub subtracts the two points +func (p *EllipticPoint) Sub(lhs, rhs *EllipticPoint) *EllipticPoint { + p.Set(lhs) + p.Arithmetic.Add(p, lhs, new(EllipticPoint).Neg(rhs)) + return p +} + +// Mul multiplies this point by the input scalar +func (p *EllipticPoint) Mul(point *EllipticPoint, scalar *Field) *EllipticPoint { + bytes := scalar.Bytes() + precomputed := [16]*EllipticPoint{} + precomputed[0] = new(EllipticPoint).Set(point).Identity() + precomputed[1] = new(EllipticPoint).Set(point) + for i := 2; i < 16; i += 2 { + precomputed[i] = new(EllipticPoint).Set(point).Double(precomputed[i>>1]) + precomputed[i+1] = new(EllipticPoint).Set(point).Add(precomputed[i], point) + } + p.Identity() + for i := 0; i < 256; i += 4 { + // Brouwer / windowing method. window size of 4. + for j := 0; j < 4; j++ { + p.Double(p) + } + window := bytes[32-1-i>>3] >> (4 - i&0x04) & 0x0F + p.Add(p, precomputed[window]) + } + return p +} + +// Equal returns 1 if the two points are equal 0 otherwise. +func (p *EllipticPoint) Equal(rhs *EllipticPoint) int { + var x1, x2, y1, y2 Field + + x1.Arithmetic = p.X.Arithmetic + x2.Arithmetic = p.X.Arithmetic + y1.Arithmetic = p.Y.Arithmetic + y2.Arithmetic = p.Y.Arithmetic + + x1.Mul(p.X, rhs.Z) + x2.Mul(rhs.X, p.Z) + + y1.Mul(p.Y, rhs.Z) + y2.Mul(rhs.Y, p.Z) + + e1 := p.Z.IsZero() + e2 := rhs.Z.IsZero() + + // Both at infinity or coordinates are the same + return (e1 & e2) | (^e1 & ^e2)&x1.Equal(&x2)&y1.Equal(&y2) +} + +// Set copies clone into p +func (p *EllipticPoint) Set(clone *EllipticPoint) *EllipticPoint { + p.X = new(Field).Set(clone.X) + p.Y = new(Field).Set(clone.Y) + p.Z = new(Field).Set(clone.Z) + p.Params = clone.Params + p.Arithmetic = clone.Arithmetic + return p +} + +// BigInt returns the x and y as big.Ints in affine +func (p *EllipticPoint) BigInt() (x, y *big.Int) { + t := new(EllipticPoint).Set(p) + p.Arithmetic.ToAffine(t, p) + x = t.X.BigInt() + y = t.Y.BigInt() + return +} + +// SetBigInt creates a point from affine x, y +// and returns the point if it is on the curve +func (p *EllipticPoint) SetBigInt(x, y *big.Int) (*EllipticPoint, error) { + xx := &Field{ + Params: p.Params.Gx.Params, + Arithmetic: p.Params.Gx.Arithmetic, + } + xx.SetBigInt(x) + yy := &Field{ + Params: p.Params.Gx.Params, + Arithmetic: p.Params.Gx.Arithmetic, + } + yy.SetBigInt(y) + pp := new(EllipticPoint).Set(p) + + zero := new(Field).Set(xx).SetZero() + one := new(Field).Set(xx).SetOne() + isIdentity := xx.IsZero() & yy.IsZero() + pp.X = xx.CMove(xx, zero, isIdentity) + pp.Y = yy.CMove(yy, zero, isIdentity) + pp.Z = one.CMove(one, zero, isIdentity) + if !p.Arithmetic.IsOnCurve(pp) && isIdentity == 0 { + return nil, fmt.Errorf("invalid coordinates") + } + return p.Set(pp), nil +} + +// GetX returns the affine X coordinate +func (p *EllipticPoint) GetX() *Field { + t := new(EllipticPoint).Set(p) + p.Arithmetic.ToAffine(t, p) + return t.X +} + +// GetY returns the affine Y coordinate +func (p *EllipticPoint) GetY() *Field { + t := new(EllipticPoint).Set(p) + p.Arithmetic.ToAffine(t, p) + return t.Y +} + +// IsOnCurve determines if this point represents a valid curve point +func (p *EllipticPoint) IsOnCurve() bool { + return p.Arithmetic.IsOnCurve(p) +} + +// ToAffine converts the point into affine coordinates +func (p *EllipticPoint) ToAffine(clone *EllipticPoint) *EllipticPoint { + p.Arithmetic.ToAffine(p, clone) + return p +} + +// SumOfProducts computes the multi-exponentiation for the specified +// points and scalars and stores the result in `p`. +// Returns an error if the lengths of the arguments is not equal. +func (p *EllipticPoint) SumOfProducts(points []*EllipticPoint, scalars []*Field) (*EllipticPoint, error) { + const Upper = 256 + const W = 4 + const Windows = Upper / W // careful--use ceiling division in case this doesn't divide evenly + if len(points) != len(scalars) { + return nil, fmt.Errorf("length mismatch") + } + + bucketSize := 1 << W + windows := make([]*EllipticPoint, Windows) + bytes := make([][32]byte, len(scalars)) + buckets := make([]*EllipticPoint, bucketSize) + + for i, scalar := range scalars { + bytes[i] = scalar.Bytes() + } + for i := range windows { + windows[i] = new(EllipticPoint).Set(p).Identity() + } + + for i := 0; i < bucketSize; i++ { + buckets[i] = new(EllipticPoint).Set(p).Identity() + } + + sum := new(EllipticPoint).Set(p) + + for j := 0; j < len(windows); j++ { + for i := 0; i < bucketSize; i++ { + buckets[i].Identity() + } + + for i := 0; i < len(scalars); i++ { + // j*W to get the nibble + // >> 3 to convert to byte, / 8 + // (W * j & W) gets the nibble, mod W + // 1 << W - 1 to get the offset + index := bytes[i][j*W>>3] >> (W * j & W) & (1< 0; i-- { + sum.Add(sum, buckets[i]) + windows[j].Add(windows[j], sum) + } + } + + p.Identity() + for i := len(windows) - 1; i >= 0; i-- { + for j := 0; j < W; j++ { + p.Double(p) + } + + p.Add(p, windows[i]) + } + return p, nil +} diff --git a/pkg/crypto/core/curves/p256_bench_test.go b/pkg/crypto/core/curves/p256_bench_test.go new file mode 100755 index 000000000..f2c2c8903 --- /dev/null +++ b/pkg/crypto/core/curves/p256_bench_test.go @@ -0,0 +1,756 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/elliptic" + crand "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "fmt" + "io" + "math/big" + "testing" + + "github.com/onsonr/sonr/pkg/crypto/core" +) + +func BenchmarkP256(b *testing.B) { + // 1000 points + + b.Run("1000 point hash - p256", func(b *testing.B) { + b.StopTimer() + points := make([][]byte, 1000) + for i := range points { + t := make([]byte, 32) + _, _ = crand.Read(t) + points[i] = t + } + acc := new(BenchPointP256).Identity() + b.StartTimer() + for _, pt := range points { + acc = acc.Hash(pt) + } + }) + + b.Run("1000 point hash - ct p256", func(b *testing.B) { + b.StopTimer() + points := make([][]byte, 1000) + for i := range points { + t := make([]byte, 32) + _, _ = crand.Read(t) + points[i] = t + } + acc := new(PointP256).Identity() + b.StartTimer() + for _, pt := range points { + acc = acc.Hash(pt) + } + }) + + b.Run("1000 point add - p256", func(b *testing.B) { + b.StopTimer() + points := make([]*BenchPointP256, 1000) + for i := range points { + points[i] = points[i].Random(crand.Reader).(*BenchPointP256) + } + acc := new(BenchPointP256).Identity() + b.StartTimer() + for _, pt := range points { + acc = acc.Add(pt) + } + }) + b.Run("1000 point add - ct p256", func(b *testing.B) { + b.StopTimer() + curve := P256() + points := make([]*PointP256, 1000) + for i := range points { + points[i] = curve.NewIdentityPoint().Random(crand.Reader).(*PointP256) + } + acc := curve.NewIdentityPoint() + b.StartTimer() + for _, pt := range points { + acc = acc.Add(pt) + } + }) + b.Run("1000 point double - p256", func(b *testing.B) { + b.StopTimer() + acc := new(BenchPointP256).Generator() + b.StartTimer() + for i := 0; i < 1000; i++ { + acc = acc.Double() + } + }) + b.Run("1000 point double - ct p256", func(b *testing.B) { + b.StopTimer() + acc := new(PointP256).Generator() + b.StartTimer() + for i := 0; i < 1000; i++ { + acc = acc.Double() + } + }) + b.Run("1000 point multiply - p256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*BenchScalarP256, 1000) + for i := range scalars { + s := new(BenchScalarP256).Random(crand.Reader) + scalars[i] = s.(*BenchScalarP256) + } + acc := new(BenchPointP256).Generator().Mul(new(BenchScalarP256).New(2)) + b.StartTimer() + for _, sc := range scalars { + acc = acc.Mul(sc) + } + }) + b.Run("1000 point multiply - ct p256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*ScalarP256, 1000) + for i := range scalars { + s := new(ScalarP256).Random(crand.Reader) + scalars[i] = s.(*ScalarP256) + } + acc := new(PointP256).Generator() + b.StartTimer() + for _, sc := range scalars { + acc = acc.Mul(sc) + } + }) + b.Run("1000 scalar invert - p256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*BenchScalarP256, 1000) + for i := range scalars { + s := new(BenchScalarP256).Random(crand.Reader) + scalars[i] = s.(*BenchScalarP256) + } + b.StartTimer() + for _, sc := range scalars { + _, _ = sc.Invert() + } + }) + b.Run("1000 scalar invert - ct p256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*ScalarP256, 1000) + for i := range scalars { + s := new(ScalarP256).Random(crand.Reader) + scalars[i] = s.(*ScalarP256) + } + b.StartTimer() + for _, sc := range scalars { + _, _ = sc.Invert() + } + }) + b.Run("1000 scalar sqrt - p256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*BenchScalarP256, 1000) + for i := range scalars { + s := new(BenchScalarP256).Random(crand.Reader) + scalars[i] = s.(*BenchScalarP256) + } + b.StartTimer() + for _, sc := range scalars { + _, _ = sc.Sqrt() + } + }) + b.Run("1000 scalar sqrt - ct p256", func(b *testing.B) { + b.StopTimer() + scalars := make([]*ScalarP256, 1000) + for i := range scalars { + s := new(ScalarP256).Random(crand.Reader) + scalars[i] = s.(*ScalarP256) + } + b.StartTimer() + for _, sc := range scalars { + _, _ = sc.Sqrt() + } + }) +} + +type BenchScalarP256 struct { + value *big.Int +} + +type BenchPointP256 struct { + x, y *big.Int +} + +func (s *BenchScalarP256) Random(reader io.Reader) Scalar { + if reader == nil { + return nil + } + var seed [64]byte + _, _ = reader.Read(seed[:]) + return s.Hash(seed[:]) +} + +func (s *BenchScalarP256) Hash(bytes []byte) Scalar { + xmd, err := expandMsgXmd(sha256.New(), bytes, []byte("P256_XMD:SHA-256_SSWU_RO_"), 48) + if err != nil { + return nil + } + v := new(big.Int).SetBytes(xmd) + return &BenchScalarP256{ + value: v.Mod(v, elliptic.P256().Params().N), + } +} + +func (s *BenchScalarP256) Zero() Scalar { + return &BenchScalarP256{ + value: big.NewInt(0), + } +} + +func (s *BenchScalarP256) One() Scalar { + return &BenchScalarP256{ + value: big.NewInt(1), + } +} + +func (s *BenchScalarP256) IsZero() bool { + return subtle.ConstantTimeCompare(s.value.Bytes(), []byte{}) == 1 +} + +func (s *BenchScalarP256) IsOne() bool { + return subtle.ConstantTimeCompare(s.value.Bytes(), []byte{1}) == 1 +} + +func (s *BenchScalarP256) IsOdd() bool { + return s.value.Bit(0) == 1 +} + +func (s *BenchScalarP256) IsEven() bool { + return s.value.Bit(0) == 0 +} + +func (s *BenchScalarP256) New(value int) Scalar { + v := big.NewInt(int64(value)) + if value < 0 { + v.Mod(v, elliptic.P256().Params().N) + } + return &BenchScalarP256{ + value: v, + } +} + +func (s *BenchScalarP256) Cmp(rhs Scalar) int { + r, ok := rhs.(*BenchScalarP256) + if ok { + return s.value.Cmp(r.value) + } else { + return -2 + } +} + +func (s *BenchScalarP256) Square() Scalar { + return &BenchScalarP256{ + value: new(big.Int).Exp(s.value, big.NewInt(2), elliptic.P256().Params().N), + } +} + +func (s *BenchScalarP256) Double() Scalar { + v := new(big.Int).Add(s.value, s.value) + return &BenchScalarP256{ + value: v.Mod(v, elliptic.P256().Params().N), + } +} + +func (s *BenchScalarP256) Invert() (Scalar, error) { + return &BenchScalarP256{ + value: new(big.Int).ModInverse(s.value, elliptic.P256().Params().N), + }, nil +} + +func (s *BenchScalarP256) Sqrt() (Scalar, error) { + return &BenchScalarP256{ + value: new(big.Int).ModSqrt(s.value, elliptic.P256().Params().N), + }, nil +} + +func (s *BenchScalarP256) Cube() Scalar { + return &BenchScalarP256{ + value: new(big.Int).Exp(s.value, big.NewInt(3), elliptic.P256().Params().N), + } +} + +func (s *BenchScalarP256) Add(rhs Scalar) Scalar { + r, ok := rhs.(*BenchScalarP256) + if ok { + v := new(big.Int).Add(s.value, r.value) + return &BenchScalarP256{ + value: v.Mod(v, elliptic.P256().Params().N), + } + } else { + return nil + } +} + +func (s *BenchScalarP256) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*BenchScalarP256) + if ok { + v := new(big.Int).Sub(s.value, r.value) + return &BenchScalarP256{ + value: v.Mod(v, elliptic.P256().Params().N), + } + } else { + return nil + } +} + +func (s *BenchScalarP256) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*BenchScalarP256) + if ok { + v := new(big.Int).Mul(s.value, r.value) + return &BenchScalarP256{ + value: v.Mod(v, elliptic.P256().Params().N), + } + } else { + return nil + } +} + +func (s *BenchScalarP256) MulAdd(y, z Scalar) Scalar { + return s.Mul(y).Add(z) +} + +func (s *BenchScalarP256) Div(rhs Scalar) Scalar { + n := elliptic.P256().Params().N + r, ok := rhs.(*BenchScalarP256) + if ok { + v := new(big.Int).ModInverse(r.value, n) + v.Mul(v, s.value) + return &BenchScalarP256{ + value: v.Mod(v, n), + } + } else { + return nil + } +} + +func (s *BenchScalarP256) Neg() Scalar { + z := new(big.Int).Neg(s.value) + return &BenchScalarP256{ + value: z.Mod(z, elliptic.P256().Params().N), + } +} + +func (s *BenchScalarP256) SetBigInt(v *big.Int) (Scalar, error) { + if v == nil { + return nil, fmt.Errorf("invalid value") + } + t := new(big.Int).Mod(v, elliptic.P256().Params().N) + if t.Cmp(v) != 0 { + return nil, fmt.Errorf("invalid value") + } + return &BenchScalarP256{ + value: t, + }, nil +} + +func (s *BenchScalarP256) BigInt() *big.Int { + return new(big.Int).Set(s.value) +} + +func (s *BenchScalarP256) Bytes() []byte { + var out [32]byte + return s.value.FillBytes(out[:]) +} + +func (s *BenchScalarP256) SetBytes(bytes []byte) (Scalar, error) { + value := new(big.Int).SetBytes(bytes) + t := new(big.Int).Mod(value, elliptic.P256().Params().N) + if t.Cmp(value) != 0 { + return nil, fmt.Errorf("invalid byte sequence") + } + return &BenchScalarP256{ + value: t, + }, nil +} + +func (s *BenchScalarP256) SetBytesWide(bytes []byte) (Scalar, error) { + if len(bytes) < 32 || len(bytes) > 128 { + return nil, fmt.Errorf("invalid byte sequence") + } + value := new(big.Int).SetBytes(bytes) + value.Mod(value, elliptic.P256().Params().N) + return &BenchScalarP256{ + value, + }, nil +} + +func (s *BenchScalarP256) Point() Point { + return new(BenchPointP256).Identity() +} + +func (s *BenchScalarP256) Clone() Scalar { + return &BenchScalarP256{ + value: new(big.Int).Set(s.value), + } +} + +func (s *BenchScalarP256) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *BenchScalarP256) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*BenchScalarP256) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *BenchScalarP256) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *BenchScalarP256) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*BenchScalarP256) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *BenchScalarP256) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *BenchScalarP256) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*BenchScalarP256) + if !ok { + return fmt.Errorf("invalid type") + } + s.value = S.value + return nil +} + +func (p *BenchPointP256) Random(reader io.Reader) Point { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *BenchPointP256) Hash(bytes []byte) Point { + curve := elliptic.P256() + + domain := []byte("P256_XMD:SHA-256_SSWU_RO_") + uniformBytes, _ := expandMsgXmd(sha256.New(), bytes, domain, 96) + + u0 := new(big.Int).SetBytes(uniformBytes[:48]) + u1 := new(big.Int).SetBytes(uniformBytes[48:]) + + u0.Mod(u0, curve.Params().P) + u1.Mod(u1, curve.Params().P) + + ssParams := p256SswuParams() + q0x, q0y := osswu3mod4(u0, ssParams) + q1x, q1y := osswu3mod4(u1, ssParams) + + x, y := curve.Add(q0x, q0y, q1x, q1y) + + return &BenchPointP256{ + x, y, + } +} + +func (p *BenchPointP256) Identity() Point { + return &BenchPointP256{ + x: big.NewInt(0), y: big.NewInt(0), + } +} + +func (p *BenchPointP256) Generator() Point { + curve := elliptic.P256().Params() + return &BenchPointP256{ + x: new(big.Int).Set(curve.Gx), + y: new(big.Int).Set(curve.Gy), + } +} + +func (p *BenchPointP256) IsIdentity() bool { + x := core.ConstantTimeEqByte(p.x, core.Zero) + y := core.ConstantTimeEqByte(p.y, core.Zero) + return (x & y) == 1 +} + +func (p *BenchPointP256) IsNegative() bool { + return p.y.Bit(0) == 1 +} + +func (p *BenchPointP256) IsOnCurve() bool { + return elliptic.P256().IsOnCurve(p.x, p.y) +} + +func (p *BenchPointP256) Double() Point { + curve := elliptic.P256() + x, y := curve.Double(p.x, p.y) + return &BenchPointP256{x, y} +} + +func (p *BenchPointP256) Scalar() Scalar { + return new(BenchScalarP256).Zero() +} + +func (p *BenchPointP256) Neg() Point { + y := new(big.Int).Sub(elliptic.P256().Params().P, p.y) + y.Mod(y, elliptic.P256().Params().P) + return &BenchPointP256{x: p.x, y: y} +} + +func (p *BenchPointP256) Add(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*BenchPointP256) + if ok { + x, y := elliptic.P256().Add(p.x, p.y, r.x, r.y) + return &BenchPointP256{x, y} + } else { + return nil + } +} + +func (p *BenchPointP256) Sub(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.Neg().(*BenchPointP256) + if ok { + x, y := elliptic.P256().Add(p.x, p.y, r.x, r.y) + return &BenchPointP256{x, y} + } else { + return nil + } +} + +func (p *BenchPointP256) Mul(rhs Scalar) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*BenchScalarP256) + if ok { + x, y := elliptic.P256().ScalarMult(p.x, p.y, r.value.Bytes()) + return &BenchPointP256{x, y} + } else { + return nil + } +} + +func (p *BenchPointP256) Equal(rhs Point) bool { + r, ok := rhs.(*BenchPointP256) + if ok { + x := core.ConstantTimeEqByte(p.x, r.x) + y := core.ConstantTimeEqByte(p.y, r.y) + return (x & y) == 1 + } else { + return false + } +} + +func (p *BenchPointP256) Set(x, y *big.Int) (Point, error) { + // check is identity or on curve + xx := subtle.ConstantTimeCompare(x.Bytes(), []byte{}) + yy := subtle.ConstantTimeCompare(y.Bytes(), []byte{}) + // Checks are constant time + onCurve := elliptic.P256().IsOnCurve(x, y) + if !onCurve && (xx&yy) != 1 { + return nil, fmt.Errorf("invalid coordinates") + } + x = new(big.Int).Set(x) + y = new(big.Int).Set(y) + return &BenchPointP256{x, y}, nil +} + +func (p *BenchPointP256) ToAffineCompressed() []byte { + var x [33]byte + x[0] = byte(2) + x[0] |= byte(p.y.Bit(0)) + p.x.FillBytes(x[1:]) + return x[:] +} + +func (p *BenchPointP256) ToAffineUncompressed() []byte { + var out [65]byte + out[0] = byte(4) + p.x.FillBytes(out[1:33]) + p.y.FillBytes(out[33:]) + return out[:] +} + +func (p *BenchPointP256) FromAffineCompressed(bytes []byte) (Point, error) { + if len(bytes) != 33 { + return nil, fmt.Errorf("invalid byte sequence") + } + sign := int(bytes[0]) + if sign != 2 && sign != 3 { + return nil, fmt.Errorf("invalid sign byte") + } + sign &= 0x1 + + x := new(big.Int).SetBytes(bytes[1:]) + rhs := rhsP256(x, elliptic.P256().Params()) + // test that rhs is quadratic residue + // if not, then this Point is at infinity + y := new(big.Int).ModSqrt(rhs, elliptic.P256().Params().P) + if y != nil { + // fix the sign + if int(y.Bit(0)) != sign { + y.Neg(y) + y.Mod(y, elliptic.P256().Params().P) + } + } else { + x = new(big.Int) + y = new(big.Int) + } + return &BenchPointP256{ + x, y, + }, nil +} + +func (p *BenchPointP256) FromAffineUncompressed(bytes []byte) (Point, error) { + if len(bytes) != 65 { + return nil, fmt.Errorf("invalid byte sequence") + } + if bytes[0] != 4 { + return nil, fmt.Errorf("invalid sign byte") + } + x := new(big.Int).SetBytes(bytes[1:33]) + y := new(big.Int).SetBytes(bytes[33:]) + return &BenchPointP256{x, y}, nil +} + +func (p *BenchPointP256) CurveName() string { + return elliptic.P256().Params().Name +} + +func (p *BenchPointP256) SumOfProducts(points []Point, scalars []Scalar) Point { + nScalars := make([]*big.Int, len(scalars)) + for i, sc := range scalars { + s, ok := sc.(*BenchScalarP256) + if !ok { + return nil + } + nScalars[i] = s.value + } + return sumOfProductsPippenger(points, nScalars) +} + +func (p *BenchPointP256) X() *big.Int { + return new(big.Int).Set(p.x) +} + +func (p *BenchPointP256) Y() *big.Int { + return new(big.Int).Set(p.y) +} + +func (p *BenchPointP256) Params() *elliptic.CurveParams { + return elliptic.P256().Params() +} + +func (p *BenchPointP256) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *BenchPointP256) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*BenchPointP256) + if !ok { + return fmt.Errorf("invalid point") + } + p.x = ppt.x + p.y = ppt.y + return nil +} + +func (p *BenchPointP256) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *BenchPointP256) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*BenchPointP256) + if !ok { + return fmt.Errorf("invalid point") + } + p.x = ppt.x + p.y = ppt.y + return nil +} + +func (p *BenchPointP256) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *BenchPointP256) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*BenchPointP256) + if !ok { + return fmt.Errorf("invalid type") + } + p.x = P.x + p.y = P.y + return nil +} + +// From https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-8.2 +func p256SswuParams() *sswuParams { + params := elliptic.P256().Params() + + // c1 = (q - 3) / 4 + c1 := new(big.Int).Set(params.P) + c1.Sub(c1, big.NewInt(3)) + c1.Rsh(c1, 2) + + a := big.NewInt(-3) + a.Mod(a, params.P) + b := new(big.Int).Set(params.B) + z := big.NewInt(-10) + z.Mod(z, params.P) + // sqrt(-Z^3) + zTmp := new(big.Int).Exp(z, big.NewInt(3), nil) + zTmp = zTmp.Neg(zTmp) + zTmp.Mod(zTmp, params.P) + c2 := new(big.Int).ModSqrt(zTmp, params.P) + + return &sswuParams{ + params, c1, c2, a, b, z, + } +} + +// rhs of the curve equation +func rhsP256(x *big.Int, params *elliptic.CurveParams) *big.Int { + f := NewField(params.P) + r := f.NewElement(x) + r2 := r.Mul(r) + + // x^3-3x+B + a := r.Mul(f.NewElement(big.NewInt(3))) + r = r2.Mul(r) + return r.Add(a.Neg()).Add(f.NewElement(params.B)).Value +} diff --git a/pkg/crypto/core/curves/p256_curve.go b/pkg/crypto/core/curves/p256_curve.go new file mode 100755 index 000000000..15930c051 --- /dev/null +++ b/pkg/crypto/core/curves/p256_curve.go @@ -0,0 +1,668 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/elliptic" + "fmt" + "io" + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + p256n "github.com/onsonr/sonr/pkg/crypto/core/curves/native/p256" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/p256/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/p256/fq" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + oldP256InitOnce sync.Once + oldP256 NistP256 +) + +type NistP256 struct { + *elliptic.CurveParams +} + +func oldP256InitAll() { + curve := elliptic.P256() + oldP256.CurveParams = curve.Params() + oldP256.P = curve.Params().P + oldP256.N = curve.Params().N + oldP256.Gx = curve.Params().Gx + oldP256.Gy = curve.Params().Gy + oldP256.B = curve.Params().B + oldP256.BitSize = curve.Params().BitSize + oldP256.Name = curve.Params().Name +} + +func NistP256Curve() *NistP256 { + oldP256InitOnce.Do(oldP256InitAll) + return &oldP256 +} + +func (curve *NistP256) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +func (curve *NistP256) IsOnCurve(x, y *big.Int) bool { + _, err := p256n.P256PointNew().SetBigInt(x, y) + return err == nil +} + +func (curve *NistP256) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + p1, err := p256n.P256PointNew().SetBigInt(x1, y1) + if err != nil { + return nil, nil + } + p2, err := p256n.P256PointNew().SetBigInt(x2, y2) + if err != nil { + return nil, nil + } + return p1.Add(p1, p2).BigInt() +} + +func (curve *NistP256) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + p1, err := p256n.P256PointNew().SetBigInt(x1, y1) + if err != nil { + return nil, nil + } + return p1.Double(p1).BigInt() +} + +func (curve *NistP256) ScalarMul(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + p1, err := p256n.P256PointNew().SetBigInt(Bx, By) + if err != nil { + return nil, nil + } + var bytes [32]byte + copy(bytes[:], internal.ReverseScalarBytes(k)) + s, err := fq.P256FqNew().SetBytes(&bytes) + if err != nil { + return nil, nil + } + return p1.Mul(p1, s).BigInt() +} + +func (curve *NistP256) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + var bytes [32]byte + copy(bytes[:], internal.ReverseScalarBytes(k)) + s, err := fq.P256FqNew().SetBytes(&bytes) + if err != nil { + return nil, nil + } + p1 := p256n.P256PointNew().Generator() + return p1.Mul(p1, s).BigInt() +} + +type ScalarP256 struct { + value *native.Field +} + +type PointP256 struct { + value *native.EllipticPoint +} + +func (s *ScalarP256) Random(reader io.Reader) Scalar { + if reader == nil { + return nil + } + var seed [64]byte + _, _ = reader.Read(seed[:]) + return s.Hash(seed[:]) +} + +func (s *ScalarP256) Hash(bytes []byte) Scalar { + dst := []byte("P256_XMD:SHA-256_SSWU_RO_") + xmd := native.ExpandMsgXmd(native.EllipticPointHasherSha256(), bytes, dst, 48) + var t [64]byte + copy(t[:48], internal.ReverseScalarBytes(xmd)) + + return &ScalarP256{ + value: fq.P256FqNew().SetBytesWide(&t), + } +} + +func (s *ScalarP256) Zero() Scalar { + return &ScalarP256{ + value: fq.P256FqNew().SetZero(), + } +} + +func (s *ScalarP256) One() Scalar { + return &ScalarP256{ + value: fq.P256FqNew().SetOne(), + } +} + +func (s *ScalarP256) IsZero() bool { + return s.value.IsZero() == 1 +} + +func (s *ScalarP256) IsOne() bool { + return s.value.IsOne() == 1 +} + +func (s *ScalarP256) IsOdd() bool { + return s.value.Bytes()[0]&1 == 1 +} + +func (s *ScalarP256) IsEven() bool { + return s.value.Bytes()[0]&1 == 0 +} + +func (s *ScalarP256) New(value int) Scalar { + t := fq.P256FqNew() + v := big.NewInt(int64(value)) + if value < 0 { + v.Mod(v, t.Params.BiModulus) + } + return &ScalarP256{ + value: t.SetBigInt(v), + } +} + +func (s *ScalarP256) Cmp(rhs Scalar) int { + r, ok := rhs.(*ScalarP256) + if ok { + return s.value.Cmp(r.value) + } else { + return -2 + } +} + +func (s *ScalarP256) Square() Scalar { + return &ScalarP256{ + value: fq.P256FqNew().Square(s.value), + } +} + +func (s *ScalarP256) Double() Scalar { + return &ScalarP256{ + value: fq.P256FqNew().Double(s.value), + } +} + +func (s *ScalarP256) Invert() (Scalar, error) { + value, wasInverted := fq.P256FqNew().Invert(s.value) + if !wasInverted { + return nil, fmt.Errorf("inverse doesn't exist") + } + return &ScalarP256{ + value, + }, nil +} + +func (s *ScalarP256) Sqrt() (Scalar, error) { + value, wasSquare := fq.P256FqNew().Sqrt(s.value) + if !wasSquare { + return nil, fmt.Errorf("not a square") + } + return &ScalarP256{ + value, + }, nil +} + +func (s *ScalarP256) Cube() Scalar { + value := fq.P256FqNew().Mul(s.value, s.value) + value.Mul(value, s.value) + return &ScalarP256{ + value, + } +} + +func (s *ScalarP256) Add(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarP256) + if ok { + return &ScalarP256{ + value: fq.P256FqNew().Add(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarP256) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarP256) + if ok { + return &ScalarP256{ + value: fq.P256FqNew().Sub(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarP256) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarP256) + if ok { + return &ScalarP256{ + value: fq.P256FqNew().Mul(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarP256) MulAdd(y, z Scalar) Scalar { + return s.Mul(y).Add(z) +} + +func (s *ScalarP256) Div(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarP256) + if ok { + v, wasInverted := fq.P256FqNew().Invert(r.value) + if !wasInverted { + return nil + } + v.Mul(v, s.value) + return &ScalarP256{value: v} + } else { + return nil + } +} + +func (s *ScalarP256) Neg() Scalar { + return &ScalarP256{ + value: fq.P256FqNew().Neg(s.value), + } +} + +func (s *ScalarP256) SetBigInt(v *big.Int) (Scalar, error) { + if v == nil { + return nil, fmt.Errorf("'v' cannot be nil") + } + value := fq.P256FqNew().SetBigInt(v) + return &ScalarP256{ + value, + }, nil +} + +func (s *ScalarP256) BigInt() *big.Int { + return s.value.BigInt() +} + +func (s *ScalarP256) Bytes() []byte { + t := s.value.Bytes() + return internal.ReverseScalarBytes(t[:]) +} + +func (s *ScalarP256) SetBytes(bytes []byte) (Scalar, error) { + if len(bytes) != 32 { + return nil, fmt.Errorf("invalid length") + } + var seq [32]byte + copy(seq[:], internal.ReverseScalarBytes(bytes)) + value, err := fq.P256FqNew().SetBytes(&seq) + if err != nil { + return nil, err + } + return &ScalarP256{ + value, + }, nil +} + +func (s *ScalarP256) SetBytesWide(bytes []byte) (Scalar, error) { + if len(bytes) != 64 { + return nil, fmt.Errorf("invalid length") + } + var seq [64]byte + copy(seq[:], bytes) + return &ScalarP256{ + value: fq.P256FqNew().SetBytesWide(&seq), + }, nil +} + +func (s *ScalarP256) Point() Point { + return new(PointP256).Identity() +} + +func (s *ScalarP256) Clone() Scalar { + return &ScalarP256{ + value: fq.P256FqNew().Set(s.value), + } +} + +func (s *ScalarP256) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *ScalarP256) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarP256) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarP256) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *ScalarP256) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarP256) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarP256) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *ScalarP256) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*ScalarP256) + if !ok { + return fmt.Errorf("invalid type") + } + s.value = S.value + return nil +} + +func (p *PointP256) Random(reader io.Reader) Point { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *PointP256) Hash(bytes []byte) Point { + value, err := p256n.P256PointNew().Hash(bytes, native.EllipticPointHasherSha256()) + // TODO: change hash to return an error also + if err != nil { + return nil + } + + return &PointP256{value} +} + +func (p *PointP256) Identity() Point { + return &PointP256{ + value: p256n.P256PointNew().Identity(), + } +} + +func (p *PointP256) Generator() Point { + return &PointP256{ + value: p256n.P256PointNew().Generator(), + } +} + +func (p *PointP256) IsIdentity() bool { + return p.value.IsIdentity() +} + +func (p *PointP256) IsNegative() bool { + return p.value.GetY().Value[0]&1 == 1 +} + +func (p *PointP256) IsOnCurve() bool { + return p.value.IsOnCurve() +} + +func (p *PointP256) Double() Point { + value := p256n.P256PointNew().Double(p.value) + return &PointP256{value} +} + +func (p *PointP256) Scalar() Scalar { + return new(ScalarP256).Zero() +} + +func (p *PointP256) Neg() Point { + value := p256n.P256PointNew().Neg(p.value) + return &PointP256{value} +} + +func (p *PointP256) Add(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointP256) + if ok { + value := p256n.P256PointNew().Add(p.value, r.value) + return &PointP256{value} + } else { + return nil + } +} + +func (p *PointP256) Sub(rhs Point) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*PointP256) + if ok { + value := p256n.P256PointNew().Sub(p.value, r.value) + return &PointP256{value} + } else { + return nil + } +} + +func (p *PointP256) Mul(rhs Scalar) Point { + if rhs == nil { + return nil + } + r, ok := rhs.(*ScalarP256) + if ok { + value := p256n.P256PointNew().Mul(p.value, r.value) + return &PointP256{value} + } else { + return nil + } +} + +func (p *PointP256) Equal(rhs Point) bool { + r, ok := rhs.(*PointP256) + if ok { + return p.value.Equal(r.value) == 1 + } else { + return false + } +} + +func (p *PointP256) Set(x, y *big.Int) (Point, error) { + value, err := p256n.P256PointNew().SetBigInt(x, y) + if err != nil { + return nil, err + } + return &PointP256{value}, nil +} + +func (p *PointP256) ToAffineCompressed() []byte { + var x [33]byte + x[0] = byte(2) + + t := p256n.P256PointNew().ToAffine(p.value) + + x[0] |= t.Y.Bytes()[0] & 1 + + xBytes := t.X.Bytes() + copy(x[1:], internal.ReverseScalarBytes(xBytes[:])) + return x[:] +} + +func (p *PointP256) ToAffineUncompressed() []byte { + var out [65]byte + out[0] = byte(4) + t := p256n.P256PointNew().ToAffine(p.value) + arr := t.X.Bytes() + copy(out[1:33], internal.ReverseScalarBytes(arr[:])) + arr = t.Y.Bytes() + copy(out[33:], internal.ReverseScalarBytes(arr[:])) + return out[:] +} + +func (p *PointP256) FromAffineCompressed(bytes []byte) (Point, error) { + var raw [native.FieldBytes]byte + if len(bytes) != 33 { + return nil, fmt.Errorf("invalid byte sequence") + } + sign := int(bytes[0]) + if sign != 2 && sign != 3 { + return nil, fmt.Errorf("invalid sign byte") + } + sign &= 0x1 + + copy(raw[:], internal.ReverseScalarBytes(bytes[1:])) + x, err := fp.P256FpNew().SetBytes(&raw) + if err != nil { + return nil, err + } + + value := p256n.P256PointNew().Identity() + rhs := fp.P256FpNew() + p.value.Arithmetic.RhsEq(rhs, x) + // test that rhs is quadratic residue + // if not, then this Point is at infinity + y, wasQr := fp.P256FpNew().Sqrt(rhs) + if wasQr { + // fix the sign + sigY := int(y.Bytes()[0] & 1) + if sigY != sign { + y.Neg(y) + } + value.X = x + value.Y = y + value.Z.SetOne() + } + return &PointP256{value}, nil +} + +func (p *PointP256) FromAffineUncompressed(bytes []byte) (Point, error) { + var arr [native.FieldBytes]byte + if len(bytes) != 65 { + return nil, fmt.Errorf("invalid byte sequence") + } + if bytes[0] != 4 { + return nil, fmt.Errorf("invalid sign byte") + } + + copy(arr[:], internal.ReverseScalarBytes(bytes[1:33])) + x, err := fp.P256FpNew().SetBytes(&arr) + if err != nil { + return nil, err + } + copy(arr[:], internal.ReverseScalarBytes(bytes[33:])) + y, err := fp.P256FpNew().SetBytes(&arr) + if err != nil { + return nil, err + } + value := p256n.P256PointNew() + value.X = x + value.Y = y + value.Z.SetOne() + return &PointP256{value}, nil +} + +func (p *PointP256) CurveName() string { + return elliptic.P256().Params().Name +} + +func (p *PointP256) SumOfProducts(points []Point, scalars []Scalar) Point { + nPoints := make([]*native.EllipticPoint, len(points)) + nScalars := make([]*native.Field, len(scalars)) + for i, pt := range points { + ptv, ok := pt.(*PointP256) + if !ok { + return nil + } + nPoints[i] = ptv.value + } + for i, sc := range scalars { + s, ok := sc.(*ScalarP256) + if !ok { + return nil + } + nScalars[i] = s.value + } + value := p256n.P256PointNew() + _, err := value.SumOfProducts(nPoints, nScalars) + if err != nil { + return nil + } + return &PointP256{value} +} + +func (p *PointP256) X() *native.Field { + return p.value.GetX() +} + +func (p *PointP256) Y() *native.Field { + return p.value.GetY() +} + +func (p *PointP256) Params() *elliptic.CurveParams { + return elliptic.P256().Params() +} + +func (p *PointP256) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *PointP256) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointP256) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointP256) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *PointP256) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointP256) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointP256) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *PointP256) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*PointP256) + if !ok { + return fmt.Errorf("invalid type") + } + p.value = P.value + return nil +} diff --git a/pkg/crypto/core/curves/p256_curve_test.go b/pkg/crypto/core/curves/p256_curve_test.go new file mode 100755 index 000000000..d05de6f6c --- /dev/null +++ b/pkg/crypto/core/curves/p256_curve_test.go @@ -0,0 +1,365 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/elliptic" + crand "crypto/rand" + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestScalarP256Random(t *testing.T) { + p256 := P256() + sc := p256.Scalar.Random(testRng()) + s, ok := sc.(*ScalarP256) + require.True(t, ok) + expected := bhex("02ca487e56f8cb1ad9666027b2282d1159792d39a5e05f0bc696f85de5acc6d4") + require.Equal(t, s.value.BigInt(), expected) + // Try 10 random values + for i := 0; i < 10; i++ { + sc := p256.Scalar.Random(crand.Reader) + _, ok := sc.(*ScalarP256) + require.True(t, ok) + require.True(t, !sc.IsZero()) + } +} + +func TestScalarP256Hash(t *testing.T) { + var b [32]byte + p256 := P256() + sc := p256.Scalar.Hash(b[:]) + s, ok := sc.(*ScalarP256) + require.True(t, ok) + expected := bhex("43ca74a23022b221e60c8499781afff2a2776ec23362712df90a3080b5557f90") + require.Equal(t, s.value.BigInt(), expected) +} + +func TestScalarP256Zero(t *testing.T) { + p256 := P256() + sc := p256.Scalar.Zero() + require.True(t, sc.IsZero()) + require.True(t, sc.IsEven()) +} + +func TestScalarP256One(t *testing.T) { + p256 := P256() + sc := p256.Scalar.One() + require.True(t, sc.IsOne()) + require.True(t, sc.IsOdd()) +} + +func TestScalarP256New(t *testing.T) { + p256 := P256() + three := p256.Scalar.New(3) + require.True(t, three.IsOdd()) + four := p256.Scalar.New(4) + require.True(t, four.IsEven()) + neg1 := p256.Scalar.New(-1) + require.True(t, neg1.IsEven()) + neg2 := p256.Scalar.New(-2) + require.True(t, neg2.IsOdd()) +} + +func TestScalarP256Square(t *testing.T) { + p256 := P256() + three := p256.Scalar.New(3) + nine := p256.Scalar.New(9) + require.Equal(t, three.Square().Cmp(nine), 0) +} + +func TestScalarP256Cube(t *testing.T) { + p256 := P256() + three := p256.Scalar.New(3) + twentySeven := p256.Scalar.New(27) + require.Equal(t, three.Cube().Cmp(twentySeven), 0) +} + +func TestScalarP256Double(t *testing.T) { + p256 := P256() + three := p256.Scalar.New(3) + six := p256.Scalar.New(6) + require.Equal(t, three.Double().Cmp(six), 0) +} + +func TestScalarP256Neg(t *testing.T) { + p256 := P256() + one := p256.Scalar.One() + neg1 := p256.Scalar.New(-1) + require.Equal(t, one.Neg().Cmp(neg1), 0) + lotsOfThrees := p256.Scalar.New(333333) + expected := p256.Scalar.New(-333333) + require.Equal(t, lotsOfThrees.Neg().Cmp(expected), 0) +} + +func TestScalarP256Invert(t *testing.T) { + p256 := P256() + nine := p256.Scalar.New(9) + actual, _ := nine.Invert() + sa, _ := actual.(*ScalarP256) + bn := bhex("8e38e38daaaaaaab38e38e38e38e38e368f2197ceb0d1f2d6af570a536e1bf66") + expected, err := p256.Scalar.SetBigInt(bn) + require.NoError(t, err) + require.Equal(t, sa.Cmp(expected), 0) +} + +func TestScalarP256Sqrt(t *testing.T) { + p256 := P256() + nine := p256.Scalar.New(9) + actual, err := nine.Sqrt() + sa, _ := actual.(*ScalarP256) + expected := p256.Scalar.New(3) + require.NoError(t, err) + require.Equal(t, sa.Cmp(expected), 0) +} + +func TestScalarP256Add(t *testing.T) { + p256 := P256() + nine := p256.Scalar.New(9) + six := p256.Scalar.New(6) + fifteen := nine.Add(six) + require.NotNil(t, fifteen) + expected := p256.Scalar.New(15) + require.Equal(t, expected.Cmp(fifteen), 0) + n := new(big.Int).Set(elliptic.P256().Params().N) + n.Sub(n, big.NewInt(3)) + + upper, err := p256.Scalar.SetBigInt(n) + require.NoError(t, err) + actual := upper.Add(nine) + require.NotNil(t, actual) + require.Equal(t, actual.Cmp(six), 0) +} + +func TestScalarP256Sub(t *testing.T) { + p256 := P256() + nine := p256.Scalar.New(9) + six := p256.Scalar.New(6) + n := new(big.Int).Set(elliptic.P256().Params().N) + n.Sub(n, big.NewInt(3)) + + expected, err := p256.Scalar.SetBigInt(n) + require.NoError(t, err) + actual := six.Sub(nine) + require.Equal(t, expected.Cmp(actual), 0) + + actual = nine.Sub(six) + require.Equal(t, actual.Cmp(p256.Scalar.New(3)), 0) +} + +func TestScalarP256Mul(t *testing.T) { + p256 := P256() + nine := p256.Scalar.New(9) + six := p256.Scalar.New(6) + actual := nine.Mul(six) + require.Equal(t, actual.Cmp(p256.Scalar.New(54)), 0) + n := new(big.Int).Set(elliptic.P256().Params().N) + n.Sub(n, big.NewInt(1)) + upper, err := p256.Scalar.SetBigInt(n) + require.NoError(t, err) + require.Equal(t, upper.Mul(upper).Cmp(p256.Scalar.New(1)), 0) +} + +func TestScalarP256Div(t *testing.T) { + p256 := P256() + nine := p256.Scalar.New(9) + actual := nine.Div(nine) + require.Equal(t, actual.Cmp(p256.Scalar.New(1)), 0) + require.Equal(t, p256.Scalar.New(54).Div(nine).Cmp(p256.Scalar.New(6)), 0) +} + +func TestScalarP256Serialize(t *testing.T) { + p256 := P256() + sc := p256.Scalar.New(255) + sequence := sc.Bytes() + require.Equal(t, len(sequence), 32) + require.Equal(t, sequence, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff}) + ret, err := p256.Scalar.SetBytes(sequence) + require.NoError(t, err) + require.Equal(t, ret.Cmp(sc), 0) + + // Try 10 random values + for i := 0; i < 10; i++ { + sc = p256.Scalar.Random(crand.Reader) + sequence = sc.Bytes() + require.Equal(t, len(sequence), 32) + ret, err = p256.Scalar.SetBytes(sequence) + require.NoError(t, err) + require.Equal(t, ret.Cmp(sc), 0) + } +} + +func TestScalarP256Nil(t *testing.T) { + p256 := P256() + one := p256.Scalar.New(1) + require.Nil(t, one.Add(nil)) + require.Nil(t, one.Sub(nil)) + require.Nil(t, one.Mul(nil)) + require.Nil(t, one.Div(nil)) + require.Nil(t, p256.Scalar.Random(nil)) + require.Equal(t, one.Cmp(nil), -2) + _, err := p256.Scalar.SetBigInt(nil) + require.Error(t, err) +} + +func TestPointP256Random(t *testing.T) { + p256 := P256() + sc := p256.Point.Random(testRng()) + s, ok := sc.(*PointP256) + require.True(t, ok) + expectedX, _ := new(big.Int).SetString("7d31a079d75687cd0dd1118996f726c3e4d52806a5124d23c1faeee9fadb2201", 16) + expectedY, _ := new(big.Int).SetString("da62629181a0e2ec6943c263bbe81f53d87cb94d0039a707309f415f04d47bab", 16) + require.Equal(t, s.X().BigInt(), expectedX) + require.Equal(t, s.Y().BigInt(), expectedY) + // Try 10 random values + for i := 0; i < 10; i++ { + sc := p256.Point.Random(crand.Reader) + _, ok := sc.(*PointP256) + require.True(t, ok) + require.True(t, !sc.IsIdentity()) + } +} + +func TestPointP256Hash(t *testing.T) { + var b [32]byte + p256 := P256() + sc := p256.Point.Hash(b[:]) + s, ok := sc.(*PointP256) + require.True(t, ok) + expectedX, _ := new(big.Int).SetString("10f1699c24cf20f5322b92bfab4fdf14814ee1472ffc6b1ef2ec36be3051925d", 16) + expectedY, _ := new(big.Int).SetString("99efe055f13c3e5e3fc65be12043a89d0482b806c7a9945c276b7aee887c1de0", 16) + require.Equal(t, s.X().BigInt(), expectedX) + require.Equal(t, s.Y().BigInt(), expectedY) +} + +func TestPointP256Identity(t *testing.T) { + p256 := P256() + sc := p256.Point.Identity() + require.True(t, sc.IsIdentity()) + require.Equal(t, sc.ToAffineCompressed(), []byte{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) +} + +func TestPointP256Generator(t *testing.T) { + p256 := P256() + sc := p256.Point.Generator() + s, ok := sc.(*PointP256) + require.True(t, ok) + require.Equal(t, s.X().BigInt(), elliptic.P256().Params().Gx) + require.Equal(t, s.Y().BigInt(), elliptic.P256().Params().Gy) +} + +func TestPointP256Set(t *testing.T) { + p256 := P256() + iden, err := p256.Point.Set(big.NewInt(0), big.NewInt(0)) + require.NoError(t, err) + require.True(t, iden.IsIdentity()) + _, err = p256.Point.Set(elliptic.P256().Params().Gx, elliptic.P256().Params().Gy) + require.NoError(t, err) +} + +func TestPointP256Double(t *testing.T) { + p256 := P256() + g := p256.Point.Generator() + g2 := g.Double() + require.True(t, g2.Equal(g.Mul(p256.Scalar.New(2)))) + i := p256.Point.Identity() + require.True(t, i.Double().Equal(i)) +} + +func TestPointP256Neg(t *testing.T) { + p256 := P256() + g := p256.Point.Generator().Neg() + require.True(t, g.Neg().Equal(p256.Point.Generator())) + require.True(t, p256.Point.Identity().Neg().Equal(p256.Point.Identity())) +} + +func TestPointP256Add(t *testing.T) { + p256 := P256() + pt := p256.Point.Generator() + require.True(t, pt.Add(pt).Equal(pt.Double())) + require.True(t, pt.Mul(p256.Scalar.New(3)).Equal(pt.Add(pt).Add(pt))) +} + +func TestPointP256Sub(t *testing.T) { + p256 := P256() + g := p256.Point.Generator() + pt := p256.Point.Generator().Mul(p256.Scalar.New(4)) + require.True(t, pt.Sub(g).Sub(g).Sub(g).Equal(g)) + require.True(t, pt.Sub(g).Sub(g).Sub(g).Sub(g).IsIdentity()) +} + +func TestPointP256Mul(t *testing.T) { + p256 := P256() + g := p256.Point.Generator() + pt := p256.Point.Generator().Mul(p256.Scalar.New(4)) + require.True(t, g.Double().Double().Equal(pt)) +} + +func TestPointP256Serialize(t *testing.T) { + p256 := P256() + ss := p256.Scalar.Random(testRng()) + g := p256.Point.Generator() + + ppt := g.Mul(ss) + require.Equal(t, ppt.ToAffineCompressed(), []byte{0x3, 0x1b, 0xfa, 0x44, 0xfb, 0x6, 0xa4, 0x6d, 0xe1, 0x38, 0x72, 0x39, 0x9a, 0x69, 0xd4, 0x71, 0x38, 0x3f, 0x8b, 0x13, 0x39, 0x60, 0xdc, 0x61, 0x91, 0x22, 0x70, 0x58, 0x7c, 0xdf, 0x82, 0x33, 0xba}) + require.Equal(t, ppt.ToAffineUncompressed(), []byte{0x4, 0x1b, 0xfa, 0x44, 0xfb, 0x6, 0xa4, 0x6d, 0xe1, 0x38, 0x72, 0x39, 0x9a, 0x69, 0xd4, 0x71, 0x38, 0x3f, 0x8b, 0x13, 0x39, 0x60, 0xdc, 0x61, 0x91, 0x22, 0x70, 0x58, 0x7c, 0xdf, 0x82, 0x33, 0xba, 0x48, 0xdf, 0x58, 0xac, 0x70, 0xf3, 0x9b, 0x9d, 0x5d, 0x84, 0x6e, 0x2d, 0x75, 0xc9, 0x6, 0x1e, 0xd9, 0x62, 0x8b, 0x15, 0x0, 0x65, 0x69, 0x79, 0xfb, 0x42, 0xc, 0x35, 0xce, 0x2e, 0x8b, 0xfd}) + retP, err := ppt.FromAffineCompressed(ppt.ToAffineCompressed()) + require.NoError(t, err) + require.True(t, ppt.Equal(retP)) + retP, err = ppt.FromAffineUncompressed(ppt.ToAffineUncompressed()) + require.NoError(t, err) + require.True(t, ppt.Equal(retP)) + + // smoke test + for i := 0; i < 25; i++ { + s := p256.Scalar.Random(crand.Reader) + pt := g.Mul(s) + cmprs := pt.ToAffineCompressed() + require.Equal(t, len(cmprs), 33) + retC, err := pt.FromAffineCompressed(cmprs) + require.NoError(t, err) + require.True(t, pt.Equal(retC)) + + un := pt.ToAffineUncompressed() + require.Equal(t, len(un), 65) + retU, err := pt.FromAffineUncompressed(un) + require.NoError(t, err) + require.True(t, pt.Equal(retU)) + } +} + +func TestPointP256Nil(t *testing.T) { + p256 := P256() + one := p256.Point.Generator() + require.Nil(t, one.Add(nil)) + require.Nil(t, one.Sub(nil)) + require.Nil(t, one.Mul(nil)) + require.Nil(t, p256.Scalar.Random(nil)) + require.False(t, one.Equal(nil)) + _, err := p256.Scalar.SetBigInt(nil) + require.Error(t, err) +} + +func TestPointP256SumOfProducts(t *testing.T) { + lhs := new(PointP256).Generator().Mul(new(ScalarP256).New(50)) + points := make([]Point, 5) + for i := range points { + points[i] = new(PointP256).Generator() + } + scalars := []Scalar{ + new(ScalarP256).New(8), + new(ScalarP256).New(9), + new(ScalarP256).New(10), + new(ScalarP256).New(11), + new(ScalarP256).New(12), + } + rhs := lhs.SumOfProducts(points, scalars) + require.NotNil(t, rhs) + require.True(t, lhs.Equal(rhs)) +} diff --git a/pkg/crypto/core/curves/pallas_curve.go b/pkg/crypto/core/curves/pallas_curve.go new file mode 100755 index 000000000..2f1e4d488 --- /dev/null +++ b/pkg/crypto/core/curves/pallas_curve.go @@ -0,0 +1,1176 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + "crypto/elliptic" + crand "crypto/rand" + "crypto/subtle" + "errors" + "fmt" + "io" + "math/big" + "sync" + + "golang.org/x/crypto/blake2b" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fq" +) + +var ( + b = new(fp.Fp).SetUint64(5) + three = &fp.Fp{0x6b0ee5d0fffffff5, 0x86f76d2b99b14bd0, 0xfffffffffffffffe, 0x3fffffffffffffff} + eight = &fp.Fp{0x7387134cffffffe1, 0xd973797adfadd5a8, 0xfffffffffffffffb, 0x3fffffffffffffff} + bool2int = map[bool]int{ + true: 1, + false: 0, + } +) + +var isomapper = [13]*fp.Fp{ + new(fp.Fp).SetRaw(&[4]uint64{0x775f6034aaaaaaab, 0x4081775473d8375b, 0xe38e38e38e38e38e, 0x0e38e38e38e38e38}), + new(fp.Fp).SetRaw(&[4]uint64{0x8cf863b02814fb76, 0x0f93b82ee4b99495, 0x267c7ffa51cf412a, 0x3509afd51872d88e}), + new(fp.Fp).SetRaw(&[4]uint64{0x0eb64faef37ea4f7, 0x380af066cfeb6d69, 0x98c7d7ac3d98fd13, 0x17329b9ec5253753}), + new(fp.Fp).SetRaw(&[4]uint64{0xeebec06955555580, 0x8102eea8e7b06eb6, 0xc71c71c71c71c71c, 0x1c71c71c71c71c71}), + new(fp.Fp).SetRaw(&[4]uint64{0xc47f2ab668bcd71f, 0x9c434ac1c96b6980, 0x5a607fcce0494a79, 0x1d572e7ddc099cff}), + new(fp.Fp).SetRaw(&[4]uint64{0x2aa3af1eae5b6604, 0xb4abf9fb9a1fc81c, 0x1d13bf2a7f22b105, 0x325669becaecd5d1}), + new(fp.Fp).SetRaw(&[4]uint64{0x5ad985b5e38e38e4, 0x7642b01ad461bad2, 0x4bda12f684bda12f, 0x1a12f684bda12f68}), + new(fp.Fp).SetRaw(&[4]uint64{0xc67c31d8140a7dbb, 0x07c9dc17725cca4a, 0x133e3ffd28e7a095, 0x1a84d7ea8c396c47}), + new(fp.Fp).SetRaw(&[4]uint64{0x02e2be87d225b234, 0x1765e924f7459378, 0x303216cce1db9ff1, 0x3fb98ff0d2ddcadd}), + new(fp.Fp).SetRaw(&[4]uint64{0x93e53ab371c71c4f, 0x0ac03e8e134eb3e4, 0x7b425ed097b425ed, 0x025ed097b425ed09}), + new(fp.Fp).SetRaw(&[4]uint64{0x5a28279b1d1b42ae, 0x5941a3a4a97aa1b3, 0x0790bfb3506defb6, 0x0c02c5bcca0e6b7f}), + new(fp.Fp).SetRaw(&[4]uint64{0x4d90ab820b12320a, 0xd976bbfabbc5661d, 0x573b3d7f7d681310, 0x17033d3c60c68173}), + new(fp.Fp).SetRaw(&[4]uint64{0x992d30ecfffffde5, 0x224698fc094cf91b, 0x0000000000000000, 0x4000000000000000}), +} + +var ( + isoa = new(fp.Fp).SetRaw(&[4]uint64{0x92bb4b0b657a014b, 0xb74134581a27a59f, 0x49be2d7258370742, 0x18354a2eb0ea8c9c}) + isob = new(fp.Fp).SetRaw(&[4]uint64{1265, 0, 0, 0}) + z = new(fp.Fp).SetRaw(&[4]uint64{0x992d30ecfffffff4, 0x224698fc094cf91b, 0x0000000000000000, 0x4000000000000000}) +) + +var ( + oldPallasInitonce sync.Once + oldPallas PallasCurve +) + +type PallasCurve struct { + *elliptic.CurveParams +} + +func oldPallasInitAll() { + oldPallas.CurveParams = new(elliptic.CurveParams) + oldPallas.P = new(big.Int).SetBytes([]byte{ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x46, 0x98, 0xfc, 0x09, 0x4c, 0xf9, 0x1b, + 0x99, 0x2d, 0x30, 0xed, 0x00, 0x00, 0x00, 0x01, + }) + oldPallas.N = new(big.Int).SetBytes([]byte{ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x46, 0x98, 0xfc, 0x09, 0x94, 0xa8, 0xdd, + 0x8c, 0x46, 0xeb, 0x21, 0x00, 0x00, 0x00, 0x01, + }) + g := new(Ep).Generator() + oldPallas.Gx = g.x.BigInt() + oldPallas.Gy = g.y.BigInt() + oldPallas.B = big.NewInt(5) + oldPallas.BitSize = 255 + pallas.Name = PallasName +} + +func Pallas() *PallasCurve { + oldPallasInitonce.Do(oldPallasInitAll) + return &oldPallas +} + +func (curve *PallasCurve) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +func (curve *PallasCurve) IsOnCurve(x, y *big.Int) bool { + p := new(Ep) + p.x = new(fp.Fp).SetBigInt(x) + p.y = new(fp.Fp).SetBigInt(y) + p.z = new(fp.Fp).SetOne() + + return p.IsOnCurve() +} + +func (curve *PallasCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + p := new(Ep) + p.x = new(fp.Fp).SetBigInt(x1) + p.y = new(fp.Fp).SetBigInt(y1) + p.z = new(fp.Fp).SetOne() + if p.x.IsZero() && p.y.IsZero() { + p.z.SetZero() + } + + q := new(Ep) + q.x = new(fp.Fp).SetBigInt(x2) + q.y = new(fp.Fp).SetBigInt(y2) + q.z = new(fp.Fp).SetOne() + if q.x.IsZero() && q.y.IsZero() { + q.z.SetZero() + } + p.Add(p, q) + p.toAffine() + return p.x.BigInt(), p.y.BigInt() +} + +func (curve *PallasCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + p := new(Ep) + p.x = new(fp.Fp).SetBigInt(x1) + p.y = new(fp.Fp).SetBigInt(y1) + p.z = new(fp.Fp).SetOne() + if p.x.IsZero() && p.y.IsZero() { + p.z.SetZero() + } + p.Double(p) + p.toAffine() + return p.x.BigInt(), p.y.BigInt() +} + +func (curve *PallasCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + p := new(Ep) + p.x = new(fp.Fp).SetBigInt(Bx) + p.y = new(fp.Fp).SetBigInt(By) + p.z = new(fp.Fp).SetOne() + if p.x.IsZero() && p.y.IsZero() { + p.z.SetZero() + } + var t [32]byte + copy(t[:], k) + ss := new(big.Int).SetBytes(k) + sc := new(fq.Fq).SetBigInt(ss) + p.Mul(p, sc) + p.toAffine() + return p.x.BigInt(), p.y.BigInt() +} + +func (curve *PallasCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + p := new(Ep).Generator() + var t [32]byte + copy(t[:], k) + ss := new(big.Int).SetBytes(k) + sc := new(fq.Fq).SetBigInt(ss) + p.Mul(p, sc) + p.toAffine() + return p.x.BigInt(), p.y.BigInt() +} + +// PallasScalar - Old interface +type PallasScalar struct{} + +func NewPallasScalar() *PallasScalar { + return &PallasScalar{} +} + +func (k PallasScalar) Add(x, y *big.Int) *big.Int { + r := new(big.Int).Add(x, y) + return r.Mod(r, fq.BiModulus) +} + +func (k PallasScalar) Sub(x, y *big.Int) *big.Int { + r := new(big.Int).Sub(x, y) + return r.Mod(r, fq.BiModulus) +} + +func (k PallasScalar) Neg(x *big.Int) *big.Int { + r := new(big.Int).Neg(x) + return r.Mod(r, fq.BiModulus) +} + +func (k PallasScalar) Mul(x, y *big.Int) *big.Int { + r := new(big.Int).Mul(x, y) + return r.Mod(r, fq.BiModulus) +} + +func (k PallasScalar) Div(x, y *big.Int) *big.Int { + r := new(big.Int).ModInverse(y, fq.BiModulus) + r.Mul(r, x) + return r.Mod(r, fq.BiModulus) +} + +func (k PallasScalar) Hash(input []byte) *big.Int { + return new(ScalarPallas).Hash(input).(*ScalarPallas).value.BigInt() +} + +func (k PallasScalar) Bytes(x *big.Int) []byte { + return x.Bytes() +} + +func (k PallasScalar) Random() (*big.Int, error) { + s, ok := new(ScalarPallas).Random(crand.Reader).(*ScalarPallas) + if !ok { + return nil, errors.New("incorrect type conversion") + } + return s.value.BigInt(), nil +} + +func (k PallasScalar) IsValid(x *big.Int) bool { + return x.Cmp(fq.BiModulus) == -1 +} + +// ScalarPallas - New interface +type ScalarPallas struct { + value *fq.Fq +} + +func (s *ScalarPallas) Random(reader io.Reader) Scalar { + if reader == nil { + return nil + } + var seed [64]byte + _, _ = reader.Read(seed[:]) + return s.Hash(seed[:]) +} + +func (s *ScalarPallas) Hash(bytes []byte) Scalar { + h, _ := blake2b.New(64, []byte{}) + xmd, err := expandMsgXmd(h, bytes, []byte("pallas_XMD:BLAKE2b_SSWU_RO_"), 64) + if err != nil { + return nil + } + var t [64]byte + copy(t[:], xmd) + return &ScalarPallas{ + value: new(fq.Fq).SetBytesWide(&t), + } +} + +func (s *ScalarPallas) Zero() Scalar { + return &ScalarPallas{ + value: new(fq.Fq).SetZero(), + } +} + +func (s *ScalarPallas) One() Scalar { + return &ScalarPallas{ + value: new(fq.Fq).SetOne(), + } +} + +func (s *ScalarPallas) IsZero() bool { + return s.value.IsZero() +} + +func (s *ScalarPallas) IsOne() bool { + return s.value.IsOne() +} + +func (s *ScalarPallas) IsOdd() bool { + return (s.value[0] & 1) == 1 +} + +func (s *ScalarPallas) IsEven() bool { + return (s.value[0] & 1) == 0 +} + +func (s *ScalarPallas) New(value int) Scalar { + v := big.NewInt(int64(value)) + return &ScalarPallas{ + value: new(fq.Fq).SetBigInt(v), + } +} + +func (s *ScalarPallas) Cmp(rhs Scalar) int { + r, ok := rhs.(*ScalarPallas) + if ok { + return s.value.Cmp(r.value) + } else { + return -2 + } +} + +func (s *ScalarPallas) Square() Scalar { + return &ScalarPallas{ + value: new(fq.Fq).Square(s.value), + } +} + +func (s *ScalarPallas) Double() Scalar { + return &ScalarPallas{ + value: new(fq.Fq).Double(s.value), + } +} + +func (s *ScalarPallas) Invert() (Scalar, error) { + value, wasInverted := new(fq.Fq).Invert(s.value) + if !wasInverted { + return nil, fmt.Errorf("inverse doesn't exist") + } + return &ScalarPallas{ + value, + }, nil +} + +func (s *ScalarPallas) Sqrt() (Scalar, error) { + value, wasSquare := new(fq.Fq).Sqrt(s.value) + if !wasSquare { + return nil, fmt.Errorf("not a square") + } + return &ScalarPallas{ + value, + }, nil +} + +func (s *ScalarPallas) Cube() Scalar { + value := new(fq.Fq).Mul(s.value, s.value) + value.Mul(value, s.value) + return &ScalarPallas{ + value, + } +} + +func (s *ScalarPallas) Add(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarPallas) + if ok { + return &ScalarPallas{ + value: new(fq.Fq).Add(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarPallas) Sub(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarPallas) + if ok { + return &ScalarPallas{ + value: new(fq.Fq).Sub(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarPallas) Mul(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarPallas) + if ok { + return &ScalarPallas{ + value: new(fq.Fq).Mul(s.value, r.value), + } + } else { + return nil + } +} + +func (s *ScalarPallas) MulAdd(y, z Scalar) Scalar { + return s.Mul(y).Add(z) +} + +func (s *ScalarPallas) Div(rhs Scalar) Scalar { + r, ok := rhs.(*ScalarPallas) + if ok { + v, wasInverted := new(fq.Fq).Invert(r.value) + if !wasInverted { + return nil + } + v.Mul(v, s.value) + return &ScalarPallas{value: v} + } else { + return nil + } +} + +func (s *ScalarPallas) Neg() Scalar { + return &ScalarPallas{ + value: new(fq.Fq).Neg(s.value), + } +} + +func (s *ScalarPallas) SetBigInt(v *big.Int) (Scalar, error) { + return &ScalarPallas{ + value: new(fq.Fq).SetBigInt(v), + }, nil +} + +func (s *ScalarPallas) BigInt() *big.Int { + return s.value.BigInt() +} + +func (s *ScalarPallas) Bytes() []byte { + t := s.value.Bytes() + return t[:] +} + +func (s *ScalarPallas) SetBytes(bytes []byte) (Scalar, error) { + if len(bytes) != 32 { + return nil, fmt.Errorf("invalid length") + } + var seq [32]byte + copy(seq[:], bytes) + value, err := new(fq.Fq).SetBytes(&seq) + if err != nil { + return nil, err + } + return &ScalarPallas{ + value, + }, nil +} + +func (s *ScalarPallas) SetBytesWide(bytes []byte) (Scalar, error) { + if len(bytes) != 64 { + return nil, fmt.Errorf("invalid length") + } + var seq [64]byte + copy(seq[:], bytes) + return &ScalarPallas{ + value: new(fq.Fq).SetBytesWide(&seq), + }, nil +} + +func (s *ScalarPallas) Point() Point { + return new(PointPallas).Identity() +} + +func (s *ScalarPallas) Clone() Scalar { + return &ScalarPallas{ + value: new(fq.Fq).Set(s.value), + } +} + +func (s *ScalarPallas) GetFq() *fq.Fq { + return new(fq.Fq).Set(s.value) +} + +func (s *ScalarPallas) SetFq(fq *fq.Fq) *ScalarPallas { + s.value = fq + return s +} + +func (s *ScalarPallas) MarshalBinary() ([]byte, error) { + return scalarMarshalBinary(s) +} + +func (s *ScalarPallas) UnmarshalBinary(input []byte) error { + sc, err := scalarUnmarshalBinary(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarPallas) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarPallas) MarshalText() ([]byte, error) { + return scalarMarshalText(s) +} + +func (s *ScalarPallas) UnmarshalText(input []byte) error { + sc, err := scalarUnmarshalText(input) + if err != nil { + return err + } + ss, ok := sc.(*ScalarPallas) + if !ok { + return fmt.Errorf("invalid scalar") + } + s.value = ss.value + return nil +} + +func (s *ScalarPallas) MarshalJSON() ([]byte, error) { + return scalarMarshalJson(s) +} + +func (s *ScalarPallas) UnmarshalJSON(input []byte) error { + sc, err := scalarUnmarshalJson(input) + if err != nil { + return err + } + S, ok := sc.(*ScalarPallas) + if !ok { + return fmt.Errorf("invalid type") + } + s.value = S.value + return nil +} + +type PointPallas struct { + value *Ep +} + +func (p *PointPallas) Random(reader io.Reader) Point { + return &PointPallas{new(Ep).Random(reader)} +} + +func (p *PointPallas) Hash(bytes []byte) Point { + return &PointPallas{new(Ep).Hash(bytes)} +} + +func (p *PointPallas) Identity() Point { + return &PointPallas{new(Ep).Identity()} +} + +func (p *PointPallas) Generator() Point { + return &PointPallas{new(Ep).Generator()} +} + +func (p *PointPallas) IsIdentity() bool { + return p.value.IsIdentity() +} + +func (p *PointPallas) IsNegative() bool { + return p.value.Y().IsOdd() +} + +func (p *PointPallas) IsOnCurve() bool { + return p.value.IsOnCurve() +} + +func (p *PointPallas) Double() Point { + return &PointPallas{new(Ep).Double(p.value)} +} + +func (p *PointPallas) Scalar() Scalar { + return &ScalarPallas{new(fq.Fq).SetZero()} +} + +func (p *PointPallas) Neg() Point { + return &PointPallas{new(Ep).Neg(p.value)} +} + +func (p *PointPallas) Add(rhs Point) Point { + r, ok := rhs.(*PointPallas) + if !ok { + return nil + } + return &PointPallas{new(Ep).Add(p.value, r.value)} +} + +func (p *PointPallas) Sub(rhs Point) Point { + r, ok := rhs.(*PointPallas) + if !ok { + return nil + } + return &PointPallas{new(Ep).Sub(p.value, r.value)} +} + +func (p *PointPallas) Mul(rhs Scalar) Point { + s, ok := rhs.(*ScalarPallas) + if !ok { + return nil + } + return &PointPallas{new(Ep).Mul(p.value, s.value)} +} + +func (p *PointPallas) Equal(rhs Point) bool { + r, ok := rhs.(*PointPallas) + if !ok { + return false + } + return p.value.Equal(r.value) +} + +func (p *PointPallas) Set(x, y *big.Int) (Point, error) { + xx := subtle.ConstantTimeCompare(x.Bytes(), []byte{}) + yy := subtle.ConstantTimeCompare(y.Bytes(), []byte{}) + xElem := new(fp.Fp).SetBigInt(x) + var data [32]byte + if yy == 1 { + if xx == 1 { + return &PointPallas{new(Ep).Identity()}, nil + } + data = xElem.Bytes() + return p.FromAffineCompressed(data[:]) + } + yElem := new(fp.Fp).SetBigInt(y) + value := &Ep{xElem, yElem, new(fp.Fp).SetOne()} + if !value.IsOnCurve() { + return nil, fmt.Errorf("point is not on the curve") + } + return &PointPallas{value}, nil +} + +func (p *PointPallas) ToAffineCompressed() []byte { + return p.value.ToAffineCompressed() +} + +func (p *PointPallas) ToAffineUncompressed() []byte { + return p.value.ToAffineUncompressed() +} + +func (p *PointPallas) FromAffineCompressed(bytes []byte) (Point, error) { + value, err := new(Ep).FromAffineCompressed(bytes) + if err != nil { + return nil, err + } + return &PointPallas{value}, nil +} + +func (p *PointPallas) FromAffineUncompressed(bytes []byte) (Point, error) { + value, err := new(Ep).FromAffineUncompressed(bytes) + if err != nil { + return nil, err + } + return &PointPallas{value}, nil +} + +func (p *PointPallas) CurveName() string { + return PallasName +} + +func (p *PointPallas) SumOfProducts(points []Point, scalars []Scalar) Point { + eps := make([]*Ep, len(points)) + for i, pt := range points { + ps, ok := pt.(*PointPallas) + if !ok { + return nil + } + eps[i] = ps.value + } + value := p.value.SumOfProducts(eps, scalars) + return &PointPallas{value} +} + +func (p *PointPallas) MarshalBinary() ([]byte, error) { + return pointMarshalBinary(p) +} + +func (p *PointPallas) UnmarshalBinary(input []byte) error { + pt, err := pointUnmarshalBinary(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointPallas) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointPallas) MarshalText() ([]byte, error) { + return pointMarshalText(p) +} + +func (p *PointPallas) UnmarshalText(input []byte) error { + pt, err := pointUnmarshalText(input) + if err != nil { + return err + } + ppt, ok := pt.(*PointPallas) + if !ok { + return fmt.Errorf("invalid point") + } + p.value = ppt.value + return nil +} + +func (p *PointPallas) MarshalJSON() ([]byte, error) { + return pointMarshalJson(p) +} + +func (p *PointPallas) UnmarshalJSON(input []byte) error { + pt, err := pointUnmarshalJson(input) + if err != nil { + return err + } + P, ok := pt.(*PointPallas) + if !ok { + return fmt.Errorf("invalid type") + } + p.value = P.value + return nil +} + +func (p *PointPallas) X() *fp.Fp { + return p.value.X() +} + +func (p *PointPallas) Y() *fp.Fp { + return p.value.Y() +} + +func (p *PointPallas) GetEp() *Ep { + return new(Ep).Set(p.value) +} + +type Ep struct { + x *fp.Fp + y *fp.Fp + z *fp.Fp +} + +func (p *Ep) Random(reader io.Reader) *Ep { + var seed [64]byte + _, _ = reader.Read(seed[:]) + return p.Hash(seed[:]) +} + +func (p *Ep) Hash(bytes []byte) *Ep { + if bytes == nil { + bytes = []byte{} + } + h, _ := blake2b.New(64, []byte{}) + u, _ := expandMsgXmd(h, bytes, []byte("pallas_XMD:BLAKE2b_SSWU_RO_"), 128) + var buf [64]byte + copy(buf[:], u[:64]) + u0 := new(fp.Fp).SetBytesWide(&buf) + copy(buf[:], u[64:]) + u1 := new(fp.Fp).SetBytesWide(&buf) + + q0 := mapSswu(u0) + q1 := mapSswu(u1) + r1 := isoMap(q0) + r2 := isoMap(q1) + return p.Identity().Add(r1, r2) +} + +func (p *Ep) Identity() *Ep { + p.x = new(fp.Fp).SetZero() + p.y = new(fp.Fp).SetZero() + p.z = new(fp.Fp).SetZero() + return p +} + +func (p *Ep) Generator() *Ep { + p.x = new(fp.Fp).SetOne() + p.y = &fp.Fp{0x2f474795455d409d, 0xb443b9b74b8255d9, 0x270c412f2c9a5d66, 0x8e00f71ba43dd6b} + p.z = new(fp.Fp).SetOne() + return p +} + +func (p *Ep) IsIdentity() bool { + return p.z.IsZero() +} + +func (p *Ep) Double(other *Ep) *Ep { + if other.IsIdentity() { + p.Set(other) + return p + } + r := new(Ep) + // essentially paraphrased https://github.com/MinaProtocol/c-reference-signer/blob/master/crypto.c#L306-L337 + a := new(fp.Fp).Square(other.x) + b := new(fp.Fp).Square(other.y) + c := new(fp.Fp).Square(b) + r.x = new(fp.Fp).Add(other.x, b) + r.y = new(fp.Fp).Square(r.x) + r.z = new(fp.Fp).Sub(r.y, a) + r.x.Sub(r.z, c) + d := new(fp.Fp).Double(r.x) + e := new(fp.Fp).Mul(three, a) + f := new(fp.Fp).Square(e) + r.y.Double(d) + r.x.Sub(f, r.y) + r.y.Sub(d, r.x) + f.Mul(eight, c) + r.z.Mul(e, r.y) + r.y.Sub(r.z, f) + f.Mul(other.y, other.z) + r.z.Double(f) + p.Set(r) + return p +} + +func (p *Ep) Neg(other *Ep) *Ep { + p.x = new(fp.Fp).Set(other.x) + p.y = new(fp.Fp).Neg(other.y) + p.z = new(fp.Fp).Set(other.z) + return p +} + +func (p *Ep) Add(lhs *Ep, rhs *Ep) *Ep { + if lhs.IsIdentity() { + return p.Set(rhs) + } + if rhs.IsIdentity() { + return p.Set(lhs) + } + z1z1 := new(fp.Fp).Square(lhs.z) + z2z2 := new(fp.Fp).Square(rhs.z) + u1 := new(fp.Fp).Mul(lhs.x, z2z2) + u2 := new(fp.Fp).Mul(rhs.x, z1z1) + s1 := new(fp.Fp).Mul(lhs.y, z2z2) + s1.Mul(s1, rhs.z) + s2 := new(fp.Fp).Mul(rhs.y, z1z1) + s2.Mul(s2, lhs.z) + + if u1.Equal(u2) { + if s1.Equal(s2) { + return p.Double(lhs) + } else { + return p.Identity() + } + } else { + h := new(fp.Fp).Sub(u2, u1) + i := new(fp.Fp).Double(h) + i.Square(i) + j := new(fp.Fp).Mul(i, h) + r := new(fp.Fp).Sub(s2, s1) + r.Double(r) + v := new(fp.Fp).Mul(u1, i) + x3 := new(fp.Fp).Square(r) + x3.Sub(x3, j) + x3.Sub(x3, new(fp.Fp).Double(v)) + s1.Mul(s1, j) + s1.Double(s1) + y3 := new(fp.Fp).Mul(r, new(fp.Fp).Sub(v, x3)) + y3.Sub(y3, s1) + z3 := new(fp.Fp).Add(lhs.z, rhs.z) + z3.Square(z3) + z3.Sub(z3, z1z1) + z3.Sub(z3, z2z2) + z3.Mul(z3, h) + p.x = new(fp.Fp).Set(x3) + p.y = new(fp.Fp).Set(y3) + p.z = new(fp.Fp).Set(z3) + + return p + } +} + +func (p *Ep) Sub(lhs, rhs *Ep) *Ep { + return p.Add(lhs, new(Ep).Neg(rhs)) +} + +func (p *Ep) Mul(point *Ep, scalar *fq.Fq) *Ep { + bytes := scalar.Bytes() + precomputed := [16]*Ep{} + precomputed[0] = new(Ep).Identity() + precomputed[1] = new(Ep).Set(point) + for i := 2; i < 16; i += 2 { + precomputed[i] = new(Ep).Double(precomputed[i>>1]) + precomputed[i+1] = new(Ep).Add(precomputed[i], point) + } + p.Identity() + for i := 0; i < 256; i += 4 { + // Brouwer / windowing method. window size of 4. + for j := 0; j < 4; j++ { + p.Double(p) + } + window := bytes[32-1-i>>3] >> (4 - i&0x04) & 0x0F + p.Add(p, precomputed[window]) + } + return p +} + +func (p *Ep) Equal(other *Ep) bool { + // warning: requires converting both to affine + // could save slightly by modifying one so that its z-value equals the other + // this would save one inversion and a handful of multiplications + // but this is more subtle and error-prone, so going to just convert both to affine. + lhs := new(Ep).Set(p) + rhs := new(Ep).Set(other) + lhs.toAffine() + rhs.toAffine() + return lhs.x.Equal(rhs.x) && lhs.y.Equal(rhs.y) +} + +func (p *Ep) Set(other *Ep) *Ep { + // check is identity or on curve + p.x = new(fp.Fp).Set(other.x) + p.y = new(fp.Fp).Set(other.y) + p.z = new(fp.Fp).Set(other.z) + return p +} + +func (p *Ep) toAffine() *Ep { + // mutates `p` in-place to convert it to "affine" form. + if p.IsIdentity() { + // warning: control flow / not constant-time + p.x.SetZero() + p.y.SetZero() + p.z.SetOne() + return p + } + zInv3, _ := new(fp.Fp).Invert(p.z) // z is necessarily nonzero + zInv2 := new(fp.Fp).Square(zInv3) + zInv3.Mul(zInv3, zInv2) + p.x.Mul(p.x, zInv2) + p.y.Mul(p.y, zInv3) + p.z.SetOne() + return p +} + +func (p *Ep) ToAffineCompressed() []byte { + // Use ZCash encoding where infinity is all zeros + // and the top bit represents the sign of y and the + // remainder represent the x-coordinate + var inf [32]byte + p1 := new(Ep).Set(p) + p1.toAffine() + x := p1.x.Bytes() + x[31] |= (p1.y.Bytes()[0] & 1) << 7 + subtle.ConstantTimeCopy(bool2int[p1.IsIdentity()], x[:], inf[:]) + return x[:] +} + +func (p *Ep) ToAffineUncompressed() []byte { + p1 := new(Ep).Set(p) + p1.toAffine() + x := p1.x.Bytes() + y := p1.y.Bytes() + return append(x[:], y[:]...) +} + +func (p *Ep) FromAffineCompressed(bytes []byte) (*Ep, error) { + if len(bytes) != 32 { + return nil, fmt.Errorf("invalid byte sequence") + } + + var input [32]byte + copy(input[:], bytes) + sign := (input[31] >> 7) & 1 + input[31] &= 0x7F + + x := new(fp.Fp) + if _, err := x.SetBytes(&input); err != nil { + return nil, err + } + rhs := rhsPallas(x) + if _, square := rhs.Sqrt(rhs); !square { + return nil, fmt.Errorf("rhs of given x-coordinate is not a square") + } + if rhs.Bytes()[0]&1 != sign { + rhs.Neg(rhs) + } + p.x = x + p.y = rhs + p.z = new(fp.Fp).SetOne() + if !p.IsOnCurve() { + return nil, fmt.Errorf("invalid point") + } + return p, nil +} + +func (p *Ep) FromAffineUncompressed(bytes []byte) (*Ep, error) { + if len(bytes) != 64 { + return nil, fmt.Errorf("invalid length") + } + p.z = new(fp.Fp).SetOne() + p.x = new(fp.Fp) + p.y = new(fp.Fp) + var x, y [32]byte + copy(x[:], bytes[:32]) + copy(y[:], bytes[32:]) + if _, err := p.x.SetBytes(&x); err != nil { + return nil, err + } + if _, err := p.y.SetBytes(&y); err != nil { + return nil, err + } + if !p.IsOnCurve() { + return nil, fmt.Errorf("invalid point") + } + return p, nil +} + +// rhs of the curve equation +func rhsPallas(x *fp.Fp) *fp.Fp { + x2 := new(fp.Fp).Square(x) + x3 := new(fp.Fp).Mul(x, x2) + return new(fp.Fp).Add(x3, b) +} + +func (p Ep) CurveName() string { + return "pallas" +} + +func (p Ep) SumOfProducts(points []*Ep, scalars []Scalar) *Ep { + nScalars := make([]*big.Int, len(scalars)) + for i, s := range scalars { + sc, ok := s.(*ScalarPallas) + if !ok { + return nil + } + nScalars[i] = sc.value.BigInt() + } + return sumOfProductsPippengerPallas(points, nScalars) +} + +func (p *Ep) X() *fp.Fp { + t := new(Ep).Set(p) + t.toAffine() + return new(fp.Fp).Set(t.x) +} + +func (p *Ep) Y() *fp.Fp { + t := new(Ep).Set(p) + t.toAffine() + return new(fp.Fp).Set(t.y) +} + +func (p *Ep) IsOnCurve() bool { + // y^2 = x^3 + axz^4 + bz^6 + // a = 0 + // b = 5 + z2 := new(fp.Fp).Square(p.z) + z4 := new(fp.Fp).Square(z2) + z6 := new(fp.Fp).Mul(z2, z4) + x2 := new(fp.Fp).Square(p.x) + x3 := new(fp.Fp).Mul(x2, p.x) + + lhs := new(fp.Fp).Square(p.y) + rhs := new(fp.Fp).SetUint64(5) + rhs.Mul(rhs, z6) + rhs.Add(rhs, x3) + return p.z.IsZero() || lhs.Equal(rhs) +} + +func (p *Ep) CMove(lhs, rhs *Ep, condition int) *Ep { + p.x = new(fp.Fp).CMove(lhs.x, rhs.x, condition) + p.y = new(fp.Fp).CMove(lhs.y, rhs.y, condition) + p.z = new(fp.Fp).CMove(lhs.z, rhs.z, condition) + return p +} + +func sumOfProductsPippengerPallas(points []*Ep, scalars []*big.Int) *Ep { + if len(points) != len(scalars) { + return nil + } + + const w = 6 + + bucketSize := (1 << w) - 1 + windows := make([]*Ep, 255/w+1) + for i := range windows { + windows[i] = new(Ep).Identity() + } + bucket := make([]*Ep, bucketSize) + + for j := 0; j < len(windows); j++ { + for i := 0; i < bucketSize; i++ { + bucket[i] = new(Ep).Identity() + } + + for i := 0; i < len(scalars); i++ { + index := bucketSize & int(new(big.Int).Rsh(scalars[i], uint(w*j)).Int64()) + if index != 0 { + bucket[index-1].Add(bucket[index-1], points[i]) + } + } + + acc, sum := new(Ep).Identity(), new(Ep).Identity() + + for i := bucketSize - 1; i >= 0; i-- { + sum.Add(sum, bucket[i]) + acc.Add(acc, sum) + } + windows[j] = acc + } + + acc := new(Ep).Identity() + for i := len(windows) - 1; i >= 0; i-- { + for j := 0; j < w; j++ { + acc.Double(acc) + } + acc.Add(acc, windows[i]) + } + return acc +} + +// Implements a degree 3 isogeny map. +// The input and output are in Jacobian coordinates, using the method +// in "Avoiding inversions" [WB2019, section 4.3]. +func isoMap(p *Ep) *Ep { + var z [4]*fp.Fp + z[0] = new(fp.Fp).Square(p.z) // z^2 + z[1] = new(fp.Fp).Mul(z[0], p.z) // z^3 + z[2] = new(fp.Fp).Square(z[0]) // z^4 + z[3] = new(fp.Fp).Square(z[1]) // z^6 + + // ((iso[0] * x + iso[1] * z^2) * x + iso[2] * z^4) * x + iso[3] * z^6 + numX := new(fp.Fp).Set(isomapper[0]) + numX.Mul(numX, p.x) + numX.Add(numX, new(fp.Fp).Mul(isomapper[1], z[0])) + numX.Mul(numX, p.x) + numX.Add(numX, new(fp.Fp).Mul(isomapper[2], z[2])) + numX.Mul(numX, p.x) + numX.Add(numX, new(fp.Fp).Mul(isomapper[3], z[3])) + + // (z^2 * x + iso[4] * z^4) * x + iso[5] * z^6 + divX := new(fp.Fp).Set(z[0]) + divX.Mul(divX, p.x) + divX.Add(divX, new(fp.Fp).Mul(isomapper[4], z[2])) + divX.Mul(divX, p.x) + divX.Add(divX, new(fp.Fp).Mul(isomapper[5], z[3])) + + // (((iso[6] * x + iso[7] * z2) * x + iso[8] * z4) * x + iso[9] * z6) * y + numY := new(fp.Fp).Set(isomapper[6]) + numY.Mul(numY, p.x) + numY.Add(numY, new(fp.Fp).Mul(isomapper[7], z[0])) + numY.Mul(numY, p.x) + numY.Add(numY, new(fp.Fp).Mul(isomapper[8], z[2])) + numY.Mul(numY, p.x) + numY.Add(numY, new(fp.Fp).Mul(isomapper[9], z[3])) + numY.Mul(numY, p.y) + + // (((x + iso[10] * z2) * x + iso[11] * z4) * x + iso[12] * z6) * z3 + divY := new(fp.Fp).Set(p.x) + divY.Add(divY, new(fp.Fp).Mul(isomapper[10], z[0])) + divY.Mul(divY, p.x) + divY.Add(divY, new(fp.Fp).Mul(isomapper[11], z[2])) + divY.Mul(divY, p.x) + divY.Add(divY, new(fp.Fp).Mul(isomapper[12], z[3])) + divY.Mul(divY, z[1]) + + z0 := new(fp.Fp).Mul(divX, divY) + x := new(fp.Fp).Mul(numX, divY) + x.Mul(x, z0) + y := new(fp.Fp).Mul(numY, divX) + y.Mul(y, new(fp.Fp).Square(z0)) + + return &Ep{ + x, y, z0, + } +} + +func mapSswu(u *fp.Fp) *Ep { + // c1 := new(fp.Fp).Neg(isoa) + // c1.Invert(c1) + // c1.Mul(isob, c1) + c1 := &fp.Fp{ + 0x1ee770ce078456ec, + 0x48cfd64c2ce76be0, + 0x43d5774c0ab79e2f, + 0x23368d2bdce28cf3, + } + // c2 := new(fp.Fp).Neg(z) + // c2.Invert(c2) + c2 := &fp.Fp{ + 0x03df915f89d89d8a, + 0x8f1e8db09ef82653, + 0xd89d89d89d89d89d, + 0x1d89d89d89d89d89, + } + + u2 := new(fp.Fp).Square(u) + tv1 := new(fp.Fp).Mul(z, u2) + tv2 := new(fp.Fp).Square(tv1) + x1 := new(fp.Fp).Add(tv1, tv2) + x1.Invert(x1) + e1 := bool2int[x1.IsZero()] + x1.Add(x1, new(fp.Fp).SetOne()) + x1.CMove(x1, c2, e1) + x1.Mul(x1, c1) + gx1 := new(fp.Fp).Square(x1) + gx1.Add(gx1, isoa) + gx1.Mul(gx1, x1) + gx1.Add(gx1, isob) + x2 := new(fp.Fp).Mul(tv1, x1) + tv2.Mul(tv1, tv2) + gx2 := new(fp.Fp).Mul(gx1, tv2) + gx1Sqrt, e2 := new(fp.Fp).Sqrt(gx1) + x := new(fp.Fp).CMove(x2, x1, bool2int[e2]) + gx2Sqrt, _ := new(fp.Fp).Sqrt(gx2) + y := new(fp.Fp).CMove(gx2Sqrt, gx1Sqrt, bool2int[e2]) + e3 := u.IsOdd() == y.IsOdd() + y.CMove(new(fp.Fp).Neg(y), y, bool2int[e3]) + + return &Ep{ + x: x, y: y, z: new(fp.Fp).SetOne(), + } +} diff --git a/pkg/crypto/core/curves/pallas_curve_test.go b/pkg/crypto/core/curves/pallas_curve_test.go new file mode 100755 index 000000000..c372e6c60 --- /dev/null +++ b/pkg/crypto/core/curves/pallas_curve_test.go @@ -0,0 +1,138 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package curves + +import ( + crand "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fq" +) + +func TestPointPallasAddDoubleMul(t *testing.T) { + g := new(Ep).Generator() + id := new(Ep).Identity() + require.Equal(t, g.Add(g, id), g) + + g2 := new(Ep).Add(g, g) + require.True(t, new(Ep).Double(g).Equal(g2)) + require.Equal(t, new(Ep).Double(g), new(Ep).Add(g, g)) + g3 := new(Ep).Add(g, g2) + require.True(t, g3.Equal(new(Ep).Mul(g, new(fq.Fq).SetUint64(3)))) + + g4 := new(Ep).Add(g3, g) + require.True(t, g4.Equal(new(Ep).Double(g2))) + require.True(t, g4.Equal(new(Ep).Mul(g, new(fq.Fq).SetUint64(4)))) +} + +func TestPointPallasHash(t *testing.T) { + h0 := new(Ep).Hash(nil) + require.True(t, h0.IsOnCurve()) + h1 := new(Ep).Hash([]byte{}) + require.True(t, h1.IsOnCurve()) + require.True(t, h0.Equal(h1)) + h2 := new(Ep).Hash([]byte{1}) + require.True(t, h2.IsOnCurve()) +} + +func TestPointPallasNeg(t *testing.T) { + g := new(Ep).Generator() + g.Neg(g) + require.True(t, g.Neg(g).Equal(new(Ep).Generator())) + id := new(Ep).Identity() + require.True(t, new(Ep).Neg(id).Equal(id)) +} + +func TestPointPallasRandom(t *testing.T) { + a := new(Ep).Random(testRng()) + require.NotNil(t, a.x) + require.NotNil(t, a.y) + require.NotNil(t, a.z) + require.True(t, a.IsOnCurve()) + e := &Ep{ + x: &fp.Fp{ + 0x7263083d01d4859c, + 0x65a03323b5a3d204, + 0xe71d73222b136668, + 0x1d1b1bcf1256b539, + }, + y: &fp.Fp{ + 0x8cc2516ffe23e1bb, + 0x5418f941eeaca812, + 0x16c9af658a846f29, + 0x11c572091c418668, + }, + z: &fp.Fp{ + 0xa879589adb77a88e, + 0x5444a531a19f2406, + 0x637ff77c51dda524, + 0x0369e90d219ce821, + }, + } + require.True(t, a.Equal(e)) +} + +func TestPointPallasSerialize(t *testing.T) { + ss := new(ScalarPallas).Random(testRng()).(*ScalarPallas) + g := new(Ep).Generator() + + ppt := new(Ep).Mul(g, ss.value) + require.Equal(t, ppt.ToAffineCompressed(), []byte{0x1c, 0x6d, 0x47, 0x1f, 0x4a, 0x81, 0xcd, 0x8, 0x4e, 0xb3, 0x17, 0x9a, 0xcd, 0x17, 0xe2, 0x9a, 0x24, 0x69, 0xb, 0x4e, 0x69, 0x5f, 0x35, 0x1a, 0x92, 0x12, 0x95, 0xc9, 0xe6, 0xd3, 0x7a, 0x0}) + require.Equal(t, ppt.ToAffineUncompressed(), []byte{0x1c, 0x6d, 0x47, 0x1f, 0x4a, 0x81, 0xcd, 0x8, 0x4e, 0xb3, 0x17, 0x9a, 0xcd, 0x17, 0xe2, 0x9a, 0x24, 0x69, 0xb, 0x4e, 0x69, 0x5f, 0x35, 0x1a, 0x92, 0x12, 0x95, 0xc9, 0xe6, 0xd3, 0x7a, 0x0, 0x80, 0x5c, 0xa1, 0x56, 0x6d, 0x1b, 0x87, 0x5f, 0xb0, 0x2e, 0xae, 0x85, 0x4e, 0x86, 0xa9, 0xcd, 0xde, 0x37, 0x6a, 0xc8, 0x4a, 0x80, 0xf6, 0x43, 0xaa, 0xe6, 0x2c, 0x2d, 0x15, 0xdb, 0xda, 0x29}) + retP, err := new(Ep).FromAffineCompressed(ppt.ToAffineCompressed()) + require.NoError(t, err) + require.True(t, ppt.Equal(retP)) + retP, err = new(Ep).FromAffineUncompressed(ppt.ToAffineUncompressed()) + require.NoError(t, err) + require.True(t, ppt.Equal(retP)) + + // smoke test + for i := 0; i < 25; i++ { + s := new(ScalarPallas).Random(crand.Reader).(*ScalarPallas) + pt := new(Ep).Mul(g, s.value) + cmprs := pt.ToAffineCompressed() + require.Equal(t, len(cmprs), 32) + retC, err := new(Ep).FromAffineCompressed(cmprs) + require.NoError(t, err) + require.True(t, pt.Equal(retC)) + + un := pt.ToAffineUncompressed() + require.Equal(t, len(un), 64) + retU, err := new(Ep).FromAffineUncompressed(un) + require.NoError(t, err) + require.True(t, pt.Equal(retU)) + } +} + +func TestPointPallasCMove(t *testing.T) { + a := new(Ep).Random(crand.Reader) + b := new(Ep).Random(crand.Reader) + require.True(t, new(Ep).CMove(a, b, 1).Equal(b)) + require.True(t, new(Ep).CMove(a, b, 0).Equal(a)) +} + +func TestPointPallasSumOfProducts(t *testing.T) { + lhs := new(Ep).Generator() + lhs.Mul(lhs, new(fq.Fq).SetUint64(50)) + points := make([]*Ep, 5) + for i := range points { + points[i] = new(Ep).Generator() + } + scalars := []Scalar{ + new(ScalarPallas).New(8), + new(ScalarPallas).New(9), + new(ScalarPallas).New(10), + new(ScalarPallas).New(11), + new(ScalarPallas).New(12), + } + rhs := lhs.SumOfProducts(points, scalars) + require.NotNil(t, rhs) + require.True(t, lhs.Equal(rhs)) +} diff --git a/pkg/crypto/core/curves/secp256k1/secp256k1.go b/pkg/crypto/core/curves/secp256k1/secp256k1.go new file mode 100644 index 000000000..e5b1297ad --- /dev/null +++ b/pkg/crypto/core/curves/secp256k1/secp256k1.go @@ -0,0 +1,315 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Copyright 2011 ThePiachu. All rights reserved. +// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// * The name of ThePiachu may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package secp256k1 + +import ( + "crypto/elliptic" + "math/big" +) + +const ( + // number of bits in a big.Word + wordBits = 32 << (uint64(^big.Word(0)) >> 63) + // number of bytes in a big.Word + wordBytes = wordBits / 8 +) + +// ScalarMult returns k*(Bx,By) where k is a number in big-endian form. +func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + Bz := new(big.Int).SetInt64(1) + x, y, z := new(big.Int), new(big.Int), new(big.Int) + + for _, byte := range k { + for bitNum := 0; bitNum < 8; bitNum++ { + x, y, z = bitCurve.doubleJacobian(x, y, z) + if byte&0x80 == 0x80 { + x, y, z = bitCurve.addJacobian(Bx, By, Bz, x, y, z) + } + byte <<= 1 + } + } + + return bitCurve.affineFromJacobian(x, y, z) +} + +// readBits encodes the absolute value of bigint as big-endian bytes. Callers +// must ensure that buf has enough space. If buf is too short the result will +// be incomplete. +func readBits(bigint *big.Int, buf []byte) { + i := len(buf) + for _, d := range bigint.Bits() { + for j := 0; j < wordBytes && i > 0; j++ { + i-- + buf[i] = byte(d) + d >>= 8 + } + } +} + +// This code is from https://github.com/ThePiachu/GoBit and implements +// several Koblitz elliptic curves over prime fields. +// +// The curve methods, internally, on Jacobian coordinates. For a given +// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, +// z1) where x = x1/z1² and y = y1/z1³. The greatest speedups come +// when the whole calculation can be performed within the transform +// (as in ScalarMult and ScalarBaseMult). But even for Add and Double, +// it's faster to apply and reverse the transform than to operate in +// affine coordinates. + +// A BitCurve represents a Koblitz Curve with a=0. +// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html +type BitCurve struct { + P *big.Int // the order of the underlying field + N *big.Int // the order of the base point + B *big.Int // the constant of the BitCurve equation + Gx, Gy *big.Int // (x,y) of the base point + BitSize int // the size of the underlying field +} + +func (bitCurve *BitCurve) Params() *elliptic.CurveParams { + return &elliptic.CurveParams{ + P: bitCurve.P, + N: bitCurve.N, + B: bitCurve.B, + Gx: bitCurve.Gx, + Gy: bitCurve.Gy, + BitSize: bitCurve.BitSize, + } +} + +// IsOnCurve returns true if the given (x,y) lies on the BitCurve. +func (bitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { + // y² = x³ + b + y2 := new(big.Int).Mul(y, y) // y² + y2.Mod(y2, bitCurve.P) // y²%P + + x3 := new(big.Int).Mul(x, x) // x² + x3.Mul(x3, x) // x³ + + x3.Add(x3, bitCurve.B) // x³+B + x3.Mod(x3, bitCurve.P) //(x³+B)%P + + return x3.Cmp(y2) == 0 +} + +// affineFromJacobian reverses the Jacobian transform. See the comment at the +// top of the file. +func (bitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { + if z.Sign() == 0 { + return new(big.Int), new(big.Int) + } + + zinv := new(big.Int).ModInverse(z, bitCurve.P) + zinvsq := new(big.Int).Mul(zinv, zinv) + + xOut = new(big.Int).Mul(x, zinvsq) + xOut.Mod(xOut, bitCurve.P) + zinvsq.Mul(zinvsq, zinv) + yOut = new(big.Int).Mul(y, zinvsq) + yOut.Mod(yOut, bitCurve.P) + return +} + +// Add returns the sum of (x1,y1) and (x2,y2) +func (bitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + // If one point is at infinity, return the other point. + // Adding the point at infinity to any point will preserve the other point. + if x1.Sign() == 0 && y1.Sign() == 0 { + return x2, y2 + } + if x2.Sign() == 0 && y2.Sign() == 0 { + return x1, y1 + } + z := new(big.Int).SetInt64(1) + if x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 { + return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z)) + } + return bitCurve.affineFromJacobian(bitCurve.addJacobian(x1, y1, z, x2, y2, z)) +} + +// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and +// (x2, y2, z2) and returns their sum, also in Jacobian form. +func (bitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { + // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl + z1z1 := new(big.Int).Mul(z1, z1) + z1z1.Mod(z1z1, bitCurve.P) + z2z2 := new(big.Int).Mul(z2, z2) + z2z2.Mod(z2z2, bitCurve.P) + + u1 := new(big.Int).Mul(x1, z2z2) + u1.Mod(u1, bitCurve.P) + u2 := new(big.Int).Mul(x2, z1z1) + u2.Mod(u2, bitCurve.P) + h := new(big.Int).Sub(u2, u1) + if h.Sign() == -1 { + h.Add(h, bitCurve.P) + } + i := new(big.Int).Lsh(h, 1) + i.Mul(i, i) + j := new(big.Int).Mul(h, i) + + s1 := new(big.Int).Mul(y1, z2) + s1.Mul(s1, z2z2) + s1.Mod(s1, bitCurve.P) + s2 := new(big.Int).Mul(y2, z1) + s2.Mul(s2, z1z1) + s2.Mod(s2, bitCurve.P) + r := new(big.Int).Sub(s2, s1) + if r.Sign() == -1 { + r.Add(r, bitCurve.P) + } + r.Lsh(r, 1) + v := new(big.Int).Mul(u1, i) + + x3 := new(big.Int).Set(r) + x3.Mul(x3, x3) + x3.Sub(x3, j) + x3.Sub(x3, v) + x3.Sub(x3, v) + x3.Mod(x3, bitCurve.P) + + y3 := new(big.Int).Set(r) + v.Sub(v, x3) + y3.Mul(y3, v) + s1.Mul(s1, j) + s1.Lsh(s1, 1) + y3.Sub(y3, s1) + y3.Mod(y3, bitCurve.P) + + z3 := new(big.Int).Add(z1, z2) + z3.Mul(z3, z3) + z3.Sub(z3, z1z1) + if z3.Sign() == -1 { + z3.Add(z3, bitCurve.P) + } + z3.Sub(z3, z2z2) + if z3.Sign() == -1 { + z3.Add(z3, bitCurve.P) + } + z3.Mul(z3, h) + z3.Mod(z3, bitCurve.P) + + return x3, y3, z3 +} + +// Double returns 2*(x,y) +func (bitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + z1 := new(big.Int).SetInt64(1) + return bitCurve.affineFromJacobian(bitCurve.doubleJacobian(x1, y1, z1)) +} + +// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and +// returns its double, also in Jacobian form. +func (bitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { + // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + + a := new(big.Int).Mul(x, x) // X1² + b := new(big.Int).Mul(y, y) // Y1² + c := new(big.Int).Mul(b, b) // B² + + d := new(big.Int).Add(x, b) // X1+B + d.Mul(d, d) //(X1+B)² + d.Sub(d, a) //(X1+B)²-A + d.Sub(d, c) //(X1+B)²-A-C + d.Mul(d, big.NewInt(2)) // 2*((X1+B)²-A-C) + + e := new(big.Int).Mul(big.NewInt(3), a) // 3*A + f := new(big.Int).Mul(e, e) // E² + + x3 := new(big.Int).Mul(big.NewInt(2), d) // 2*D + x3.Sub(f, x3) // F-2*D + x3.Mod(x3, bitCurve.P) + + y3 := new(big.Int).Sub(d, x3) // D-X3 + y3.Mul(e, y3) // E*(D-X3) + y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) // E*(D-X3)-8*C + y3.Mod(y3, bitCurve.P) + + z3 := new(big.Int).Mul(y, z) // Y1*Z1 + z3.Mul(big.NewInt(2), z3) // 3*Y1*Z1 + z3.Mod(z3, bitCurve.P) + + return x3, y3, z3 +} + +// ScalarBaseMult returns k*G, where G is the base point of the group and k is +// an integer in big-endian form. +func (bitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + return bitCurve.ScalarMult(bitCurve.Gx, bitCurve.Gy, k) +} + +// Marshal converts a point into the form specified in section 4.3.6 of ANSI +// X9.62. +func (bitCurve *BitCurve) Marshal(x, y *big.Int) []byte { + byteLen := (bitCurve.BitSize + 7) >> 3 + ret := make([]byte, 1+2*byteLen) + ret[0] = 4 // uncompressed point flag + readBits(x, ret[1:1+byteLen]) + readBits(y, ret[1+byteLen:]) + return ret +} + +// Unmarshal converts a point, serialised by Marshal, into an x, y pair. On +// error, x = nil. +func (bitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { + byteLen := (bitCurve.BitSize + 7) >> 3 + if len(data) != 1+2*byteLen { + return + } + if data[0] != 4 { // uncompressed form + return + } + x = new(big.Int).SetBytes(data[1 : 1+byteLen]) + y = new(big.Int).SetBytes(data[1+byteLen:]) + return +} + +var theCurve = new(BitCurve) + +func init() { + // See SEC 2 section 2.7.1 + // curve parameters taken from: + // http://www.secg.org/sec2-v2.pdf + theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0) + theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0) + theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0) + theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0) + theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0) + theCurve.BitSize = 256 +} + +// S256 returns a BitCurve which implements secp256k1. +func S256() *BitCurve { + return theCurve +} diff --git a/pkg/crypto/core/curves/sp256_curve.go b/pkg/crypto/core/curves/sp256_curve.go new file mode 100644 index 000000000..e7831f091 --- /dev/null +++ b/pkg/crypto/core/curves/sp256_curve.go @@ -0,0 +1,11 @@ +package curves + +import ( + "crypto/elliptic" + + "github.com/dustinxie/ecc" +) + +func SP256() elliptic.Curve { + return ecc.P256k1() +} diff --git a/pkg/crypto/core/hash.go b/pkg/crypto/core/hash.go new file mode 100755 index 000000000..ec3680101 --- /dev/null +++ b/pkg/crypto/core/hash.go @@ -0,0 +1,272 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package core + +import ( + "bytes" + "crypto/elliptic" + "crypto/sha256" + "fmt" + "hash" + "math" + "math/big" + + "github.com/btcsuite/btcd/btcec/v2" + "golang.org/x/crypto/hkdf" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +type HashField struct { + // F_p^k + Order *big.Int // p^k + Characteristic *big.Int // p + ExtensionDegree *big.Int // k +} + +type Params struct { + F *HashField + SecurityParameter int + Hash func() hash.Hash + L int +} + +func getParams(curve elliptic.Curve) (*Params, error) { + switch curve.Params().Name { + case btcec.S256().Name, elliptic.P256().Params().Name: + return &Params{ + F: &HashField{ + Order: curve.Params().P, + Characteristic: curve.Params().P, + ExtensionDegree: new(big.Int).SetInt64(1), + }, + SecurityParameter: 128, + Hash: sha256.New, + L: 48, + }, nil + case "Bls12381G1": + return &Params{ + F: &HashField{ + Order: curve.Params().P, + Characteristic: curve.Params().P, + ExtensionDegree: new(big.Int).SetInt64(1), + }, + SecurityParameter: 128, + Hash: sha256.New, + L: 48, + }, nil + case "ed25519": + return &Params{ + F: &HashField{ + Order: curve.Params().P, + Characteristic: curve.Params().P, + ExtensionDegree: new(big.Int).SetInt64(1), + }, + SecurityParameter: 128, + Hash: sha256.New, + L: 48, + }, nil + default: + return nil, fmt.Errorf("not implemented: %s", curve.Params().Name) + } +} + +func I2OSP(b, n int) []byte { + os := new(big.Int).SetInt64(int64(b)).Bytes() + if n > len(os) { + var buf bytes.Buffer + buf.Write(make([]byte, n-len(os))) + buf.Write(os) + return buf.Bytes() + } + return os[:n] +} + +func OS2IP(os []byte) *big.Int { + return new(big.Int).SetBytes(os) +} + +func hashThis(f func() hash.Hash, this []byte) ([]byte, error) { + h := f() + w, err := h.Write(this) + if w != len(this) { + return nil, fmt.Errorf("bytes written to hash doesn't match expected") + } else if err != nil { + return nil, err + } + v := h.Sum(nil) + return v, nil +} + +func concat(xs ...[]byte) []byte { + var result []byte + for _, x := range xs { + result = append(result, x...) + } + return result +} + +func xor(b1, b2 []byte) []byte { + // b1 and b2 must be same length + result := make([]byte, len(b1)) + for i := range b1 { + result[i] = b1[i] ^ b2[i] + } + + return result +} + +func ExpandMessageXmd(f func() hash.Hash, msg, DST []byte, lenInBytes int) ([]byte, error) { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.1 + + // step 1 + ell := int(math.Ceil(float64(lenInBytes) / float64(f().Size()))) + + // step 2 + if ell > 255 { + return nil, fmt.Errorf("ell > 255") + } + + // step 3 + dstPrime := append(DST, I2OSP(len(DST), 1)...) + + // step 4 + zPad := I2OSP(0, f().BlockSize()) + + // step 5 & 6 + msgPrime := concat(zPad, msg, I2OSP(lenInBytes, 2), I2OSP(0, 1), dstPrime) + + var err error + + b := make([][]byte, ell+1) + + // step 7 + b[0], err = hashThis(f, msgPrime) + if err != nil { + return nil, err + } + + // step 8 + b[1], err = hashThis(f, concat(b[0], I2OSP(1, 1), dstPrime)) + if err != nil { + return nil, err + } + + // step 9 + for i := 2; i <= ell; i++ { + // step 10 + b[i], err = hashThis(f, concat(xor(b[0], b[i-1]), I2OSP(i, 1), dstPrime)) + if err != nil { + return nil, err + } + } + // step 11 + uniformBytes := concat(b[1:]...) + + // step 12 + return uniformBytes[:lenInBytes], nil +} + +func hashToField(msg []byte, count int, curve elliptic.Curve) ([][]*big.Int, error) { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.3 + + parameters, err := getParams(curve) + if err != nil { + return nil, err + } + + f := parameters.Hash + + DST := []byte("Coinbase_tECDSA") + + m := int(parameters.F.ExtensionDegree.Int64()) + L := parameters.L + + // step 1 + lenInBytes := count * m * L + + // step 2 + uniformBytes, err := ExpandMessageXmd(f, msg, DST, lenInBytes) + if err != nil { + return nil, err + } + + u := make([][]*big.Int, count) + + // step 3 + for i := 0; i < count; i++ { + e := make([]*big.Int, m) + // step 4 + for j := 0; j < m; j++ { + // step 5 + elmOffset := L * (j + i*m) + // step 6 + tv := uniformBytes[elmOffset : elmOffset+L] + // step 7 + e[j] = new(big.Int).Mod(OS2IP(tv), parameters.F.Characteristic) + + } + // step 8 + u[i] = e + } + // step 9 + return u, nil +} + +func Hash(msg []byte, curve elliptic.Curve) (*big.Int, error) { + u, err := hashToField(msg, 1, curve) + if err != nil { + return nil, err + } + return u[0][0], nil +} + +// fiatShamir computes the HKDF over many values +// iteratively such that each value is hashed separately +// and based on preceding values +// +// The first value is computed as okm_0 = KDF(f || value) where +// f is a byte slice of 32 0xFF +// salt is zero-filled byte slice with length equal to the hash output length +// info is the protocol name +// okm is the 32 byte output +// +// The each subsequent iteration is computed by as okm_i = KDF(f_i || value || okm_{i-1}) +// where f_i = 2^b - 1 - i such that there are 0xFF bytes prior to the value. +// f_1 changes the first byte to 0xFE, f_2 to 0xFD. The previous okm is appended to the value +// to provide cryptographic domain separation. +// See https://signal.org/docs/specifications/x3dh/#cryptographic-notation +// and https://signal.org/docs/specifications/xeddsa/#hash-functions +// for more details. +// This uses the KDF function similar to X3DH for each `value` +// But changes the key just like XEdDSA where the prefix bytes change by a single bit +func FiatShamir(values ...*big.Int) ([]byte, error) { + // Don't accept any nil arguments + if AnyNil(values...) { + return nil, internal.ErrNilArguments + } + + info := []byte("Coinbase tECDSA 1.0") + salt := make([]byte, 32) + okm := make([]byte, 32) + f := bytes.Repeat([]byte{0xFF}, 32) + + for _, b := range values { + ikm := append(f, b.Bytes()...) + ikm = append(ikm, okm...) + kdf := hkdf.New(sha256.New, ikm, salt, info) + n, err := kdf.Read(okm) + if err != nil { + return nil, err + } + if n != len(okm) { + return nil, fmt.Errorf("unable to read expected number of bytes want=%v got=%v", len(okm), n) + } + internal.ByteSub(f) + } + return okm, nil +} diff --git a/pkg/crypto/core/hash_test.go b/pkg/crypto/core/hash_test.go new file mode 100755 index 000000000..13873c36b --- /dev/null +++ b/pkg/crypto/core/hash_test.go @@ -0,0 +1,132 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package core + +import ( + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "fmt" + "hash" + "math/big" + "strconv" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestExpandMessageXmd(t *testing.T) { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-K.1 + tests := []struct { + f func() hash.Hash + msg []byte + lenInBytesHex string + expectedHex string + }{ + {sha256.New, []byte(""), "20", "f659819a6473c1835b25ea59e3d38914c98b374f0970b7e4c92181df928fca88"}, + {sha256.New, []byte("abc"), "20", "1c38f7c211ef233367b2420d04798fa4698080a8901021a795a1151775fe4da7"}, + {sha256.New, []byte("abcdef0123456789"), "20", "8f7e7b66791f0da0dbb5ec7c22ec637f79758c0a48170bfb7c4611bd304ece89"}, + {sha256.New, []byte("q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"), "20", "72d5aa5ec810370d1f0013c0df2f1d65699494ee2a39f72e1716b1b964e1c642"}, + {sha256.New, []byte("a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), "20", "3b8e704fc48336aca4c2a12195b720882f2162a4b7b13a9c350db46f429b771b"}, + {sha256.New, []byte(""), "80", "8bcffd1a3cae24cf9cd7ab85628fd111bb17e3739d3b53f89580d217aa79526f1708354a76a402d3569d6a9d19ef3de4d0b991e4f54b9f20dcde9b95a66824cbdf6c1a963a1913d43fd7ac443a02fc5d9d8d77e2071b86ab114a9f34150954a7531da568a1ea8c760861c0cde2005afc2c114042ee7b5848f5303f0611cf297f"}, + {sha256.New, []byte("abc"), "80", "fe994ec51bdaa821598047b3121c149b364b178606d5e72bfbb713933acc29c186f316baecf7ea22212f2496ef3f785a27e84a40d8b299cec56032763eceeff4c61bd1fe65ed81decafff4a31d0198619c0aa0c6c51fca15520789925e813dcfd318b542f8799441271f4db9ee3b8092a7a2e8d5b75b73e28fb1ab6b4573c192"}, + {sha256.New, []byte("abcdef0123456789"), "80", "c9ec7941811b1e19ce98e21db28d22259354d4d0643e301175e2f474e030d32694e9dd5520dde93f3600d8edad94e5c364903088a7228cc9eff685d7eaac50d5a5a8229d083b51de4ccc3733917f4b9535a819b445814890b7029b5de805bf62b33a4dc7e24acdf2c924e9fe50d55a6b832c8c84c7f82474b34e48c6d43867be"}, + {sha256.New, []byte("q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"), "80", "48e256ddba722053ba462b2b93351fc966026e6d6db493189798181c5f3feea377b5a6f1d8368d7453faef715f9aecb078cd402cbd548c0e179c4ed1e4c7e5b048e0a39d31817b5b24f50db58bb3720fe96ba53db947842120a068816ac05c159bb5266c63658b4f000cbf87b1209a225def8ef1dca917bcda79a1e42acd8069"}, + {sha256.New, []byte("a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), "80", "396962db47f749ec3b5042ce2452b619607f27fd3939ece2746a7614fb83a1d097f554df3927b084e55de92c7871430d6b95c2a13896d8a33bc48587b1f66d21b128a1a8240d5b0c26dfe795a1a842a0807bb148b77c2ef82ed4b6c9f7fcb732e7f94466c8b51e52bf378fba044a31f5cb44583a892f5969dcd73b3fa128816e"}, + + {sha512.New, []byte(""), "20", "2eaa1f7b5715f4736e6a5dbe288257abf1faa028680c1d938cd62ac699ead642"}, + {sha512.New, []byte("abc"), "20", "0eeda81f69376c80c0f8986496f22f21124cb3c562cf1dc608d2c13005553b0f"}, + {sha512.New, []byte("abcdef0123456789"), "20", "2e375fc05e05e80dbf3083796fde2911789d9e8847e1fcebf4ca4b36e239b338"}, + {sha512.New, []byte("q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"), "20", "c37f9095fe7fe4f01c03c3540c1229e6ac8583b07510085920f62ec66acc0197"}, + {sha512.New, []byte("a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), "20", "af57a7f56e9ed2aa88c6eab45c8c6e7638ae02da7c92cc04f6648c874ebd560e"}, + {sha512.New, []byte(""), "80", "0687ce02eba5eb3faf1c3c539d1f04babd3c0f420edae244eeb2253b6c6d6865145c31458e824b4e87ca61c3442dc7c8c9872b0b7250aa33e0668ccebbd2b386de658ca11a1dcceb51368721ae6dcd2d4bc86eaebc4e0d11fa02ad053289c9b28a03da6c942b2e12c14e88dbde3b0ba619d6214f47212b628f3e1b537b66efcf"}, + {sha512.New, []byte("abc"), "80", "779ae4fd8a92f365e4df96b9fde97b40486bb005c1a2096c86f55f3d92875d89045fbdbc4a0e9f2d3e1e6bcd870b2d7131d868225b6fe72881a81cc5166b5285393f71d2e68bb0ac603479959370d06bdbe5f0d8bfd9af9494d1e4029bd68ab35a561341dd3f866b3ef0c95c1fdfaab384ce24a23427803dda1db0c7d8d5344a"}, + {sha512.New, []byte("abcdef0123456789"), "80", "f0953d28846a50e9f88b7ae35b643fc43733c9618751b569a73960c655c068db7b9f044ad5a40d49d91c62302eaa26163c12abfa982e2b5d753049e000adf7630ae117aeb1fb9b61fc724431ac68b369e12a9481b4294384c3c890d576a79264787bc8076e7cdabe50c044130e480501046920ff090c1a091c88391502f0fbac"}, + {sha512.New, []byte("q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"), "80", "64d3e59f0bc3c5e653011c914b419ba8310390a9585311fddb26791d26663bd71971c347e1b5e88ba9274d2445ed9dcf48eea9528d807b7952924159b7c27caa4f25a2ea94df9508e70a7012dfce0e8021b37e59ea21b80aa9af7f1a1f2efa4fbe523c4266ce7d342acaacd438e452c501c131156b4945515e9008d2b155c258"}, + {sha512.New, []byte("a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), "80", "01524feea5b22f6509f6b1e805c97df94faf4d821b01aadeebc89e9daaed0733b4544e50852fd3e019d58eaad6d267a134c8bc2c08bc46c10bfeff3ee03110bcd8a0d695d75a34092bd8b677bdd369a13325549abab54f4ac907b712bdd3567f38c4554c51902b735b81f43a7ef6f938c7690d107c052c7e7b795ac635b3200a"}, + } + + for _, test := range tests { + t.Run(fmt.Sprintf("msg: %s", test.msg), func(t *testing.T) { + DST := []byte("QUUX-V01-CS02-with-expander") + lenInBytes, err := strconv.ParseInt(test.lenInBytesHex, 16, 64) + require.NoError(t, err) + expected, err := hex.DecodeString(test.expectedHex) + require.NoError(t, err) + actual, err := ExpandMessageXmd(test.f, test.msg, DST, int(lenInBytes)) + require.NoError(t, err) + require.Equal(t, actual, expected) + }) + } +} +func TestFiatShamirDeterministic(t *testing.T) { + a := big.NewInt(1) + hash, err := FiatShamir(a) + require.Nil(t, err) + require.Equal(t, hash, []byte{0x3d, 0x95, 0xc0, 0x9f, 0x41, 0x33, 0x25, 0xbb, 0x10, 0x77, 0x2d, 0x83, 0x1d, 0x3e, 0x67, 0x98, 0xce, 0x7b, 0xde, 0xd5, 0x7f, 0x9, 0x7e, 0xfc, 0x77, 0x23, 0xfc, 0x49, 0x36, 0x82, 0xdd, 0x6a}) + + a = big.NewInt(0xaaa) + hash, err = FiatShamir(a) + require.Nil(t, err) + require.Equal(t, hash, []byte{0x61, 0xa9, 0x7f, 0x6, 0x74, 0xec, 0x47, 0xf5, 0xac, 0x30, 0xa0, 0x4c, 0x34, 0xdb, 0x51, 0x97, 0x60, 0x7e, 0xb2, 0x4a, 0x97, 0x9, 0xa5, 0xb9, 0x1c, 0x89, 0x30, 0x39, 0xb7, 0x29, 0xe6, 0x30}) +} + +func TestFiatShamirEqual(t *testing.T) { + pi, err := FiatShamir(One) + require.Nil(t, err) + pi_, err := FiatShamir(One) + require.Nil(t, err) + require.Equal(t, pi, pi_) +} + +func TestFiatShamirNotEqual(t *testing.T) { + pi, err := FiatShamir(One) + require.Nil(t, err) + pi_, err := FiatShamir(Two) + require.Nil(t, err) + require.NotEqual(t, pi, pi_) +} + +func TestFiatShamirOrderDependent(t *testing.T) { + a := big.NewInt(1) + b := big.NewInt(100) + + pi, err := FiatShamir(a, b) + require.Nil(t, err) + pi_, err := FiatShamir(a, b) + require.Nil(t, err) + require.Equal(t, pi, pi_) + + q, _ := FiatShamir(b, a) + require.NotEqual(t, pi, q) +} + +func TestFiatShamirExtensionAttackResistance(t *testing.T) { + a := big.NewInt(0x00FF) + b := big.NewInt(0xFF00) + + c := big.NewInt(0x00) + d := big.NewInt(0xFFFF00) + + pi, err := FiatShamir(a, b) + require.Nil(t, err) + pi_, err := FiatShamir(c, d) + require.Nil(t, err) + require.NotEqual(t, pi, pi_) + + a = big.NewInt(0x0000) + b = big.NewInt(0xFFFF) + + c = big.NewInt(0x0000F) + d = big.NewInt(0xFFF) + + q, err := FiatShamir(a, b) + require.Nil(t, err) + q_, err := FiatShamir(c, d) + require.Nil(t, err) + require.NotEqual(t, q, q_) +} diff --git a/pkg/crypto/core/mod.go b/pkg/crypto/core/mod.go new file mode 100755 index 000000000..a9ae15cb7 --- /dev/null +++ b/pkg/crypto/core/mod.go @@ -0,0 +1,178 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Package core contains convenience functions for modular arithmetic. + +// Package core contains a set of primitives, including but not limited to various +// elliptic curves, hashes, and commitment schemes. These primitives are used internally +// and can also be used independently on their own externally. +package core + +import ( + crand "crypto/rand" + "crypto/subtle" + "fmt" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + // Zero is additive identity in the set of integers + Zero = big.NewInt(0) + + // One is the multiplicative identity in the set of integers + One = big.NewInt(1) + + // Two is the odd prime + Two = big.NewInt(2) +) + +// ConstantTimeEqByte determines if a, b have identical byte serialization +// and signs. It uses the crypto/subtle package to get a constant time comparison +// over byte representations. Return value is a byte which may be +// useful in bitwise operations. Returns 0x1 if the two values have the +// identical sign and byte representation; 0x0 otherwise. +func ConstantTimeEqByte(a, b *big.Int) byte { + if a == nil && a == b { + return 1 + } + if a == nil || b == nil { + return 0 + } + // Determine if the byte representations are the same + var sameBytes byte + if subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1 { + sameBytes = 1 + } else { + sameBytes = 0 + } + + // Determine if the signs are the same + var sameSign byte + if a.Sign() == b.Sign() { + sameSign = 1 + } else { + sameSign = 0 + } + + // Report the conjunction + return sameBytes & sameSign +} + +// ConstantTimeEq determines if a, b have identical byte serialization +// and uses the crypto/subtle package to get a constant time comparison +// over byte representations. +func ConstantTimeEq(a, b *big.Int) bool { + return ConstantTimeEqByte(a, b) == 1 +} + +// In determines ring membership before modular reduction: x ∈ Z_m +// returns nil if 0 ≤ x < m +func In(x, m *big.Int) error { + if AnyNil(x, m) { + return internal.ErrNilArguments + } + // subtle doesn't support constant time big.Int compare + // just use big.Cmp for now + // x ∈ Z_m ⇔ 0 ≤ x < m + if x.Cmp(Zero) != -1 && x.Cmp(m) == -1 { + return nil + } + return internal.ErrZmMembership +} + +// Add (modular addition): z = x+y (modulo m) +func Add(x, y, m *big.Int) (*big.Int, error) { + if AnyNil(x, y) { + return nil, internal.ErrNilArguments + } + z := new(big.Int).Add(x, y) + // Compute the residue if one is specified, otherwise + // we leave the value as an unbound integer + if m != nil { + z.Mod(z, m) + } + return z, nil +} + +// Mul (modular multiplication): z = x*y (modulo m) +func Mul(x, y, m *big.Int) (*big.Int, error) { + if AnyNil(x, y) { + return nil, internal.ErrNilArguments + } + z := new(big.Int).Mul(x, y) + + // Compute the residue if one is specified, otherwise + // we leave the value as an unbound integer + if m != nil { + z.Mod(z, m) + } + return z, nil +} + +// Exp (modular exponentiation): z = x^y (modulo m) +func Exp(x, y, m *big.Int) (*big.Int, error) { + if AnyNil(x, y) { + return nil, internal.ErrNilArguments + } + // This wrapper looks silly, but it makes the calling code read more consistently. + return new(big.Int).Exp(x, y, m), nil +} + +// Neg (modular negation): z = -x (modulo m) +func Neg(x, m *big.Int) (*big.Int, error) { + if AnyNil(x, m) { + return nil, internal.ErrNilArguments + } + z := new(big.Int).Neg(x) + z.Mod(z, m) + return z, nil +} + +// Inv (modular inverse): returns y such that xy = 1 (modulo m). +func Inv(x, m *big.Int) (*big.Int, error) { + if AnyNil(x, m) { + return nil, internal.ErrNilArguments + } + z := new(big.Int).ModInverse(x, m) + if z == nil { + return nil, fmt.Errorf("cannot compute the multiplicative inverse") + } + return z, nil +} + +// Rand generates a cryptographically secure random integer in the range: 1 < r < m. +func Rand(m *big.Int) (*big.Int, error) { + if m == nil { + return nil, internal.ErrNilArguments + } + + // Select a random element, but not zero or one + // The reason is the random element may be used as a Scalar or an exponent. + // An exponent of 1 is generally acceptable because the generator can't be + // 1. If a Scalar is combined with another Scalar like in fiat-shamir, it + // offers no hiding properties when multiplied. + for { + result, err := crand.Int(crand.Reader, m) + if err != nil { + return nil, err + } + + if result.Cmp(One) == 1 { // result > 1 + return result, nil + } + } +} + +// AnyNil determines if any of values are nil +func AnyNil(values ...*big.Int) bool { + for _, x := range values { + if x == nil { + return true + } + } + return false +} diff --git a/pkg/crypto/core/mod_test.go b/pkg/crypto/core/mod_test.go new file mode 100755 index 000000000..3114ad51b --- /dev/null +++ b/pkg/crypto/core/mod_test.go @@ -0,0 +1,565 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package core + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + four = big.NewInt(4) + + // Large numbers for testing -- computing with independent tooling + // x,y 100-digit numbers + x, _ = new(big.Int).SetString("7146643783615963513942641287213372249533955323510461217840179896547799100626220786140425637990097431", 10) + y, _ = new(big.Int).SetString("1747698065194620177681258504464368264357359841192790848951902311522815739310792522712583635858354245", 10) + sumxy, _ = new(big.Int).SetString("8894341848810583691623899791677740513891315164703252066792082208070614839937013308853009273848451676", 10) + xy, _ = new(big.Int).SetString("12490175513260779219420155073726764321605372267033815716483640700978475653623775696463227582174703069158832890348206546318843052423532258178885792744599932977235221784868792263260215861775082862444595", 10) + + // 101-digit modulus + m, _ = new(big.Int).SetString("85832751158419329546684678412285185885848111422509523329716452068504806021136687603399722116388773253", 10) + + // 99-digit modulus + n, _ = new(big.Int).SetString("604464499356780653111583485887412477603580949137220100557796699530113283915988830359783807274682723", 10) +) + +func TestConstantTimeEqByteSound(t *testing.T) { + hundoDigit := internal.B10("3593421565679030456559622742114065111786271367498220644136232358421457354322411370928949366452183472") + tests := []struct { + name string + a, b *big.Int + expected byte + }{ + {"positive: 5", internal.B10("5"), internal.B10("5"), 1}, + {"positive: 100", internal.B10("100"), internal.B10("100"), 1}, + {"positive: -1204", internal.B10("-1204"), internal.B10("-1204"), 1}, + {"positive: 100 digits", hundoDigit, hundoDigit, 1}, + {"positive: 0", internal.B10("0"), internal.B10("0"), 1}, + {"positive: 0/-0", internal.B10("0"), internal.B10("-0"), 1}, + {"positive: -0/-0", internal.B10("-0"), internal.B10("-0"), 1}, + + {"negative: 5/-5", internal.B10("5"), internal.B10("-5"), 0}, + {"negative: 5/500", internal.B10("5"), internal.B10("500"), 0}, + {"negative: 100/100 digit", internal.B10("100"), hundoDigit, 0}, + {"negative: -1204/-5", internal.B10("-1204"), internal.B10("-15"), 0}, + {"negative: 0/-5 digits", internal.B10("0"), internal.B10("-5"), 0}, + } + // Run all the tests! + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + actual := ConstantTimeEqByte(test.a, test.b) + require.Equal(t, test.expected, actual) + }) + } +} + +func TestConstantTimeEqSound(t *testing.T) { + hundoDigit := internal.B10("3593421565679030456559622742114065111786271367498220644136232358421457354322411370928949366452183472") + tests := []struct { + name string + a, b *big.Int + expected bool + }{ + {"positive: 5", internal.B10("5"), internal.B10("5"), true}, + {"positive: 100", internal.B10("100"), internal.B10("100"), true}, + {"positive: -1204", internal.B10("-1204"), internal.B10("-1204"), true}, + {"positive: 100 digits", hundoDigit, hundoDigit, true}, + {"positive: 0", internal.B10("0"), internal.B10("0"), true}, + {"positive: 0/-0", internal.B10("0"), internal.B10("-0"), true}, + {"positive: -0/-0", internal.B10("-0"), internal.B10("-0"), true}, + + {"negative: 5/-5", internal.B10("5"), internal.B10("-5"), false}, + {"negative: 5/500", internal.B10("5"), internal.B10("500"), false}, + {"negative: 100/100 digit", internal.B10("100"), hundoDigit, false}, + {"negative: -1204/-5", internal.B10("-1204"), internal.B10("-15"), false}, + {"negative: 0/-5 digits", internal.B10("0"), internal.B10("-5"), false}, + } + // Run all the tests! + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + actual := ConstantTimeEq(test.a, test.b) + require.Equal(t, test.expected, actual) + }) + } +} + +// Ring membership tests +func TestIn(t *testing.T) { + // Some large numbers for testing + x, _ := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208583", 10) + y, _ := new(big.Int).SetString("32168432167132168106409840321684604654063138460840123871234181628904319728058", 10) + N := new(big.Int).Mul(x, y) // N = xy + NN := new(big.Int).Mul(N, N) // N^2 = N*N = x^2y^2 + errMember := internal.ErrZmMembership + + tests := []struct { + x *big.Int + m *big.Int + expected error + }{ + // + // Completist test for: Z_4 + // + // Too small: -x ∉ Z_4, \forall \x \in \N + {big.NewInt(-4), four, errMember}, + {big.NewInt(-3), four, errMember}, + {big.NewInt(-2), four, errMember}, + {big.NewInt(-1), four, errMember}, + + // Just right: {0,1,2,3} = Z_4 + {big.NewInt(0), four, nil}, + {big.NewInt(1), four, nil}, + {big.NewInt(2), four, nil}, + {big.NewInt(3), four, nil}, + + // Too big: {4,5,6,7} ∉ Z_4 + {big.NewInt(4), four, errMember}, + {big.NewInt(5), four, errMember}, + {big.NewInt(6), four, errMember}, + {big.NewInt(7), four, errMember}, + + // + // Large numbers + // + // x,y,N < N^2 + {x, NN, nil}, + {y, NN, nil}, + {N, NN, nil}, + + // N+x,N+y,2N < N^2 ⇒ x ∈ Z_N^2 + {big.NewInt(0).Add(N, x), NN, nil}, + {big.NewInt(0).Add(N, y), NN, nil}, + {big.NewInt(0).Add(N, N), NN, nil}, + + // Nx,Ny < N^2 ⇒ x ∈ Z_N^2 + {big.NewInt(0).Mul(N, x), NN, nil}, + {big.NewInt(0).Mul(N, y), NN, nil}, + + // -x,-y,-N ∉ Z_N^2 + {big.NewInt(0).Neg(x), NN, errMember}, + {big.NewInt(0).Neg(y), NN, errMember}, + {big.NewInt(0).Neg(N), NN, errMember}, + + // N^2 ∉ Z_N^2 + {NN, NN, errMember}, + } + + // All the tests! + for _, test := range tests { + actual := In(test.x, test.m) + require.Equal(t, test.expected, actual) + } +} + +// Tests for modular addition with known answers +func TestAdd(t *testing.T) { + // Pre-compute some values + sumXyModn, err := Add(x, y, n) + require.Nil(t, err) + + tests := []struct { + x, y, m, expected *big.Int // inputs: x,y,m + }{ + // Small number tests + {big.NewInt(-1), big.NewInt(1), four, big.NewInt(0)}, + {big.NewInt(2), big.NewInt(1), four, big.NewInt(3)}, + {big.NewInt(0), big.NewInt(2), four, big.NewInt(2)}, + {big.NewInt(2), big.NewInt(4), four, big.NewInt(2)}, + {big.NewInt(15), big.NewInt(15), four, big.NewInt(2)}, + + // Large number tests + {x, y, m, sumxy}, + {y, x, m, sumxy}, + + // Large number Zero tests + {Zero, x, m, x}, + {x, Zero, m, x}, + {Zero, y, m, y}, + {y, Zero, m, y}, + + // Commutative + {x, y, m, sumxy}, + {y, x, m, sumxy}, + {x, y, n, sumXyModn}, + {y, x, n, sumXyModn}, + {sumXyModn, Zero, n, sumXyModn}, + {Zero, sumXyModn, n, sumXyModn}, + } + // All the tests! + for _, test := range tests { + actual, err := Add(test.x, test.y, test.m) + require.NoError(t, err) + require.Zero(t, actual.Cmp(test.expected)) + } +} + +// Tests for modular addition according to known invariants +func TestAddInvariants(t *testing.T) { + inputs := []*big.Int{x, y, Zero, One, new(big.Int).Neg(x), new(big.Int).Neg(y)} + moduli := []*big.Int{m, n, big.NewInt(10001)} + + // Run all combinations of the inputs/moduli + for _, x := range inputs { + for _, y := range inputs { + for _, m := range moduli { + + // Addition is commutative + z0, err := Add(x, y, m) + require.NoError(t, err) + z1, err := Add(y, x, m) + require.NoError(t, err) + require.Equal(t, z0, z1) + + // Addition is transitive: x+x+y == y+x+x == x+y+x + a0, _ := Add(x, x, m) + a0, _ = Add(a0, y, m) + + a1, _ := Add(y, x, m) + a1, _ = Add(a1, x, m) + + a2, _ := Add(x, y, m) + a2, _ = Add(a2, x, m) + + require.Equal(t, a0, a1) + require.Equal(t, a1, a2) + } + } + } +} + +// Tests modular multiplication with known answers +func TestMul(t *testing.T) { + // Pre-compute some values + xyModm := new(big.Int).Mod(xy, m) + + tests := []struct { + x, y, m, expected *big.Int // inputs: x,y,m + }{ + // Small number tests + {big.NewInt(-1), big.NewInt(1), four, big.NewInt(3)}, + {big.NewInt(2), big.NewInt(1), four, big.NewInt(2)}, + {big.NewInt(0), big.NewInt(2), four, big.NewInt(0)}, + {big.NewInt(2), big.NewInt(4), four, big.NewInt(0)}, + {big.NewInt(15), big.NewInt(15), four, big.NewInt(1)}, + + // Large number tests + {x, y, m, xyModm}, + {y, x, m, xyModm}, + + // Large number Zero tests + {Zero, x, m, Zero}, + {x, Zero, m, Zero}, + {Zero, y, n, Zero}, + } + // All the tests! + for _, test := range tests { + z, err := Mul(test.x, test.y, test.m) + require.NoError(t, err) + require.Zero(t, z.Cmp(test.expected)) + } +} + +// Tests for modular multiplication according to known invariants +func TestMulInvariants(t *testing.T) { + inputs := []*big.Int{x, y, Zero, One, new(big.Int).Neg(x), new(big.Int).Neg(y)} + moduli := []*big.Int{m, n, big.NewInt(10001)} + + // Run all combinations of the inputs/moduli + for _, x := range inputs { + for _, y := range inputs { + for _, m := range moduli { + + // Mul is commutative + a, err := Mul(x, y, m) + require.NoError(t, err) + aʹ, err := Mul(y, x, m) + require.NoError(t, err) + require.Equal(t, a, aʹ) + + // Mul is transitive: (xx)y == (xy)x + z, _ := Mul(x, x, m) + z, _ = Mul(z, y, m) + + zʹ, _ := Mul(x, y, m) + zʹ, _ = Mul(zʹ, x, m) + require.Equal(t, z, zʹ) + } + } + } +} + +// Tests modular negation with known answers +func TestNeg(t *testing.T) { + tests := []struct { + x, m, e *big.Int + }{ + {big.NewInt(1), big.NewInt(7), big.NewInt(6)}, + {big.NewInt(2), big.NewInt(7), big.NewInt(5)}, + {big.NewInt(3), big.NewInt(7), big.NewInt(4)}, + {big.NewInt(4), big.NewInt(7), big.NewInt(3)}, + {big.NewInt(5), big.NewInt(7), big.NewInt(2)}, + {big.NewInt(6), big.NewInt(7), big.NewInt(1)}, + + {big.NewInt(-1), big.NewInt(7), big.NewInt(1)}, + {big.NewInt(-2), big.NewInt(7), big.NewInt(2)}, + {big.NewInt(-3), big.NewInt(7), big.NewInt(3)}, + {big.NewInt(-4), big.NewInt(7), big.NewInt(4)}, + {big.NewInt(-5), big.NewInt(7), big.NewInt(5)}, + {big.NewInt(-6), big.NewInt(7), big.NewInt(6)}, + + {big.NewInt(8), big.NewInt(7), big.NewInt(6)}, + {big.NewInt(9), big.NewInt(7), big.NewInt(5)}, + {big.NewInt(10), big.NewInt(7), big.NewInt(4)}, + {big.NewInt(11), big.NewInt(7), big.NewInt(3)}, + {big.NewInt(12), big.NewInt(7), big.NewInt(2)}, + {big.NewInt(13), big.NewInt(7), big.NewInt(1)}, + } + + for _, test := range tests { + r, err := Neg(test.x, test.m) + require.NoError(t, err) + if r.Cmp(test.e) != 0 { + t.Errorf("TestNeg failed. Expected %v, got: %v ", test.e, r) + } + } +} + +func TestNegInvariants(t *testing.T) { + tests := []struct { + x, m, e *big.Int + }{ + {big.NewInt(0), big.NewInt(7), big.NewInt(0)}, + {big.NewInt(7), big.NewInt(7), big.NewInt(0)}, + {big.NewInt(-7), big.NewInt(7), big.NewInt(0)}, + } + + for _, test := range tests { + r, err := Neg(test.x, test.m) + require.NoError(t, err) + if r.Cmp(test.e) != 0 { + t.Errorf("TestNeg failed. Expected %v, got: %v ", test.e, r) + } + } +} + +// Simple test for distinct Rand output +func TestRandDistinct(t *testing.T) { + // Each value should be distinct + a, _ := Rand(n) + b, _ := Rand(n) + c, _ := Rand(n) + + // ❄️❄️❄️ + require.NotEqual(t, a, b) + require.NotEqual(t, a, c) + require.NotEqual(t, b, c) +} + +// Rand values should be O(log2(m)) bits +func TestRandIsExpectedLength(t *testing.T) { + trials := 1000 + max := big.NewInt(-1) + + // Generate many nonces, keep the max + for i := 0; i < trials; i++ { + r, err := Rand(m) + require.NoError(t, err) + + // Nonces should be < m + if r.Cmp(m) != -1 { + t.Errorf("nonce too large, require %v < %v", r, m) + } + + if r.Cmp(max) == 1 { + max = r + } + } + + // With high probability, the max nonce should be very close N + lowerBound := new(big.Int).Rsh(m, 1) + if max.Cmp(lowerBound) == -1 { + t.Errorf("Expected max nonce: %v > %v", max, lowerBound) + } +} + +// Randomly selected nonces with a large modulus will be unique with overwhelming probability +func TestRandDistinctWithLargeModulus(t *testing.T) { + const iterations = 1000 + testUnique(t, iterations, func() *big.Int { + r, _ := Rand(m) + return r + }) +} + +// Calls sampleFunc() n times and asserts that the lower 64B of each output are unique. +func testUnique(t *testing.T, iterations int, sampleFunc func() *big.Int) { + // For simplicity, we test only the lower 64B of each nonce. This is sufficient + // to prove uniqueness and go-lang doesn't hash slices (no slices in maps) + const size = 256 / 8 + seen := make(map[[size]byte]bool) + var x [size]byte + + // Check the pre-computed commitments for uniquness + for i := 0; i < iterations; i++ { + // Retrieve a sample + sample := sampleFunc() + require.NotNil(t, sample) + + // Copy the bytes from slice>array + copy(x[:], sample.Bytes()) + + // Ensure each sample is unique + if seen[x] { + t.Errorf("duplicate sample found: %v", x) + } + seen[x] = true + } +} + +// Ensure Rand never returns 0 or 1. +func TestRandNotZeroNotOne(t *testing.T) { + // Test for non-zero only useful when iterations >> |Z_m| + const iterations = 1000 + m := big.NewInt(5) + + for i := 0; i < iterations; i++ { + r, err := Rand(m) + require.NoError(t, err) + // Not 0 or 1 + require.NotEqual(t, r, Zero) + require.NotEqual(t, r, One) + } +} + +func TestRand_NilModulusErrors(t *testing.T) { + r, err := Rand(nil) + require.Nil(t, r) + require.Contains(t, err.Error(), internal.ErrNilArguments.Error()) +} + +// Double-inverse is the identity function in fields +func TestInvRoundTrip(t *testing.T) { + m := internal.B10("1031") // Prime-order modulus + + for _, a := range []*big.Int{ + internal.B10("500"), + internal.B10("-500"), + internal.B10("1"), + internal.B10("1030"), + } { + // Our expected value is the modular reduction of the test value + expected := a.Mod(a, m) + + // Invert and check + aInv, err := Inv(a, m) + require.NoError(t, err, "a=%v", a) + require.NotNil(t, aInv) + + // Invert again and check + a_, err := Inv(aInv, m) + if err != nil { + require.Equal(t, expected, a_) + } + } +} + +// Tests values for which there is no inverse in the given field +func TestInvNotFound(t *testing.T) { + m := internal.B10("1024") // m = 2^10 + // 0 and even numbers will not have inverse in this ring + + for _, a := range []*big.Int{ + internal.B10("500"), + internal.B10("-500"), + internal.B10("0"), + internal.B10("1024"), + internal.B10("512"), + internal.B10("300000000"), + } { + // Invert and check + aInv, err := Inv(a, m) + require.Error(t, err, "a=%v", a) + require.Nil(t, aInv) + } +} + +func TestExpKnownAnswer(t *testing.T) { + p := internal.B10("1031") // prime-order field + pMinus1 := internal.B10("1030") + tests := []struct { + name string + x, e, m *big.Int + expected *big.Int + }{ + {"fermat's little thm: 500", internal.B10("500"), p, p, internal.B10("500")}, + {"fermat's little thm (p-1): 500", internal.B10("500"), pMinus1, p, One}, + {"fermat's little thm (p-1): 5000", internal.B10("5000"), pMinus1, p, One}, + {"399^0 = 1", internal.B10("399"), Zero, p, One}, + {"673^1 = 673", internal.B10("673"), One, p, internal.B10("673")}, + } + + // Run all the tests! + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + actual, err := Exp(test.x, test.e, test.m) + if err != nil { + require.Equal(t, test.expected, actual) + } + }) + } +} + +// A product of two 1024b safe primes +var N1024 = internal.B10("22657252520748253292205422817162431301953923432914829530688424232913850279325496327198502914522231560238552529734156383924448818535517634061008476071362010781638360092704508943571866960229942049437914690556866055765377519627454975682400206932320319743805083072214857842762721537739950074695623974079312071498296625705376593890814889314744719469735809152488403143751157723139035869185892099006348653635981206799193781030834368833947197930944812082594326193527332208252230115672713914945889734620959932802893197325106135662762752470236627025599443912886530954179753873735786171937758916890000958846322096261981191349917") + +// A product of two 256b safe primes +var N256 = internal.B10("10815068324662993508164204692909269429257853772524581783499643160896147777579932560873002543907262462663453338979819981987639157192530671167315407970757417") + +func Benchmark_rand1024(b *testing.B) { + if testing.Short() { + b.Skip("skipping test in short mode.") + } + + for i := 0; i < b.N; i++ { + Rand(N1024) // nolint + } +} + +func BenchmarkRand1024(b *testing.B) { + if testing.Short() { + b.Skip("skipping test in short mode.") + } + + for i := 0; i < b.N; i++ { + Rand(N1024) // nolint + } +} + +func Benchmark_rand256(b *testing.B) { + if testing.Short() { + b.Skip("skipping test in short mode.") + } + + for i := 0; i < b.N; i++ { + Rand(N256) // nolint + } +} + +func BenchmarkRandStar256(b *testing.B) { + if testing.Short() { + b.Skip("skipping test in short mode.") + } + + for i := 0; i < b.N; i++ { + Rand(N256) // nolint + } +} diff --git a/pkg/crypto/core/primes.go b/pkg/crypto/core/primes.go new file mode 100755 index 000000000..24ae766ed --- /dev/null +++ b/pkg/crypto/core/primes.go @@ -0,0 +1,42 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package core + +import ( + "crypto/rand" + "fmt" + "math" + "math/big" +) + +// GenerateSafePrime creates a prime number `p` +// where (`p`-1)/2 is also prime with at least `bits` +func GenerateSafePrime(bits uint) (*big.Int, error) { + if bits < 3 { + return nil, fmt.Errorf("safe prime size must be at least 3-bits") + } + + var p *big.Int + var err error + checks := int(math.Max(float64(bits)/16, 8)) + for { + // rand.Prime throws an error if bits < 2 + // -1 so the Sophie-Germain prime is 1023 bits + // and the Safe prime is 1024 + p, err = rand.Prime(rand.Reader, int(bits)-1) + if err != nil { + return nil, err + } + p.Add(p.Lsh(p, 1), One) + + if p.ProbablyPrime(checks) { + break + } + } + + return p, nil +} diff --git a/pkg/crypto/core/protocol/protocol.go b/pkg/crypto/core/protocol/protocol.go new file mode 100755 index 000000000..3927d9af4 --- /dev/null +++ b/pkg/crypto/core/protocol/protocol.go @@ -0,0 +1,109 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package protocol + +import ( + "encoding/base64" + "encoding/json" + "fmt" +) + +var ( + ErrNotInitialized = fmt.Errorf("object has not been initialized") + ErrProtocolFinished = fmt.Errorf("the protocol has finished") +) + +const ( + // Dkls18Dkg specifies the DKG protocol of the DKLs18 potocol. + Dkls18Dkg = "DKLs18-DKG" + + // Dkls18Sign specifies the DKG protocol of the DKLs18 potocol. + Dkls18Sign = "DKLs18-Sign" + + // Dkls18Refresh specifies the DKG protocol of the DKLs18 potocol. + Dkls18Refresh = "DKLs18-Refresh" + + // versions will increment in 100 intervals, to leave room for adding other versions in between them if it is + // ever needed in the future. + + // Version0 is version 0! + Version0 = 100 + + // Version1 is version 2! + Version1 = 200 +) + +// Message provides serializers and deserializer for the inputs and outputs of each step of the protocol. +// Moreover, it adds some metadata and versioning around the serialized data. +type Message struct { + Payloads map[string][]byte //`json:"payloads"` + Metadata map[string]string //`json:"metadata"` + Protocol string //`json:"protocol"` + Version uint //`json:"version"` +} + +// EncodeMessage encodes the message to a string. +func EncodeMessage(m *Message) (string, error) { + bz, err := json.Marshal(m) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(bz), nil +} + +// DecodeMessage decodes the message from a string. +func DecodeMessage(s string) (*Message, error) { + bz, err := base64.StdEncoding.DecodeString(s) + if err != nil { + return nil, err + } + var m Message + if err := json.Unmarshal(bz, &m); err != nil { + return nil, err + } + return &m, nil +} + +// MarshalJSON marshals the message to JSON. +func (m *Message) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`{"payloads":%s,"metadata":%s,"protocol":%s,"version":%d}`, m.Payloads, m.Metadata, m.Protocol, m.Version)), nil +} + +// UnmarshalJSON unmarshals the message from JSON. +func (m *Message) UnmarshalJSON(data []byte) error { + var obj map[string]interface{} + if err := json.Unmarshal(data, &obj); err != nil { + return err + } + m.Payloads = make(map[string][]byte) + m.Metadata = make(map[string]string) + for k, v := range obj { + switch k { + case "payloads": + m.Payloads = v.(map[string][]byte) + case "metadata": + m.Metadata = v.(map[string]string) + case "protocol": + m.Protocol = v.(string) + case "version": + m.Version = uint(v.(float64)) + } + } + return nil +} + +// Iterator an interface for the DKLs18 protocols that follows the iterator pattern. +type Iterator interface { + // Next runs the next round of the protocol. + // Returns `ErrProtocolFinished` when protocol has completed. + Next(input *Message) (*Message, error) + + // Result returns the final result, if any, of the completed protocol. + // Returns nil if the protocol has not yet terminated. + // Returns an error if an error was encountered during protocol execution. + Result(version uint) (*Message, error) +} diff --git a/pkg/crypto/daed/aes_siv.go b/pkg/crypto/daed/aes_siv.go new file mode 100644 index 000000000..faed548c0 --- /dev/null +++ b/pkg/crypto/daed/aes_siv.go @@ -0,0 +1,244 @@ +package daed + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/subtle" + "errors" + "fmt" + "math" + // Placeholder for internal crypto/cipher allowlist, please ignore. + // Placeholder for internal crypto/subtle allowlist, please ignore. +) + +// AESSIV is an implementation of AES-SIV-CMAC as defined in +// https://tools.ietf.org/html/rfc5297. +// +// AESSIV implements a deterministic encryption with associated data (i.e. the +// DeterministicAEAD interface). Hence the implementation below is restricted +// to one AD component. +// +// Security Note: +// +// Chatterjee, Menezes and Sarkar analyze AES-SIV in Section 5.1 of +// https://www.math.uwaterloo.ca/~ajmeneze/publications/tightness.pdf +// +// Their analysis shows that AES-SIV is susceptible to an attack in +// a multi-user setting. Concretely, if an attacker knows the encryption +// of a message m encrypted and authenticated with k different keys, +// then it is possible to find one of the MAC keys in time 2^b / k +// where b is the size of the MAC key. A consequence of this attack +// is that 128-bit MAC keys give unsufficient security. +// Since 192-bit AES keys are not supported by tink for voodoo reasons +// and RFC 5297 only supports same size encryption and MAC keys this +// implies that keys must be 64 bytes (2*256 bits) long. +type AESSIV struct { + Cipher cipher.Block + K1 []byte + K2 []byte + CmacK1 []byte + CmacK2 []byte +} + +const ( + // AESSIVKeySize is the key size in bytes. + AESSIVKeySize = 64 + + intSize = 32 << (^uint(0) >> 63) // 32 or 64 + maxInt = 1<<(intSize-1) - 1 +) + +// NewAESSIV returns an AESSIV instance. +func NewAESSIV(key []byte) (*AESSIV, error) { + if len(key) != AESSIVKeySize { + return nil, fmt.Errorf("aes_siv: invalid key size %d", len(key)) + } + + k1 := key[:32] + k2 := key[32:] + c, err := aes.NewCipher(k1) + if err != nil { + return nil, fmt.Errorf("aes_siv: aes.NewCipher(%s) failed, %v", k1, err) + } + + block := make([]byte, aes.BlockSize) + c.Encrypt(block, block) + multiplyByX(block) + cmacK1 := make([]byte, aes.BlockSize) + copy(cmacK1, block) + multiplyByX(block) + cmacK2 := make([]byte, aes.BlockSize) + copy(cmacK2, block) + + return &AESSIV{ + K1: k1, + K2: k2, + CmacK1: cmacK1, + CmacK2: cmacK2, + Cipher: c, + }, nil +} + +// multiplyByX multiplies an element in GF(2^128) by its generator. +// +// This function is incorrectly named "doubling" in section 2.3 of RFC 5297. +func multiplyByX(block []byte) { + carry := int(block[0] >> 7) + for i := 0; i < aes.BlockSize-1; i++ { + block[i] = (block[i] << 1) | (block[i+1] >> 7) + } + + block[aes.BlockSize-1] = (block[aes.BlockSize-1] << 1) ^ byte(subtle.ConstantTimeSelect(carry, 0x87, 0x00)) +} + +// EncryptDeterministically deterministically encrypts plaintext with associatedData. +func (asc *AESSIV) EncryptDeterministically(plaintext, associatedData []byte) ([]byte, error) { + if len(plaintext) > maxInt-aes.BlockSize { + return nil, fmt.Errorf("aes_siv: plaintext too long") + } + siv := make([]byte, aes.BlockSize) + asc.s2v(plaintext, associatedData, siv) + + ct := make([]byte, len(plaintext)+aes.BlockSize) + copy(ct[:aes.BlockSize], siv) + if err := asc.ctrCrypt(siv, plaintext, ct[aes.BlockSize:]); err != nil { + return nil, err + } + + return ct, nil +} + +// DecryptDeterministically deterministically decrypts ciphertext with associatedData. +func (asc *AESSIV) DecryptDeterministically(ciphertext, associatedData []byte) ([]byte, error) { + if len(ciphertext) < aes.BlockSize { + return nil, errors.New("aes_siv: ciphertext is too short") + } + + pt := make([]byte, len(ciphertext)-aes.BlockSize) + siv := ciphertext[:aes.BlockSize] + asc.ctrCrypt(siv, ciphertext[aes.BlockSize:], pt) + s2v := make([]byte, aes.BlockSize) + asc.s2v(pt, associatedData, s2v) + + diff := byte(0) + for i := 0; i < aes.BlockSize; i++ { + diff |= siv[i] ^ s2v[i] + } + if diff != 0 { + return nil, errors.New("aes_siv: invalid ciphertext") + } + + return pt, nil +} + +// ctrCrypt encrypts (or decrypts) the bytes in in using an SIV and writes the +// result to out. +func (asc *AESSIV) ctrCrypt(siv, in, out []byte) error { + // siv might be used outside of ctrCrypt(), so making a copy of it. + iv := make([]byte, aes.BlockSize) + copy(iv, siv) + iv[8] &= 0x7f + iv[12] &= 0x7f + + c, err := aes.NewCipher(asc.K2) + if err != nil { + return fmt.Errorf("aes_siv: aes.NewCipher(%s) failed, %v", asc.K2, err) + } + + steam := cipher.NewCTR(c, iv) + steam.XORKeyStream(out, in) + return nil +} + +// s2v is a Pseudo-Random Function (PRF) construction: +// https://tools.ietf.org/html/rfc5297. +func (asc *AESSIV) s2v(msg, ad, siv []byte) { + block := make([]byte, aes.BlockSize) + asc.cmac(block, block) + multiplyByX(block) + + adMac := make([]byte, aes.BlockSize) + asc.cmac(ad, adMac) + xorBlock(adMac, block) + + if len(msg) >= aes.BlockSize { + asc.cmacLong(msg, block, siv) + } else { + multiplyByX(block) + for i := 0; i < len(msg); i++ { + block[i] ^= msg[i] + } + block[len(msg)] ^= 0x80 + asc.cmac(block, siv) + } +} + +// cmacLong computes CMAC(XorEnd(data, last)), where XorEnd xors the bytes in +// last to the last bytes in data. +// +// The size of the data must be at least 16 bytes. +func (asc *AESSIV) cmacLong(data, last, mac []byte) { + block := make([]byte, aes.BlockSize) + copy(block, data[:aes.BlockSize]) + + idx := aes.BlockSize + for aes.BlockSize <= len(data)-idx { + asc.Cipher.Encrypt(block, block) + xorBlock(data[idx:idx+aes.BlockSize], block) + idx += aes.BlockSize + } + + remaining := len(data) - idx + for i := 0; i < aes.BlockSize-remaining; i++ { + block[remaining+i] ^= last[i] + } + if remaining == 0 { + xorBlock(asc.CmacK1, block) + } else { + asc.Cipher.Encrypt(block, block) + for i := 0; i < remaining; i++ { + block[i] ^= last[aes.BlockSize-remaining+i] + block[i] ^= data[idx+i] + } + block[remaining] ^= 0x80 + xorBlock(asc.CmacK2, block) + } + + asc.Cipher.Encrypt(mac, block) +} + +// cmac computes a CMAC of some data. +func (asc *AESSIV) cmac(data, mac []byte) { + numBs := int(math.Ceil(float64(len(data)) / aes.BlockSize)) + if numBs == 0 { + numBs = 1 + } + lastBSize := len(data) - (numBs-1)*aes.BlockSize + + block := make([]byte, aes.BlockSize) + idx := 0 + for i := 0; i < numBs-1; i++ { + xorBlock(data[idx:idx+aes.BlockSize], block) + asc.Cipher.Encrypt(block, block) + idx += aes.BlockSize + } + for j := 0; j < lastBSize; j++ { + block[j] ^= data[idx+j] + } + + if lastBSize == aes.BlockSize { + xorBlock(asc.CmacK1, block) + } else { + block[lastBSize] ^= 0x80 + xorBlock(asc.CmacK2, block) + } + + asc.Cipher.Encrypt(mac, block) +} + +// xorBlock sets block[i] = x[i] ^ block[i]. +func xorBlock(x, block []byte) { + for i := 0; i < aes.BlockSize; i++ { + block[i] ^= x[i] + } +} diff --git a/pkg/crypto/daed/aes_siv_test.go b/pkg/crypto/daed/aes_siv_test.go new file mode 100644 index 000000000..5831bb19f --- /dev/null +++ b/pkg/crypto/daed/aes_siv_test.go @@ -0,0 +1,303 @@ +package daed_test + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "os" + "path/filepath" + "testing" + + subtle "github.com/onsonr/sonr/pkg/crypto/daed" + "github.com/onsonr/sonr/pkg/crypto/subtle/random" +) + +type testData struct { + Algorithm string + GeneratorVersion string + TestGroups []*testGroup + NumberOfTests uint32 +} + +type testGroup struct { + Type string + Tests []*testCase + KeySize uint32 +} + +type testCase struct { + Key string + Aad string + Msg string + Ct string + Result string + TcID uint32 +} + +func TestAESSIV_EncryptDecrypt(t *testing.T) { + keyStr := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + key, _ := hex.DecodeString(keyStr) + msg := []byte("Some data to encrypt.") + aad := []byte("Additional data") + + a, err := subtle.NewAESSIV(key) + if err != nil { + t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) + } + + ct, err := a.EncryptDeterministically(msg, aad) + if err != nil { + t.Errorf("Unexpected encryption error: %v", err) + } + + if pt, err := a.DecryptDeterministically(ct, aad); err != nil { + t.Errorf("Unexpected decryption error: %v", err) + } else if !bytes.Equal(pt, msg) { + t.Errorf("Mismatched plaintexts: got %v, want %v", pt, msg) + } +} + +func TestAESSIV_EmptyPlaintext(t *testing.T) { + keyStr := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + key, _ := hex.DecodeString(keyStr) + aad := []byte("Additional data") + + a, err := subtle.NewAESSIV(key) + if err != nil { + t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) + } + + ct, err := a.EncryptDeterministically(nil, aad) + if err != nil { + t.Errorf("Unexpected encryption error: %v", err) + } + if pt, err := a.DecryptDeterministically(ct, aad); err != nil { + t.Errorf("Unexpected decryption error: %v", err) + } else if !bytes.Equal(pt, []byte{}) { + t.Errorf("Mismatched plaintexts: got %v, want []", pt) + } + + ct, err = a.EncryptDeterministically([]byte{}, aad) + if err != nil { + t.Errorf("Unexpected encryption error: %v", err) + } + if pt, err := a.DecryptDeterministically(ct, aad); err != nil { + t.Errorf("Unexpected decryption error: %v", err) + } else if !bytes.Equal(pt, []byte{}) { + t.Errorf("Mismatched plaintexts: got %v, want []", pt) + } +} + +func TestAESSIV_EmptyAdditionalData(t *testing.T) { + keyStr := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + key, _ := hex.DecodeString(keyStr) + + a, err := subtle.NewAESSIV(key) + if err != nil { + t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) + } + + ct, err := a.EncryptDeterministically(nil, nil) + if err != nil { + t.Errorf("Unexpected encryption error: %v", err) + } + + if pt, err := a.DecryptDeterministically(ct, nil); err != nil { + t.Errorf("Unexpected decryption error: %v", err) + } else if !bytes.Equal(pt, []byte{}) { + t.Errorf("Mismatched plaintexts: got %v, want []", pt) + } + + if pt, err := a.DecryptDeterministically(ct, []byte{}); err != nil { + t.Errorf("Unexpected decryption error: %v", err) + } else if !bytes.Equal(pt, []byte{}) { + t.Errorf("Mismatched plaintexts: got %v, want []", pt) + } +} + +func TestAESSIV_KeySizes(t *testing.T) { + keyStr := "198371900187498172316311acf81d238ff7619873a61983d619c87b63a1987f" + + "987131819803719b847126381cd763871638aa71638176328761287361231321" + + "812731321de508761437195ff231765aa4913219873ac6918639816312130011" + + "abc900bba11400187984719827431246bbab1231eb4145215ff7141436616beb" + + "9817298148712fed3aab61000ff123313e" + key, _ := hex.DecodeString(keyStr) + + for i := 0; i < len(key); i++ { + _, err := subtle.NewAESSIV(key[:i]) + if i == subtle.AESSIVKeySize && err != nil { + t.Errorf("Rejected valid key size: %v, %v", i, err) + } + if i != subtle.AESSIVKeySize && err == nil { + t.Errorf("Allowed invalid key size: %v", i) + } + } +} + +func TestAESSIV_MessageSizes(t *testing.T) { + keyStr := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + key, _ := hex.DecodeString(keyStr) + aad := []byte("Additional data") + + a, err := subtle.NewAESSIV(key) + if err != nil { + t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) + } + + for i := uint32(0); i < 1024; i++ { + msg := random.GetRandomBytes(i) + ct, err := a.EncryptDeterministically(msg, aad) + if err != nil { + t.Errorf("Unexpected encryption error: %v", err) + } + if pt, err := a.DecryptDeterministically(ct, aad); err != nil { + t.Errorf("Unexpected decryption error: %v", err) + } else if !bytes.Equal(pt, msg) { + t.Errorf("Mismatched plaintexts: got %v, want %v", pt, msg) + } + } + + for i := uint32(1024); i < 100000; i += 5000 { + msg := random.GetRandomBytes(i) + ct, err := a.EncryptDeterministically(msg, aad) + if err != nil { + t.Errorf("Unexpected encryption error: %v", err) + } + if pt, err := a.DecryptDeterministically(ct, aad); err != nil { + t.Errorf("Unexpected decryption error: %v", err) + } else if !bytes.Equal(pt, msg) { + t.Errorf("Mismatched plaintexts: got %v, want %v", pt, msg) + } + } +} + +func TestAESSIV_AdditionalDataSizes(t *testing.T) { + keyStr := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + key, _ := hex.DecodeString(keyStr) + msg := []byte("Some data to encrypt.") + + a, err := subtle.NewAESSIV(key) + if err != nil { + t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) + } + + for i := uint32(0); i < 1024; i++ { + aad := random.GetRandomBytes(i) + ct, err := a.EncryptDeterministically(msg, aad) + if err != nil { + t.Errorf("Unexpected encryption error: %v", err) + } + if pt, err := a.DecryptDeterministically(ct, aad); err != nil { + t.Errorf("Unexpected decryption error: %v", err) + } else if !bytes.Equal(pt, msg) { + t.Errorf("Mismatched plaintexts: got %v, want %v", pt, msg) + } + } +} + +func TestAESSIV_CiphertextModifications(t *testing.T) { + keyStr := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + + "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" + key, _ := hex.DecodeString(keyStr) + aad := []byte("Additional data") + + a, err := subtle.NewAESSIV(key) + if err != nil { + t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) + } + + for i := uint32(0); i < 50; i++ { + msg := random.GetRandomBytes(i) + ct, err := a.EncryptDeterministically(msg, aad) + if err != nil { + t.Errorf("Unexpected encryption error: %v", err) + } + for j := 0; j < len(ct); j++ { + for b := uint32(0); b < 8; b++ { + ct[j] ^= 1 << b + if _, err := a.DecryptDeterministically(ct, aad); err == nil { + t.Errorf("Modified ciphertext decrypted: byte %d, bit %d", j, b) + } + ct[j] ^= 1 << b + } + } + } +} + +func TestAESSIV_WycheproofVectors(t *testing.T) { + srcDir, ok := os.LookupEnv("TEST_SRCDIR") + if !ok { + t.Skip("TEST_SRCDIR not set") + } + f, err := os.Open(filepath.Join(srcDir, "wycheproof/testvectors/aes_siv_cmac_test.json")) + if err != nil { + t.Fatalf("Cannot open file: %s", err) + } + parser := json.NewDecoder(f) + data := new(testData) + if err := parser.Decode(data); err != nil { + t.Fatalf("Cannot decode test data: %s", err) + } + + for _, g := range data.TestGroups { + if g.KeySize/8 != subtle.AESSIVKeySize { + continue + } + + for _, tc := range g.Tests { + key, err := hex.DecodeString(tc.Key) + if err != nil { + t.Errorf("#%d, cannot decode key: %s", tc.TcID, err) + } + aad, err := hex.DecodeString(tc.Aad) + if err != nil { + t.Errorf("#%d, cannot decode aad: %s", tc.TcID, err) + } + msg, err := hex.DecodeString(tc.Msg) + if err != nil { + t.Errorf("#%d, cannot decode msg: %s", tc.TcID, err) + } + ct, err := hex.DecodeString(tc.Ct) + if err != nil { + t.Errorf("#%d, cannot decode ct: %s", tc.TcID, err) + } + + a, err := subtle.NewAESSIV(key) + if err != nil { + t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) + continue + } + + // EncryptDeterministically should always succeed since msg and aad are valid inputs. + gotCt, err := a.EncryptDeterministically(msg, aad) + if err != nil { + t.Errorf("#%d, unexpected encryption error: %v", tc.TcID, err) + } else { + if tc.Result == "valid" && !bytes.Equal(gotCt, ct) { + t.Errorf("#%d, incorrect encryption: got %v, want %v", tc.TcID, gotCt, ct) + } + if tc.Result == "invalid" && bytes.Equal(gotCt, ct) { + t.Errorf("#%d, invalid encryption: got %v, want %v", tc.TcID, gotCt, ct) + } + } + + pt, err := a.DecryptDeterministically(ct, aad) + if tc.Result == "valid" { + if err != nil { + t.Errorf("#%d, unexpected decryption error: %v", tc.TcID, err) + } else if !bytes.Equal(pt, msg) { + t.Errorf("#%d, incorrect decryption: got %v, want %v", tc.TcID, pt, msg) + } + } else { + if err == nil { + t.Errorf("#%d, decryption error expected: got nil", tc.TcID) + } + } + } + } +} diff --git a/pkg/crypto/dkg/frost/README.md b/pkg/crypto/dkg/frost/README.md new file mode 100755 index 000000000..a85c425a7 --- /dev/null +++ b/pkg/crypto/dkg/frost/README.md @@ -0,0 +1,13 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## FROST: Flexible Round-Optimized Schnorr Threshold Signatures + +This package is an implementation of the DKG part of +[FROST: Flexible Round-Optimized Schnorr Threshold Signatures](https://eprint.iacr.org/2020/852.pdf) diff --git a/pkg/crypto/dkg/frost/dkg_round1.go b/pkg/crypto/dkg/frost/dkg_round1.go new file mode 100755 index 000000000..7af575091 --- /dev/null +++ b/pkg/crypto/dkg/frost/dkg_round1.go @@ -0,0 +1,148 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package frost + +import ( + "bytes" + crand "crypto/rand" + "encoding/gob" + "fmt" + "reflect" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" + "github.com/onsonr/sonr/pkg/crypto/sharing" +) + +// Round1Bcast are values that are broadcast to all other participants +// after round1 completes +type Round1Bcast struct { + Verifiers *sharing.FeldmanVerifier + Wi, Ci curves.Scalar +} + +type Round1Result struct { + Broadcast *Round1Bcast + P2P *sharing.ShamirShare +} + +func (result *Round1Result) Encode() ([]byte, error) { + gob.Register(result.Broadcast.Verifiers.Commitments[0]) // just the point for now + gob.Register(result.Broadcast.Ci) + buf := &bytes.Buffer{} + enc := gob.NewEncoder(buf) + if err := enc.Encode(result); err != nil { + return nil, errors.Wrap(err, "couldn't encode round 1 broadcast") + } + return buf.Bytes(), nil +} + +func (result *Round1Result) Decode(input []byte) error { + buf := bytes.NewBuffer(input) + dec := gob.NewDecoder(buf) + if err := dec.Decode(result); err != nil { + return errors.Wrap(err, "couldn't encode round 1 broadcast") + } + return nil +} + +// Round1P2PSend are values that are P2PSend to all other participants +// after round1 completes +type Round1P2PSend = map[uint32]*sharing.ShamirShare + +// Round1 implements dkg round 1 of FROST +func (dp *DkgParticipant) Round1(secret []byte) (*Round1Bcast, Round1P2PSend, error) { + // Make sure dkg participant is not empty + if dp == nil || dp.Curve == nil { + return nil, nil, internal.ErrNilArguments + } + + // Make sure round number is correct + if dp.round != 1 { + return nil, nil, internal.ErrInvalidRound + } + + // Check number of participants + if uint32(len(dp.otherParticipantShares)+1) > dp.feldman.Limit || uint32(len(dp.otherParticipantShares)+1) < dp.feldman.Threshold { + return nil, nil, fmt.Errorf("length of dp.otherParticipantShares + 1 should be equal to feldman limit") + } + + // If secret is nil, sample a new one + // If not, check secret is valid + var s curves.Scalar + var err error + if secret == nil { + s = dp.Curve.Scalar.Random(crand.Reader) + } else { + s, err = dp.Curve.Scalar.SetBytes(secret) + if err != nil { + return nil, nil, err + } + if s.IsZero() { + return nil, nil, internal.ErrZeroValue + } + } + + // Step 1 - (Aj0,...Ajt), (xi1,...,xin) <- FeldmanShare(s) + // We should validate types of Feldman curve scalar and participant's curve scalar. + if reflect.TypeOf(dp.feldman.Curve.Scalar) != reflect.TypeOf(dp.Curve.Scalar) { + return nil, nil, fmt.Errorf("feldman scalar should have the same type as the dkg participant scalar") + } + verifiers, shares, err := dp.feldman.Split(s, crand.Reader) + if err != nil { + return nil, nil, err + } + + // Store Verifiers and shares + dp.verifiers = verifiers + dp.secretShares = shares + + // Step 2 - Sample ki <- Z_q + ki := dp.Curve.Scalar.Random(crand.Reader) + + // Step 3 - Compute Ri = ki*G + Ri := dp.Curve.ScalarBaseMult(ki) + + // Step 4 - Compute Ci = H(i, CTX, g^{a_(i,0)}, R_i), where CTX is fixed context string + var msg []byte + // Append participant id + msg = append(msg, byte(dp.Id)) + // Append CTX + msg = append(msg, dp.ctx) + // Append a_{i,0}*G + msg = append(msg, verifiers.Commitments[0].ToAffineCompressed()...) + // Append Ri + msg = append(msg, Ri.ToAffineCompressed()...) + // Hash the message and get Ci + ci := dp.Curve.Scalar.Hash(msg) + + // Step 5 - Compute Wi = ki+a_{i,0}*c_i mod q. Note that a_{i,0} is the secret. + // Note: We have to compute scalar in the following way when using ed25519 curve, rather than scalar := dp.Scalar.Mul(s, Ci) + // there is an invalid encoding error when we compute scalar as above. + wi := s.MulAdd(ci, ki) + + // Step 6 - Broadcast (Ci, Wi, Ci) to other participants + round1Bcast := &Round1Bcast{ + verifiers, + wi, + ci, + } + + // Step 7 - P2PSend f_i(j) to each participant Pj and keep (i, f_j(i)) for himself + p2pSend := make(Round1P2PSend, len(dp.otherParticipantShares)) + for id := range dp.otherParticipantShares { + p2pSend[id] = shares[id-1] + } + + // Update internal state + dp.round = 2 + + // return + return round1Bcast, p2pSend, nil +} diff --git a/pkg/crypto/dkg/frost/dkg_round2.go b/pkg/crypto/dkg/frost/dkg_round2.go new file mode 100755 index 000000000..16cd6691a --- /dev/null +++ b/pkg/crypto/dkg/frost/dkg_round2.go @@ -0,0 +1,158 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package frost + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" + "github.com/onsonr/sonr/pkg/crypto/sharing" +) + +// Round2Bcast are values that are broadcast to all other participants +// after round2 completes +type Round2Bcast struct { + VerificationKey curves.Point + VkShare curves.Point +} + +// Round2 implements dkg round 2 of FROST +func (dp *DkgParticipant) Round2(bcast map[uint32]*Round1Bcast, p2psend map[uint32]*sharing.ShamirShare) (*Round2Bcast, error) { + // Make sure dkg participant is not empty + if dp == nil || dp.Curve == nil { + return nil, internal.ErrNilArguments + } + + // Check dkg participant has the correct dkg round number + if dp.round != 2 { + return nil, internal.ErrInvalidRound + } + + // Check the input is valid + if bcast == nil || p2psend == nil || len(p2psend) == 0 { + return nil, internal.ErrNilArguments + } + + // Check length of bcast and p2psend + if uint32(len(bcast)) > dp.feldman.Limit || uint32(len(bcast)) < dp.feldman.Threshold-1 { + return nil, fmt.Errorf("invalid broadcast length") + } + + if uint32(len(p2psend)) > dp.feldman.Limit-1 || uint32(len(p2psend)) < dp.feldman.Threshold-1 { + return nil, fmt.Errorf("invalid p2pSend length") + } + + // We should validate Wi and Ci values in Round1Bcast + for id := range bcast { + // ci should be within the range 1 to q-1, q is the group order. + if bcast[id].Ci.IsZero() { + return nil, fmt.Errorf("ci should not be zero from participant %d\n", id) + } + } + // Validate each received commitment is on curve + for id := range bcast { + for _, com := range bcast[id].Verifiers.Commitments { + if !com.IsOnCurve() || com.IsIdentity() { + return nil, fmt.Errorf("some commitment is not on curve from participant %d\n", id) + } + } + } + + var err error + + // Step 2 - for j in 1,...,n + for id := range bcast { + + // Step 3 - if j == i, continue + if id == dp.Id { + continue + } + + // Step 4 - Check equation c_j = H(j, CTX, A_{j,0}, g^{w_j}*A_{j,0}^{-c_j} + // Get Aj0 + Aj0 := bcast[id].Verifiers.Commitments[0] + // Compute g^{w_j} + prod1 := dp.Curve.ScalarBaseMult(bcast[id].Wi) + // Compute A_{j,0}^{-c_j} + prod2 := Aj0.Mul(bcast[id].Ci.Neg()) + + // We need to check Aj0 and prod2 are points on the same curve. + if !Aj0.IsOnCurve() || Aj0.IsIdentity() || !prod2.IsOnCurve() || prod2.IsIdentity() || Aj0.CurveName() != prod2.CurveName() { + return nil, fmt.Errorf("invalid Aj0 or prod2 which is not on the same curve") + } + if prod2 == nil { + return nil, fmt.Errorf("invalid should not be nil") + } + + prod := prod1.Add(prod2) + var msg []byte + // Append participant id + msg = append(msg, byte(id)) + // Append CTX + msg = append(msg, dp.ctx) + // Append Aj0 + msg = append(msg, Aj0.ToAffineCompressed()...) + // Append prod + msg = append(msg, prod.ToAffineCompressed()...) + // Hash the message and get cj + cj := dp.Curve.Scalar.Hash(msg) + // Check equation + if cj.Cmp(bcast[id].Ci) != 0 { + return nil, fmt.Errorf("Hash check fails for participant with id %d\n", id) + } + + // Step 5 - FeldmanVerify + fji := p2psend[id] + if err = bcast[id].Verifiers.Verify(fji); err != nil { + return nil, fmt.Errorf("feldman verify fails for participant with id %d\n", id) + } + } + + sk, err := dp.Curve.Scalar.SetBytes(dp.secretShares[dp.Id-1].Value) + if err != nil { + return nil, err + } + vk := dp.verifiers.Commitments[0] + // Step 6 - Compute signing key share ski = \sum_{j=1}^n xji + for id := range bcast { + if id == dp.Id { + continue + } + t2, err := dp.Curve.Scalar.SetBytes(p2psend[id].Value) + if err != nil { + return nil, err + } + sk = sk.Add(t2) + } + + // Step 8 - Compute verification key vk = sum(A_{j,0}), j = 1,...,n + for id := range bcast { + if id == dp.Id { + continue + } + vk = vk.Add(bcast[id].Verifiers.Commitments[0]) + } + + // Store signing key share + dp.SkShare = sk + + // Step 7 - Compute verification key share vki = ski*G and store + dp.VkShare = dp.Curve.ScalarBaseMult(sk) + + // Store verification key + dp.VerificationKey = vk + + // Update round number + dp.round = 3 + + // Broadcast + return &Round2Bcast{ + vk, + dp.VkShare, + }, nil +} diff --git a/pkg/crypto/dkg/frost/dkg_rounds_test.go b/pkg/crypto/dkg/frost/dkg_rounds_test.go new file mode 100755 index 000000000..2c60514bc --- /dev/null +++ b/pkg/crypto/dkg/frost/dkg_rounds_test.go @@ -0,0 +1,168 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package frost + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/sharing" +) + +var ( + testCurve = curves.ED25519() + Ctx = "string to prevent replay attack" +) + +// Test dkg round1 works for 2 participants +func TestDkgRound1Works(t *testing.T) { + p1, err := NewDkgParticipant(1, 2, Ctx, testCurve, 2) + require.NoError(t, err) + bcast, p2psend, err := p1.Round1(nil) + require.NoError(t, err) + require.NotNil(t, bcast) + require.NotNil(t, p2psend) + require.NotNil(t, p1.ctx) + require.Equal(t, len(p2psend), 1) + require.Equal(t, p1.round, 2) + _, ok := p2psend[2] + require.True(t, ok) +} + +func TestDkgRound1RepeatCall(t *testing.T) { + p1, err := NewDkgParticipant(1, 2, Ctx, testCurve, 2) + require.NoError(t, err) + _, _, err = p1.Round1(nil) + require.NoError(t, err) + _, _, err = p1.Round1(nil) + require.Error(t, err) +} + +func TestDkgRound1BadSecret(t *testing.T) { + p1, err := NewDkgParticipant(1, 2, Ctx, testCurve, 2) + require.NoError(t, err) + // secret == 0 + secret := []byte{0} + _, _, err = p1.Round1(secret) + require.Error(t, err) + // secret too big + secret = []byte{7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7} + _, _, err = p1.Round1(secret) + require.Error(t, err) +} + +func PrepareRound2Input(t *testing.T) (*DkgParticipant, *DkgParticipant, *Round1Bcast, *Round1Bcast, Round1P2PSend, Round1P2PSend) { + // Prepare round 1 output of 2 participants + p1, err := NewDkgParticipant(1, 2, Ctx, testCurve, 2) + require.NoError(t, err) + require.Equal(t, p1.otherParticipantShares[2].Id, uint32(2)) + p2, err := NewDkgParticipant(2, 2, Ctx, testCurve, 1) + require.NoError(t, err) + require.Equal(t, p2.otherParticipantShares[1].Id, uint32(1)) + bcast1, p2psend1, _ := p1.Round1(nil) + bcast2, p2psend2, _ := p2.Round1(nil) + return p1, p2, bcast1, bcast2, p2psend1, p2psend2 +} + +// Test FROST DKG round 2 works +func TestDkgRound2Works(t *testing.T) { + // Prepare Dkg Round1 output + p1, _, bcast1, bcast2, _, p2psend2 := PrepareRound2Input(t) + // Actual Test + require.NotNil(t, bcast1) + require.NotNil(t, bcast2) + require.NotNil(t, p2psend2[1]) + bcast := make(map[uint32]*Round1Bcast) + p2p := make(map[uint32]*sharing.ShamirShare) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p[2] = p2psend2[1] + round2Out, err := p1.Round2(bcast, p2p) + require.NoError(t, err) + require.NotNil(t, round2Out) + require.NotNil(t, p1.SkShare) + require.NotNil(t, p1.VkShare) + require.NotNil(t, p1.VerificationKey) + require.NotNil(t, p1.otherParticipantShares) +} + +// Test FROST DKG round 2 repeat call +func TestDkgRound2RepeatCall(t *testing.T) { + // Prepare round 1 output + p1, _, bcast1, bcast2, _, p2psend2 := PrepareRound2Input(t) + // Actual Test + require.NotNil(t, bcast1) + require.NotNil(t, bcast2) + require.NotNil(t, p2psend2[1]) + bcast := make(map[uint32]*Round1Bcast) + p2p := make(map[uint32]*sharing.ShamirShare) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p[2] = p2psend2[1] + _, err := p1.Round2(bcast, p2p) + require.NoError(t, err) + _, err = p1.Round2(bcast, p2p) + require.Error(t, err) +} + +// Test FROST Dkg Round 2 Bad Input +func TestDkgRound2BadInput(t *testing.T) { + // Prepare Dkg Round 1 output + p1, _, _, _, _, _ := PrepareRound2Input(t) + bcast := make(map[uint32]*Round1Bcast) + p2p := make(map[uint32]*sharing.ShamirShare) + + // Test empty bcast and p2p + _, err := p1.Round2(bcast, p2p) + require.Error(t, err) + + // Test nil bcast and p2p + p1, _, _, _, _, _ = PrepareRound2Input(t) + _, err = p1.Round2(nil, nil) + require.Error(t, err) + + // Test tampered input bcast and p2p + p1, _, bcast1, bcast2, _, p2psend2 := PrepareRound2Input(t) + bcast = make(map[uint32]*Round1Bcast) + p2p = make(map[uint32]*sharing.ShamirShare) + + // Tamper p2psend2 by doubling the value + tmp, _ := testCurve.Scalar.SetBytes(p2psend2[1].Value) + p2psend2[1].Value = tmp.Double().Bytes() + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p[2] = p2psend2[1] + _, err = p1.Round2(bcast, p2p) + require.Error(t, err) +} + +// Test full round works +func TestFullDkgRoundsWorks(t *testing.T) { + // Initiate two participants and running round 1 + p1, p2, bcast1, bcast2, p2psend1, p2psend2 := PrepareRound2Input(t) + bcast := make(map[uint32]*Round1Bcast) + p2p1 := make(map[uint32]*sharing.ShamirShare) + p2p2 := make(map[uint32]*sharing.ShamirShare) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p1[2] = p2psend2[1] + p2p2[1] = p2psend1[2] + + // Running round 2 + round2Out1, _ := p1.Round2(bcast, p2p1) + round2Out2, _ := p2.Round2(bcast, p2p2) + require.Equal(t, round2Out1.VerificationKey, round2Out2.VerificationKey) + s, _ := sharing.NewShamir(2, 2, testCurve) + sk, err := s.Combine(&sharing.ShamirShare{Id: p1.Id, Value: p1.SkShare.Bytes()}, + &sharing.ShamirShare{Id: p2.Id, Value: p2.SkShare.Bytes()}) + require.NoError(t, err) + + vk := testCurve.ScalarBaseMult(sk) + require.True(t, vk.Equal(p1.VerificationKey)) +} diff --git a/pkg/crypto/dkg/frost/participant.go b/pkg/crypto/dkg/frost/participant.go new file mode 100755 index 000000000..5742059cd --- /dev/null +++ b/pkg/crypto/dkg/frost/participant.go @@ -0,0 +1,65 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package frost is an implementation of the DKG part of https://eprint.iacr.org/2020/852.pdf +package frost + +import ( + "strconv" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" + "github.com/onsonr/sonr/pkg/crypto/sharing" +) + +type DkgParticipant struct { + round int + Curve *curves.Curve + otherParticipantShares map[uint32]*dkgParticipantData + Id uint32 + SkShare curves.Scalar + VerificationKey curves.Point + VkShare curves.Point + feldman *sharing.Feldman + verifiers *sharing.FeldmanVerifier + secretShares []*sharing.ShamirShare + ctx byte +} + +type dkgParticipantData struct { + Id uint32 + Share *sharing.ShamirShare + Verifiers *sharing.FeldmanVerifier +} + +func NewDkgParticipant(id, threshold uint32, ctx string, curve *curves.Curve, otherParticipants ...uint32) (*DkgParticipant, error) { + if curve == nil || len(otherParticipants) == 0 { + return nil, internal.ErrNilArguments + } + limit := uint32(len(otherParticipants)) + 1 + feldman, err := sharing.NewFeldman(threshold, limit, curve) + if err != nil { + return nil, err + } + otherParticipantShares := make(map[uint32]*dkgParticipantData, len(otherParticipants)) + for _, id := range otherParticipants { + otherParticipantShares[id] = &dkgParticipantData{ + Id: id, + } + } + + // SetBigInt the common fixed string + ctxV, _ := strconv.Atoi(ctx) + + return &DkgParticipant{ + Id: id, + round: 1, + Curve: curve, + feldman: feldman, + otherParticipantShares: otherParticipantShares, + ctx: byte(ctxV), + }, nil +} diff --git a/pkg/crypto/dkg/gennaro/README.md b/pkg/crypto/dkg/gennaro/README.md new file mode 100755 index 000000000..0bc82ea79 --- /dev/null +++ b/pkg/crypto/dkg/gennaro/README.md @@ -0,0 +1,13 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## One Round Threshold ECDSA with Identifiable Abort (GG20) + +This package is an implementation of the DKG part of +[One Round Threshold ECDSA with Identifiable Abort](https://eprint.iacr.org/2020/540.pdf). diff --git a/pkg/crypto/dkg/gennaro/participant.go b/pkg/crypto/dkg/gennaro/participant.go new file mode 100755 index 000000000..04c1848c5 --- /dev/null +++ b/pkg/crypto/dkg/gennaro/participant.go @@ -0,0 +1,97 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package gennaro is an implementation of the DKG part of https://eprint.iacr.org/2020/540.pdf +package gennaro + +import ( + "crypto/elliptic" + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +// Participant is a DKG player that contains information needed to perform DKG rounds +// and yield a secret key share and public key when finished +type Participant struct { + round int + curve elliptic.Curve + scalar curves.EcScalar + otherParticipantShares map[uint32]*dkgParticipantData + id uint32 + skShare *curves.Element + verificationKey *v1.ShareVerifier + feldman *v1.Feldman + pedersen *v1.Pedersen + pedersenResult *v1.PedersenResult +} + +// NewParticipant creates a participant ready to perform a DKG +// `id` is the integer value identifier for this participant +// `threshold` is the minimum bound for the secret sharing scheme +// `generator` is the blinding factor generator used by pedersen's verifiable secret sharing +// `otherParticipants` is the integer value identifiers for the other participants +// `id` and `otherParticipants` must be the set of integers 1,2,....,n +func NewParticipant(id, threshold uint32, generator *curves.EcPoint, scalar curves.EcScalar, otherParticipants ...uint32) (*Participant, error) { + if generator == nil || len(otherParticipants) == 0 { + return nil, internal.ErrNilArguments + } + err := validIds(append(otherParticipants, id)) + if err != nil { + return nil, err + } + + limit := uint32(len(otherParticipants)) + 1 + feldman, err := v1.NewFeldman(threshold, limit, generator.Curve) + if err != nil { + return nil, err + } + pedersen, err := v1.NewPedersen(threshold, limit, generator) + if err != nil { + return nil, err + } + + otherParticipantShares := make(map[uint32]*dkgParticipantData, len(otherParticipants)) + for _, id := range otherParticipants { + otherParticipantShares[id] = &dkgParticipantData{ + Id: id, + } + } + + return &Participant{ + id: id, + round: 1, + curve: generator.Curve, + scalar: scalar, + feldman: feldman, + pedersen: pedersen, + otherParticipantShares: otherParticipantShares, + }, nil +} + +// Determines if the SSIDs are exactly the values 1..n. +func validIds(ids []uint32) error { + // Index + idMap := make(map[uint32]bool, len(ids)) + for _, id := range ids { + idMap[id] = true + } + // Check + for i := 1; i <= len(ids); i++ { + if ok := idMap[uint32(i)]; !ok { + return fmt.Errorf("the ID list %v is invalid. Values must be 1,2,..,n.", ids) + } + } + return nil +} + +type dkgParticipantData struct { + Id uint32 + Share *v1.ShamirShare + Verifiers []*v1.ShareVerifier +} diff --git a/pkg/crypto/dkg/gennaro/participant_test.go b/pkg/crypto/dkg/gennaro/participant_test.go new file mode 100755 index 000000000..715cd7476 --- /dev/null +++ b/pkg/crypto/dkg/gennaro/participant_test.go @@ -0,0 +1,48 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package gennaro + +import ( + "math/big" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var testGenerator, _ = curves.NewScalarBaseMult(btcec.S256(), big.NewInt(3333)) + +func TestNewParticipantWorks(t *testing.T) { + p, err := NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 2) + require.NoError(t, err) + require.NotNil(t, p) + require.Equal(t, p.id, uint32(1)) + require.Equal(t, p.round, 1) + require.Equal(t, p.curve, btcec.S256()) + require.NotNil(t, p.pedersen) + require.NotNil(t, p.feldman) + require.Nil(t, p.pedersenResult) + require.NotNil(t, p.otherParticipantShares) + require.NotNil(t, p.scalar) + _, ok := p.otherParticipantShares[2] + require.True(t, ok) +} + +func TestNewParticipantBadInputs(t *testing.T) { + _, err := NewParticipant(0, 0, nil, nil) + require.Error(t, err) + require.Equal(t, err, internal.ErrNilArguments) + _, err = NewParticipant(1, 2, nil, nil) + require.Error(t, err) + require.Equal(t, err, internal.ErrNilArguments) + _, err = NewParticipant(1, 2, testGenerator, nil) + require.Error(t, err) + require.Equal(t, err, internal.ErrNilArguments) +} diff --git a/pkg/crypto/dkg/gennaro/round1.go b/pkg/crypto/dkg/gennaro/round1.go new file mode 100755 index 000000000..1a8ad140e --- /dev/null +++ b/pkg/crypto/dkg/gennaro/round1.go @@ -0,0 +1,79 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package gennaro + +import ( + "fmt" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/core" + "github.com/onsonr/sonr/pkg/crypto/internal" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +// Round1Bcast are the values that are broadcast to all other participants +// after round1 completes +type Round1Bcast = []*v1.ShareVerifier + +// Round1P2PSend are the values that are sent to individual participants based +// on the id +type Round1P2PSend = map[uint32]*Round1P2PSendPacket + +// Round1P2PSendPacket are the shares generated from the secret for a specific participant +type Round1P2PSendPacket struct { + SecretShare *v1.ShamirShare + BlindingShare *v1.ShamirShare +} + +// Round1 computes the first round for the DKG +// `secret` can be nil +// NOTE: if `secret` is nil, a new secret is generated which creates a new key +// if `secret` is set, then this performs key resharing aka proactive secret sharing update +func (dp *Participant) Round1(secret []byte) (Round1Bcast, Round1P2PSend, error) { + if dp.round != 1 { + return nil, nil, internal.ErrInvalidRound + } + + if secret == nil { + // 1. x $← Zq∗ + s, err := dp.scalar.Random() + if err != nil { + return nil, nil, err + } + secret = s.Bytes() + } else { + s := new(big.Int).SetBytes(secret) + if !dp.scalar.IsValid(s) { + return nil, nil, fmt.Errorf("invalid secret value") + } + if s.Cmp(core.Zero) == 0 { + return nil, nil, internal.ErrZeroValue + } + } + + var err error + // 2. {X1,...,Xt},{R1,...,Rt},{x1,...,xn},{r1,...,rn}= PedersenFeldmanShare(E,Q,x,t,{p1,...,pn}) + dp.pedersenResult, err = dp.pedersen.Split(secret) + if err != nil { + return nil, nil, err + } + + // 4. P2PSend x_j,r_j to participant p_j in {p_1,...,p_n}_{i != j} + p2pSend := make(Round1P2PSend, len(dp.otherParticipantShares)) + for id := range dp.otherParticipantShares { + p2pSend[id] = &Round1P2PSendPacket{ + SecretShare: dp.pedersenResult.SecretShares[id-1], + BlindingShare: dp.pedersenResult.BlindingShares[id-1], + } + } + + // Update internal state + dp.round = 2 + + // 3. EchoBroadcast {X_1,...,X_t} to all other participants. + return dp.pedersenResult.BlindedVerifiers, p2pSend, nil +} diff --git a/pkg/crypto/dkg/gennaro/round2.go b/pkg/crypto/dkg/gennaro/round2.go new file mode 100755 index 000000000..422272791 --- /dev/null +++ b/pkg/crypto/dkg/gennaro/round2.go @@ -0,0 +1,90 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package gennaro + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/internal" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +type Round2Bcast = []*v1.ShareVerifier + +// Round2 computes the second round for Gennaro DKG +// Algorithm 3 - Gennaro DKG Round 2 +// bcast contains all Round1 broadcast from other participants to this participant +// p2p contains all Round1 P2P send message from other participants to this participant +func (dp *Participant) Round2(bcast map[uint32]Round1Bcast, p2p map[uint32]*Round1P2PSendPacket) (Round2Bcast, error) { + // Check participant is not empty + if dp == nil || dp.curve == nil { + return nil, internal.ErrNilArguments + } + + // Check participant has the correct dkg round number + if dp.round != 2 { + return nil, internal.ErrInvalidRound + } + + // Check the input is valid + if bcast == nil || p2p == nil || len(bcast) == 0 || len(p2p) == 0 { + return nil, internal.ErrNilArguments + } + + // 1. set sk = x_{ii} + sk := dp.pedersenResult.SecretShares[dp.id-1].Value + + // 2. for j in 1,...,n + for id := range bcast { + + // 3. if i = j continue + if id == dp.id { + continue + } + + // Ensure a valid p2p entry exists + if p2p[id] == nil { + return nil, fmt.Errorf("missing p2p packet for id=%v", id) + } + + // 4. If PedersenVerify(E, Q, x_ji, r_ji, {X_ji,...,X_jt}) = false, abort + xji := p2p[id].SecretShare + rji := p2p[id].BlindingShare + bvs := bcast[id] + if ok, err := dp.pedersen.Verify(xji, rji, bvs); !ok { + if err != nil { + return nil, err + } else { + return nil, fmt.Errorf("invalid share for participant id=%v", id) + } + } + + // Store other participants' shares xji for usage in round 3 + dp.otherParticipantShares[id].Share = p2p[id].SecretShare + + // 5. sk = (sk+xji) mod q + // NOTE: we use the EcScalar class to add instead of + // just using big.Int Add and Mod + // because Ed25519 will fail with the big.Int Add and Mod + // and Ed25519 uses different little endian vs big endian + // in big.Int + t1 := sk.BigInt() + t2 := xji.Value.BigInt() + r := dp.scalar.Add(t1, t2) + + sk = sk.Field().NewElement(r) + } + + // Update internal state + dp.round = 3 + + // 7. Store ski as participant i's secret key share + dp.skShare = sk + + // 6. EchoBroadcast {R_1,...,R_t} to all other participants. + return dp.pedersenResult.Verifiers, nil +} diff --git a/pkg/crypto/dkg/gennaro/round3.go b/pkg/crypto/dkg/gennaro/round3.go new file mode 100755 index 000000000..b6321989e --- /dev/null +++ b/pkg/crypto/dkg/gennaro/round3.go @@ -0,0 +1,89 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package gennaro + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/internal" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +// Round3Bcast contains values that will be broadcast to other participants. +type Round3Bcast = v1.ShareVerifier + +// Round3 computes the third round for Gennaro DKG +// Algorithm 4 - Gennaro DKG Round 3 +// bcast contains all Round2 broadcast from other participants to this participant. +func (dp *Participant) Round3(bcast map[uint32]Round2Bcast) (*Round3Bcast, *v1.ShamirShare, error) { + // Check participant is not empty + if dp == nil || dp.curve == nil { + return nil, nil, internal.ErrNilArguments + } + + // Check participant has the correct dkg round number + if dp.round != 3 { + return nil, nil, internal.ErrInvalidRound + } + + // Check the input is valid + if len(bcast) == 0 { + return nil, nil, internal.ErrNilArguments + } + + // 1. SetBigInt Pk = R_i1 + Pk := dp.pedersenResult.Verifiers[0] + + // 2. for j in 1,...,n + for id := range bcast { + // 3. if i = j continue + if id == dp.id { + continue + } + + // 4. If FeldmanVerify(E, xji, {R_j1,...,R_jt}) = false; abort + xji := dp.otherParticipantShares[id].Share + vs := bcast[id] + if ok, err := dp.feldman.Verify(xji, vs); !ok { + if err != nil { + return nil, nil, err + } else { + return nil, nil, fmt.Errorf("invalid share for participant #{id}") + } + } + + // Store the feldman verifiers for round 4 + dp.otherParticipantShares[id].Verifiers = vs + + // 5. Pk = Pk+R_j1 + temp, err := Pk.Add(bcast[id][0]) + if err != nil { + return nil, nil, fmt.Errorf("error in computing Pk+R_j1") + } //nolint:errcheck + Pk = temp + } + + // This is a sanity check to make sure nothing went wrong + // when computing the public key + if !Pk.IsOnCurve() || Pk.IsIdentity() { + return nil, nil, fmt.Errorf("invalid public key") + } + + // 6. Store Pk as the public verification key + dp.verificationKey = Pk + + // Update internal state + dp.round = 4 + + skShare := v1.ShamirShare{ + Identifier: dp.id, + Value: dp.skShare, + } + + // Output Pk as the public verification key + return Pk, &skShare, nil +} diff --git a/pkg/crypto/dkg/gennaro/round4.go b/pkg/crypto/dkg/gennaro/round4.go new file mode 100755 index 000000000..9cd7c201e --- /dev/null +++ b/pkg/crypto/dkg/gennaro/round4.go @@ -0,0 +1,76 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package gennaro + +import ( + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/core" + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +// Round4 computes the public shares used by tECDSA during signing +// that are converted to additive shares once the signing participants +// are known. This function is idempotent +func (dp *Participant) Round4() (map[uint32]*curves.EcPoint, error) { + // Check participant is not empty + if dp == nil || dp.curve == nil { + return nil, internal.ErrNilArguments + } + + // Check participant has the correct dkg round number + if dp.round != 4 { + return nil, internal.ErrInvalidRound + } + + n := len(dp.otherParticipantShares) + 1 //+1 to include self + // Wj's + publicShares := make(map[uint32]*curves.EcPoint, n) + + // 1. R = {{R1,...,Rt},{Rij,...,Rit}i!=j} + r := make(map[uint32][]*v1.ShareVerifier, n) + r[dp.id] = dp.pedersenResult.Verifiers + for j := range dp.otherParticipantShares { + r[j] = dp.otherParticipantShares[j].Verifiers + } + + // 2. for j in 1,...,n + for j, v := range r { + // 3. Wj = Pk + publicShares[j] = &curves.EcPoint{ + Curve: dp.verificationKey.Curve, + X: new(big.Int).Set(dp.verificationKey.X), + Y: new(big.Int).Set(dp.verificationKey.Y), + } + + // 4. for k in 1,...,t + for k := 0; k < len(dp.pedersenResult.Verifiers); k++ { + // 5. ck = pj * k mod q + pj := big.NewInt(int64(j)) + ck, err := core.Mul(pj, big.NewInt(int64(k+1)), dp.curve.Params().N) + if err != nil { + return nil, err + } + + // 6a. t = ck * Rj + t, err := v[k].ScalarMult(ck) + if err != nil { + return nil, err + } + + // 6b. Wj = Wj + t + publicShares[j], err = publicShares[j].Add(t) + if err != nil { + return nil, err + } + } + } + + return publicShares, nil +} diff --git a/pkg/crypto/dkg/gennaro/rounds_test.go b/pkg/crypto/dkg/gennaro/rounds_test.go new file mode 100755 index 000000000..f756a9642 --- /dev/null +++ b/pkg/crypto/dkg/gennaro/rounds_test.go @@ -0,0 +1,381 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package gennaro + +import ( + "fmt" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +func TestParticipantRound1Works(t *testing.T) { + p1, err := NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 2) + require.NoError(t, err) + bcast, p2psend, err := p1.Round1(nil) + require.NoError(t, err) + require.NotNil(t, bcast) + require.NotNil(t, p2psend) + require.Equal(t, len(p2psend), 1) + require.Equal(t, len(bcast), 2) + require.NotNil(t, p1.pedersenResult) + require.Equal(t, p1.round, 2) + _, ok := p2psend[2] + require.True(t, ok) +} + +func TestParticipantRound1RepeatCall(t *testing.T) { + p1, err := NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 2) + require.NoError(t, err) + _, _, err = p1.Round1(nil) + require.NoError(t, err) + _, _, err = p1.Round1(nil) + require.Error(t, err) +} + +func TestParticipantRound1BadSecret(t *testing.T) { + p1, err := NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 2) + require.NoError(t, err) + // secret == 0 + secret := []byte{0} + _, _, err = p1.Round1(secret) + require.Error(t, err) + // secret too big + secret = []byte{7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7} + _, _, err = p1.Round1(secret) + require.Error(t, err) +} + +func PrepareRound2Input(t *testing.T) (*Participant, *Participant, Round1Bcast, Round1Bcast, Round1P2PSend) { + // Prepare round 1 output of 2 participants + p1, err := NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 2) + require.NoError(t, err) + require.Equal(t, p1.otherParticipantShares[2].Id, uint32(2)) + p2, err := NewParticipant(2, 2, testGenerator, curves.NewK256Scalar(), 1) + require.NoError(t, err) + require.Equal(t, p2.otherParticipantShares[1].Id, uint32(1)) + bcast1, _, _ := p1.Round1(nil) + bcast2, p2psend2, _ := p2.Round1(nil) + return p1, p2, bcast1, bcast2, p2psend2 +} + +// Test Gennaro DKG round2 works +func TestParticipantRound2Works(t *testing.T) { + // Prepare Dkg Round 1 output + p1, _, bcast1, bcast2, p2psend2 := PrepareRound2Input(t) + // Actual Test + require.NotNil(t, bcast1) + require.NotNil(t, bcast2) + require.NotNil(t, p2psend2[1]) + bcast := make(map[uint32]Round1Bcast) + p2p := make(map[uint32]*Round1P2PSendPacket) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p[2] = p2psend2[1] + round2Out, err := p1.Round2(bcast, p2p) + require.NoError(t, err) + require.NotNil(t, round2Out) + require.Equal(t, len(round2Out), 2) + require.NotNil(t, p1.skShare) + require.Equal(t, p1.round, 3) + require.NotNil(t, p1.otherParticipantShares) +} + +// Test Gennaro DKG round 2 repeat call +func TestParticipantRound2RepeatCall(t *testing.T) { + // Prepare Dkg Round 1 output + p1, _, bcast1, bcast2, p2psend2 := PrepareRound2Input(t) + // Actual Test + require.NotNil(t, bcast1) + require.NotNil(t, bcast2) + require.NotNil(t, p2psend2[1]) + bcast := make(map[uint32]Round1Bcast) + p2p := make(map[uint32]*Round1P2PSendPacket) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p[2] = p2psend2[1] + _, err := p1.Round2(bcast, p2p) + require.NoError(t, err) + _, err = p1.Round2(bcast, p2p) + require.Error(t, err) +} + +// Test Gennaro Dkg Round 2 Bad Input +func TestParticipantRound2BadInput(t *testing.T) { + // Prepare Dkg Round 1 output + p1, _, _, _, _ := PrepareRound2Input(t) + bcast := make(map[uint32]Round1Bcast) + p2p := make(map[uint32]*Round1P2PSendPacket) + + // Test empty bcast and p2p + _, err := p1.Round2(bcast, p2p) + require.Error(t, err) + + // Test nil bcast and p2p + p1, _, _, _, _ = PrepareRound2Input(t) + _, err = p1.Round2(nil, nil) + require.Error(t, err) + + // Test tampered input bcast and p2p + p1, _, bcast1, bcast2, p2psend2 := PrepareRound2Input(t) + bcast = make(map[uint32]Round1Bcast) + p2p = make(map[uint32]*Round1P2PSendPacket) + + // Tamper bcast1 and p2psend2 by doubling their value + bcast1[1].Y = bcast1[1].Y.Add(bcast1[1].Y, bcast1[1].Y) + p2psend2[1].SecretShare.Value = p2psend2[1].SecretShare.Value.Add(p2psend2[1].SecretShare.Value) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p[2] = p2psend2[1] + _, err = p1.Round2(bcast, p2p) + require.Error(t, err) +} + +func PrepareRound3Input(t *testing.T) (*Participant, *Participant, map[uint32]Round2Bcast) { + p1, _ := NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 2) + p2, _ := NewParticipant(2, 2, testGenerator, curves.NewK256Scalar(), 1) + bcast1, p2psend1, _ := p1.Round1(nil) + bcast2, p2psend2, _ := p2.Round1(nil) + bcast := make(map[uint32]Round1Bcast) + p2p1 := make(map[uint32]*Round1P2PSendPacket) + p2p2 := make(map[uint32]*Round1P2PSendPacket) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p1[2] = p2psend2[1] + p2p2[1] = p2psend1[2] + round2Out1, _ := p1.Round2(bcast, p2p1) + round2Out2, _ := p2.Round2(bcast, p2p2) + round3Input := make(map[uint32]Round2Bcast) + round3Input[1] = round2Out1 + round3Input[2] = round2Out2 + return p1, p2, round3Input +} + +// Test Gennaro Dkg Round 3 Works +func TestParticipantRound3Works(t *testing.T) { + // Prepare Gennaro Dkg Round 3 Input + p1, p2, round3Input := PrepareRound3Input(t) + + // Actual Test + round3Out1, _, err := p1.Round3(round3Input) + require.NoError(t, err) + require.NotNil(t, round3Out1) + round3Out2, _, err := p2.Round3(round3Input) + require.NoError(t, err) + require.NotNil(t, round3Out2) + require.Equal(t, p1.round, 4) + require.Equal(t, p2.round, 4) + require.Equal(t, p1.verificationKey, p2.verificationKey) + + // Test if shares recombine properly + s, _ := v1.NewShamir(2, 2, curves.NewField(btcec.S256().N)) + sk, err := s.Combine(&v1.ShamirShare{Identifier: p1.id, Value: p1.skShare}, + &v1.ShamirShare{Identifier: p2.id, Value: p2.skShare}) + require.NoError(t, err) + + // Test verification keys are G * sk + x, y := btcec.S256().ScalarBaseMult(sk) + tmp := &curves.EcPoint{ + Curve: btcec.S256(), + X: x, + Y: y, + } + require.True(t, tmp.Equals(p1.verificationKey)) + require.True(t, tmp.Equals(p2.verificationKey)) +} + +// Test Gennaro Dkg Round3 Repeat Call +func TestParticipantRound3RepeatCall(t *testing.T) { + // Prepare Round 3 Input + p1, _, round3Input := PrepareRound3Input(t) + + // Actual Test + _, _, err := p1.Round3(round3Input) + require.NoError(t, err) + _, _, err = p1.Round3(round3Input) + require.Error(t, err) +} + +// Test Gennaro DKG Round 3 Bad Input +func TestParticipantRound3BadInput(t *testing.T) { + // Test empty round 3 input + p1, _, _ := PrepareRound3Input(t) + emptyInput := make(map[uint32]Round2Bcast) + _, _, err := p1.Round3(emptyInput) + require.Error(t, err) + + // Test nil round 3 input + p1, _, _ = PrepareRound3Input(t) + _, _, err = p1.Round3(nil) + require.Error(t, err) + + // Test tampered round 3 input + p1, _, round3Input := PrepareRound3Input(t) + // Tamper participant2's broadcast + round3Input[2][0], _ = round3Input[2][0].Add(round3Input[2][1]) + _, _, err = p1.Round3(round3Input) + require.Error(t, err) +} + +// Test Gennaro Dkg Round 4 Works +func TestParticipantRound4Works(t *testing.T) { + // Prepare Gennaro Dkg Round 3 Input + p1, p2, round3Input := PrepareRound3Input(t) + round3Out1, _, err := p1.Round3(round3Input) + require.NoError(t, err) + require.NotNil(t, round3Out1) + round3Out2, _, err := p2.Round3(round3Input) + require.NoError(t, err) + require.NotNil(t, round3Out2) + + // Actual test + publicShares1, err := p1.Round4() + require.NoError(t, err) + require.NotNil(t, publicShares1) + publicShares2, err := p2.Round4() + require.NoError(t, err) + require.NotNil(t, publicShares2) + + require.Equal(t, publicShares1, publicShares2) +} + +// Test Gennaro Dkg Round 4 Works +func TestParticipantRound4RepeatCall(t *testing.T) { + // Prepare Gennaro Dkg Round 3 Input + p1, p2, round3Input := PrepareRound3Input(t) + round3Out1, _, err := p1.Round3(round3Input) + require.NoError(t, err) + require.NotNil(t, round3Out1) + round3Out2, _, err := p2.Round3(round3Input) + require.NoError(t, err) + require.NotNil(t, round3Out2) + + // Actual test + publicShares1, err := p1.Round4() + require.NoError(t, err) + require.NotNil(t, publicShares1) + publicShares2, err := p1.Round4() + require.NoError(t, err) + require.NotNil(t, publicShares2) + + require.Equal(t, publicShares1, publicShares2) +} + +// Test all Gennaro DKG rounds +func TestAllGennaroDkgRounds(t *testing.T) { + // Initiate two participants + p1, _ := NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 2) + p2, _ := NewParticipant(2, 2, testGenerator, curves.NewK256Scalar(), 1) + + // Running round 1 + bcast1, p2psend1, _ := p1.Round1(nil) + bcast2, p2psend2, _ := p2.Round1(nil) + bcast := make(map[uint32]Round1Bcast) + p2p1 := make(map[uint32]*Round1P2PSendPacket) + p2p2 := make(map[uint32]*Round1P2PSendPacket) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p1[2] = p2psend2[1] + p2p2[1] = p2psend1[2] + + // Running round 2 + round2Out1, _ := p1.Round2(bcast, p2p1) + round2Out2, _ := p2.Round2(bcast, p2p2) + round3Input := make(map[uint32]Round2Bcast) + round3Input[1] = round2Out1 + round3Input[2] = round2Out2 + + // Running round 3 + round3Out1, _, _ := p1.Round3(round3Input) + round3Out2, _, _ := p2.Round3(round3Input) + require.NotNil(t, round3Out1) + require.NotNil(t, round3Out2) + + // Running round 4 + publicShares1, _ := p1.Round4() + publicShares2, _ := p2.Round4() + + // Test output of all rounds + require.Equal(t, publicShares1, publicShares2) + s, _ := v1.NewShamir(2, 2, curves.NewField(btcec.S256().N)) + sk, err := s.Combine(&v1.ShamirShare{Identifier: p1.id, Value: p1.skShare}, + &v1.ShamirShare{Identifier: p2.id, Value: p2.skShare}) + require.NoError(t, err) + + x, y := btcec.S256().ScalarBaseMult(sk) + tmp := &curves.EcPoint{ + Curve: btcec.S256(), + X: x, + Y: y, + } + require.True(t, tmp.Equals(p1.verificationKey)) + require.True(t, tmp.Equals(p2.verificationKey)) +} + +// Ensure correct functioning when input is missing +func TestParticipant2BadInput(t *testing.T) { + // + // Setup + // + p1, _ := NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 2) + p2, _ := NewParticipant(2, 2, testGenerator, curves.NewK256Scalar(), 1) + bcast1, _, _ := p1.Round1(nil) + bcast2, p2psend2, _ := p2.Round1(nil) + bcast := make(map[uint32]Round1Bcast) + p2p1 := make(map[uint32]*Round1P2PSendPacket) + bcast[1] = bcast1 + bcast[2] = bcast2 + // Exclude p2p 2>1 + p2p1[4] = p2psend2[1] + + // Run round 2 + _, err := p1.Round2(bcast, p2p1) + require.Error(t, err) +} + +func TestValidIDs(t *testing.T) { + err := fmt.Errorf("") + tests := []struct { + name string + in []uint32 + expected error + }{ + {"positive-1,2", []uint32{1, 2}, nil}, + {"positive-2,1", []uint32{2, 1}, nil}, + {"positive-1-10", []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, nil}, + {"positive-1-10-random", []uint32{10, 9, 6, 5, 3, 2, 8, 7, 1, 4}, nil}, + {"negative-1,3", []uint32{1, 3}, err}, + {"negative-1-10-missing-5", []uint32{10, 9, 6, 3, 2, 8, 7, 1, 4}, err}, + } + // Run all the tests! + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := validIds(test.in) + if test.expected == nil { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } +} + +// Test newParticipant with arbitrary IDs +func TestParticipantArbitraryIds(t *testing.T) { + _, err := NewParticipant(3, 2, testGenerator, curves.NewK256Scalar(), 4) + require.Error(t, err) + _, err = NewParticipant(0, 2, testGenerator, curves.NewK256Scalar(), 1) + require.Error(t, err) + _, err = NewParticipant(2, 2, testGenerator, curves.NewK256Scalar(), 2, 3, 5) + require.Error(t, err) + _, err = NewParticipant(1, 2, testGenerator, curves.NewK256Scalar(), 4) + require.Error(t, err) +} diff --git a/pkg/crypto/dkg/gennaro2p/README.md b/pkg/crypto/dkg/gennaro2p/README.md new file mode 100755 index 000000000..365265760 --- /dev/null +++ b/pkg/crypto/dkg/gennaro2p/README.md @@ -0,0 +1,12 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## Two-party GG20 + +This package wraps dkg/genarro and specializes it for the 2-party case. diff --git a/pkg/crypto/dkg/gennaro2p/genarro2p.go b/pkg/crypto/dkg/gennaro2p/genarro2p.go new file mode 100755 index 000000000..11fcff5da --- /dev/null +++ b/pkg/crypto/dkg/gennaro2p/genarro2p.go @@ -0,0 +1,151 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package gennaro2p wraps dkg/genarro and specializes it for the 2-party case. Simpler API, no +// distinction between broadcast and peer messages, and only counterparty messages are +// used as round inputs since self-inputs are always ignored. +package gennaro2p + +import ( + "crypto/elliptic" + "fmt" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/dkg/gennaro" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +const threshold = 2 + +// Participant is a DKG player that contains information needed to perform DKG rounds +// and yield a secret key share and public key when finished +type Participant struct { + id uint32 + counterPartyId uint32 + embedded *gennaro.Participant + blind *curves.EcPoint +} + +type Round1Message struct { + Verifiers []*v1.ShareVerifier + SecretShare *v1.ShamirShare + BlindingShare *v1.ShamirShare + Blind *curves.EcPoint +} + +type Round2Message struct { + Verifiers []*v1.ShareVerifier +} + +type DkgResult struct { + PublicKey *curves.EcPoint + SecretShare *v1.ShamirShare + PublicShares map[uint32]*curves.EcPoint +} + +// NewParticipant creates a participant ready to perform a DKG +// blind must be a generator and must be synchronized between counterparties. +// The first participant can set it to `nil` and a secure blinding factor will be +// generated. +func NewParticipant(id, counterPartyId uint32, blind *curves.EcPoint, + scalar curves.EcScalar, curve elliptic.Curve, +) (*Participant, error) { + // Generate blinding value, if required + var err error + if blind == nil { + blind, err = newBlind(scalar, curve) + if err != nil { + return nil, errors.Wrap(err, "generating fresh blinding generator") + } + } + p, err := gennaro.NewParticipant(id, threshold, blind, scalar, counterPartyId) + if err != nil { + return nil, errors.Wrap(err, "created genarro.Participant") + } + return &Participant{id, counterPartyId, p, blind}, nil +} + +// Creates a random blinding factor (as a generator) required for pedersen's VSS +func newBlind(curveScalar curves.EcScalar, curve elliptic.Curve) (*curves.EcPoint, error) { + rScalar, err := curveScalar.Random() + if err != nil { + return nil, errors.Wrap(err, "generating blinding scalar") + } + return curves.NewScalarBaseMult(curve, rScalar) +} + +// Runs DKG round 1. If `secret` is nil, shares of a new, random signing key are generated. +// Otherwise, the existing secret shares will be refreshed but the privkey and pubkey +// will remain unchanged. +func (p *Participant) Round1(secret []byte) (*Round1Message, error) { + // Run round 1 + bcast, p2p, err := p.embedded.Round1(secret) + if err != nil { + return nil, errors.Wrap(err, "calling embedded.Round1()") + } + + // Ensure the map has the expected entry so there's no SIGSEGV when we + // repackage it + if p2p[p.counterPartyId] == nil { + return nil, fmt.Errorf("round1 response for p2p[%v] is nil", p.counterPartyId) + } + + // Package response + return &Round1Message{ + bcast, + p2p[p.counterPartyId].SecretShare, + p2p[p.counterPartyId].BlindingShare, + p.blind, + }, nil +} + +// Runs DKG round 2 using the counterparty's output from round 1. +func (p *Participant) Round2(msg *Round1Message) (*Round2Message, error) { + // Run round 2 + bcast, err := p.embedded.Round2( + map[uint32]gennaro.Round1Bcast{ + p.counterPartyId: msg.Verifiers, + }, + map[uint32]*gennaro.Round1P2PSendPacket{ + p.counterPartyId: { + SecretShare: msg.SecretShare, + BlindingShare: msg.BlindingShare, + }, + }) + if err != nil { + return nil, errors.Wrap(err, "calling embedded.Round2()") + } + + // Package response + return &Round2Message{bcast}, nil +} + +// Completes the DKG using the counterparty's output from round 2. +func (p *Participant) Finalize(msg *Round2Message) (*DkgResult, error) { + // Run round 3 + pk, share, err := p.embedded.Round3( + map[uint32]gennaro.Round2Bcast{ + p.counterPartyId: msg.Verifiers, + }) + if err != nil { + return nil, errors.Wrap(err, "calling embedded.Round3()") + } + + // Compute public shares + pubShares, err := p.embedded.Round4() + if err != nil { + return nil, errors.Wrap(err, "calling embedded.Roun4()") + } + + // Package response + return &DkgResult{ + PublicKey: pk, + SecretShare: share, + PublicShares: pubShares, + }, nil +} diff --git a/pkg/crypto/dkg/gennaro2p/genarro2p_test.go b/pkg/crypto/dkg/gennaro2p/genarro2p_test.go new file mode 100755 index 000000000..9826f5153 --- /dev/null +++ b/pkg/crypto/dkg/gennaro2p/genarro2p_test.go @@ -0,0 +1,181 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package gennaro2p + +import ( + "crypto/elliptic" + "fmt" + "reflect" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +var ( + curveScalar = curves.NewK256Scalar() + curve = btcec.S256() +) + +const ( + clientId = 1 + serverId = 2 +) + +// Benchmark full DKG including blind selection and setup +func BenchmarkDkg(b *testing.B) { + if testing.Short() { + b.Skip("skipping test in short mode.") + } + + for i := 0; i < b.N; i++ { + _, _, err := dkg() + require.NoError(b, err) + } +} + +// Run a DKG and reports the client/server results +func dkg() (*DkgResult, *DkgResult, error) { + // Create client/server + blind, _ := newBlind(curveScalar, curve) + + client, err := NewParticipant(clientId, serverId, blind, curveScalar, curve) + if err != nil { + return nil, nil, err + } + + server, err := NewParticipant(serverId, clientId, blind, curveScalar, curve) + if err != nil { + return nil, nil, err + } + + // R1 + clientR1, err := client.Round1(nil) + if err != nil { + return nil, nil, err + } + + serverR1, err := server.Round1(nil) + if err != nil { + return nil, nil, err + } + + // R2 + clientR2, err := client.Round2(serverR1) + if err != nil { + return nil, nil, err + } + + serverR2, err := server.Round2(clientR1) + if err != nil { + return nil, nil, err + } + + // Finalize + clientResult, err := client.Finalize(serverR2) + if err != nil { + return nil, nil, err + } + + serverResult, err := server.Finalize(clientR2) + if err != nil { + return nil, nil, err + } + + return clientResult, serverResult, nil +} + +// Run a full DKG and verify the absence of errors and valid results +func TestDkg(t *testing.T) { + // Setup and ensure no errors + clientResult, serverResult, err := dkg() + require.NoError(t, err) + require.NotNil(t, clientResult) + require.NotNil(t, serverResult) + + // Now run tests + t.Run("produce the same public key", func(t *testing.T) { + require.Equal(t, clientResult.PublicKey, serverResult.PublicKey) + }) + t.Run("produce identical public shares", func(t *testing.T) { + require.True(t, reflect.DeepEqual(clientResult.PublicShares, serverResult.PublicShares)) + }) + t.Run("produce distinct secret shares", func(t *testing.T) { + require.NotEqual(t, clientResult.SecretShare, serverResult.SecretShare) + }) + t.Run("produce distinct secret shares", func(t *testing.T) { + require.NotEqual(t, clientResult.SecretShare, serverResult.SecretShare) + }) + t.Run("shares sum to expected public key", func(t *testing.T) { + pubkey, err := reconstructPubkey( + clientResult.SecretShare, + serverResult.SecretShare, + curve) + require.NoError(t, err) + require.Equal(t, serverResult.PublicKey, pubkey) + }) +} + +// Reconstruct the pubkey from 2 shares +func reconstructPubkey(s1, s2 *v1.ShamirShare, curve elliptic.Curve) (*curves.EcPoint, error) { + s, err := v1.NewShamir(2, 2, s1.Value.Field()) + if err != nil { + return nil, err + } + + sk, err := s.Combine(s1, s2) + if err != nil { + return nil, err + } + + x, y := curve.ScalarBaseMult(sk) + return &curves.EcPoint{ + Curve: curve, + X: x, + Y: y, + }, nil +} + +// Test blind generator helper function produces a value on the expected curve +func TestNewBlindOnCurve(t *testing.T) { + const n = 1024 + for i := 0; i < n; i++ { + b, err := newBlind(curveScalar, curve) + require.NoError(t, err) + require.NotNil(t, b) + + // Valid point? + require.True(t, b.IsOnCurve() && b.IsValid()) + require.True(t, b.IsValid()) + require.False(t, b.IsIdentity()) + require.False(t, b.IsBasePoint()) + } +} + +func TestNewBlindProvidesDistinctPoints(t *testing.T) { + const n = 1024 + seen := make(map[string]bool, n) + // seen := make(map[core.EcPoint]bool, n) + + for i := 0; i < n; i++ { + b, err := newBlind(curveScalar, curve) + require.NoError(t, err) + + // serialize so the point is hashable + txt := fmt.Sprintf("%#v", b) + + // We shouldn't see the same point twice + ok := seen[txt] + require.False(t, ok) + + // store + seen[txt] = true + } +} diff --git a/pkg/crypto/ecies/encrypt.go b/pkg/crypto/ecies/encrypt.go new file mode 100644 index 000000000..4217c7fd6 --- /dev/null +++ b/pkg/crypto/ecies/encrypt.go @@ -0,0 +1,13 @@ +package ecies + +import eciesgo "github.com/ecies/go/v2" + +// Encrypt encrypts a plaintext using a public key +func Encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) { + return eciesgo.Encrypt(pub, plaintext) +} + +// Decrypt decrypts a ciphertext using a private key +func Decrypt(priv *PrivateKey, ciphertext []byte) ([]byte, error) { + return eciesgo.Decrypt(priv, ciphertext) +} diff --git a/pkg/crypto/ecies/keys.go b/pkg/crypto/ecies/keys.go new file mode 100644 index 000000000..8d02d84cf --- /dev/null +++ b/pkg/crypto/ecies/keys.go @@ -0,0 +1,57 @@ +package ecies + +import ( + "bytes" + "crypto/ecdsa" + "crypto/rand" + "fmt" + + eciesgo "github.com/ecies/go/v2" + "lukechampine.com/blake3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type PrivateKey = eciesgo.PrivateKey + +type PublicKey = eciesgo.PublicKey + +// GenerateKey generates secp256k1 key pair +func GenerateKey() (*PrivateKey, error) { + curve := curves.SP256() + p, err := ecdsa.GenerateKey(curve, rand.Reader) + if err != nil { + return nil, fmt.Errorf("cannot generate key pair: %w", err) + } + return &PrivateKey{ + PublicKey: &PublicKey{ + Curve: curve, + X: p.X, + Y: p.Y, + }, + D: p.D, + }, nil +} + +// GenerateKeyFromSeed generates secp256k1 key pair from []byte seed +func GenerateKeyFromSeed(seed []byte) (*PrivateKey, error) { + curve := curves.SP256() + p, err := ecdsa.GenerateKey(curve, bytes.NewReader(seed[:])) + if err != nil { + return nil, fmt.Errorf("cannot generate key pair: %w", err) + } + return &PrivateKey{ + PublicKey: &PublicKey{ + Curve: curve, + X: p.X, + Y: p.Y, + }, + D: p.D, + }, nil +} + +// HashSeed returns 512 sum hash of byte slice +func HashSeed(seed []byte) []byte { + bz := blake3.Sum512(seed) + return bz[:] +} diff --git a/pkg/crypto/ecies/keys_test.go b/pkg/crypto/ecies/keys_test.go new file mode 100644 index 000000000..25d652402 --- /dev/null +++ b/pkg/crypto/ecies/keys_test.go @@ -0,0 +1,22 @@ +package ecies_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/onsonr/sonr/pkg/crypto/ecies" +) + +func TestGenerateKey(t *testing.T) { + _, err := ecies.GenerateKey() + assert.NoError(t, err) +} + +func TestGenerateFromSeed(t *testing.T) { + seed := ecies.HashSeed([]byte("testasdfasdfasdfasdfasdfw234453412341testasdfasdfasdfasdfasdfw234453412341")) + _, err := ecies.GenerateKeyFromSeed(seed) + assert.NoError(t, err) + _, err = ecies.GenerateKeyFromSeed(seed) + assert.NoError(t, err) +} diff --git a/pkg/crypto/internal/err.go b/pkg/crypto/internal/err.go new file mode 100755 index 000000000..2ea5082cb --- /dev/null +++ b/pkg/crypto/internal/err.go @@ -0,0 +1,22 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package internal + +import "fmt" + +var ( + ErrNotOnCurve = fmt.Errorf("point not on the curve") + ErrPointsDistinctCurves = fmt.Errorf("points must be from the same curve") + ErrZmMembership = fmt.Errorf("x ∉ Z_m") + ErrResidueOne = fmt.Errorf("value must be 1 (mod N)") + ErrNCannotBeZero = fmt.Errorf("N cannot be 0") + ErrNilArguments = fmt.Errorf("arguments cannot be nil") + ErrZeroValue = fmt.Errorf("arguments cannot be 0") + ErrInvalidRound = fmt.Errorf("invalid round method called") + ErrIncorrectCount = fmt.Errorf("incorrect number of inputs") + ErrInvalidJson = fmt.Errorf("json format does not contain the necessary data") +) diff --git a/pkg/crypto/internal/hash.go b/pkg/crypto/internal/hash.go new file mode 100755 index 000000000..6320ea599 --- /dev/null +++ b/pkg/crypto/internal/hash.go @@ -0,0 +1,93 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package internal + +import ( + "bytes" + "crypto/sha256" + "fmt" + + "golang.org/x/crypto/hkdf" +) + +// Hash computes the HKDF over many values +// iteratively such that each value is hashed separately +// and based on preceding values +// +// The first value is computed as okm_0 = KDF(f || value) where +// f is a byte slice of 32 0xFF +// salt is zero-filled byte slice with length equal to the hash output length +// info is the protocol name +// okm is the 32 byte output +// +// The each subsequent iteration is computed by as okm_i = KDF(f_i || value || okm_{i-1}) +// where f_i = 2^b - 1 - i such that there are 0xFF bytes prior to the value. +// f_1 changes the first byte to 0xFE, f_2 to 0xFD. The previous okm is appended to the value +// to provide cryptographic domain separation. +// See https://signal.org/docs/specifications/x3dh/#cryptographic-notation +// and https://signal.org/docs/specifications/xeddsa/#hash-functions +// for more details. +// This uses the KDF function similar to X3DH for each `value` +// But changes the key just like XEdDSA where the prefix bytes change by a single bit +func Hash(info []byte, values ...[]byte) ([]byte, error) { + // Don't accept any nil arguments + if anyNil(values...) { + return nil, ErrNilArguments + } + + salt := make([]byte, 32) + okm := make([]byte, 32) + f := bytes.Repeat([]byte{0xFF}, 32) + + for _, b := range values { + ikm := append(f, b...) + ikm = append(ikm, okm...) + kdf := hkdf.New(sha256.New, ikm, salt, info) + n, err := kdf.Read(okm) + if err != nil { + return nil, err + } + if n != len(okm) { + return nil, fmt.Errorf("unable to read expected number of bytes want=%v got=%v", len(okm), n) + } + ByteSub(f) + } + return okm, nil +} + +func anyNil(values ...[]byte) bool { + for _, x := range values { + if x == nil { + return true + } + } + return false +} + +// ByteSub is a constant time algorithm for subtracting +// 1 from the array as if it were a big number. +// 0 is considered a wrap which resets to 0xFF +func ByteSub(b []byte) { + m := byte(1) + for i := 0; i < len(b); i++ { + b[i] -= m + + // If b[i] > 0, s == 0 + // If b[i] == 0, s == 1 + // Computing IsNonZero(b[i]) + s1 := int8(b[i]) >> 7 + s2 := -int8(b[i]) >> 7 + s := byte((s1 | s2) + 1) + + // If s == 0, don't subtract anymore + // s == 1, continue subtracting + m = s & m + // If s == 0 this does nothing + // If s == 1 reset this value to 0xFF + b[i] |= -s + } +} diff --git a/pkg/crypto/internal/hash_test.go b/pkg/crypto/internal/hash_test.go new file mode 100755 index 000000000..638cc909e --- /dev/null +++ b/pkg/crypto/internal/hash_test.go @@ -0,0 +1,62 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package internal + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestByteSub(t *testing.T) { + f := bytes.Repeat([]byte{0xFF}, 32) + ByteSub(f) + require.Equal(t, f[0], byte(0xFE)) + for i := 1; i < len(f); i++ { + require.Equal(t, f[i], byte(0xFF)) + } + ByteSub(f) + require.Equal(t, f[0], byte(0xFD)) + for i := 1; i < len(f); i++ { + require.Equal(t, f[i], byte(0xFF)) + } + f[0] = 0x2 + ByteSub(f) + for i := 1; i < len(f); i++ { + require.Equal(t, f[i], byte(0xFF)) + } + ByteSub(f) + require.Equal(t, f[0], byte(0xFF)) + require.Equal(t, f[1], byte(0xFE)) + for i := 2; i < len(f); i++ { + require.Equal(t, f[i], byte(0xFF)) + } + ByteSub(f) + require.Equal(t, f[0], byte(0xFE)) + require.Equal(t, f[1], byte(0xFE)) + for i := 2; i < len(f); i++ { + require.Equal(t, f[i], byte(0xFF)) + } + f[0] = 1 + f[1] = 1 + ByteSub(f) + require.Equal(t, f[0], byte(0xFF)) + require.Equal(t, f[1], byte(0xFF)) + require.Equal(t, f[2], byte(0xFE)) + for i := 3; i < len(f); i++ { + require.Equal(t, f[i], byte(0xFF)) + } +} + +func TestByteSubAll1(t *testing.T) { + f := bytes.Repeat([]byte{0x1}, 32) + ByteSub(f) + for i := 0; i < len(f); i++ { + require.Equal(t, f[i], byte(0xFF)) + } +} diff --git a/pkg/crypto/internal/point.go b/pkg/crypto/internal/point.go new file mode 100755 index 000000000..6393e803a --- /dev/null +++ b/pkg/crypto/internal/point.go @@ -0,0 +1,44 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package internal + +import ( + "crypto/elliptic" + "math/big" + + "filippo.io/edwards25519" +) + +func CalcFieldSize(curve elliptic.Curve) int { + bits := curve.Params().BitSize + return (bits + 7) / 8 +} + +func ReverseScalarBytes(inBytes []byte) []byte { + outBytes := make([]byte, len(inBytes)) + + for i, j := 0, len(inBytes)-1; j >= 0; i, j = i+1, j-1 { + outBytes[i] = inBytes[j] + } + + return outBytes +} + +func BigInt2Ed25519Point(y *big.Int) (*edwards25519.Point, error) { + b := y.Bytes() + var arr [32]byte + copy(arr[32-len(b):], b) + return edwards25519.NewIdentityPoint().SetBytes(arr[:]) +} + +func BigInt2Ed25519Scalar(x *big.Int) (*edwards25519.Scalar, error) { + // big.Int is big endian; ed25519 assumes little endian encoding + kBytes := ReverseScalarBytes(x.Bytes()) + var arr [32]byte + copy(arr[:], kBytes) + return edwards25519.NewScalar().SetCanonicalBytes(arr[:]) +} diff --git a/pkg/crypto/internal/testutils.go b/pkg/crypto/internal/testutils.go new file mode 100755 index 000000000..eec48970e --- /dev/null +++ b/pkg/crypto/internal/testutils.go @@ -0,0 +1,21 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package internal + +import ( + "math/big" +) + +// B10 creating a big.Int from a base 10 string. panics on failure to +// ensure zero-values aren't used in place of malformed strings. +func B10(s string) *big.Int { + x, ok := new(big.Int).SetString(s, 10) + if !ok { + panic("Couldn't derive big.Int from string") + } + return x +} diff --git a/pkg/crypto/mpc/caps.go b/pkg/crypto/mpc/caps.go new file mode 100644 index 000000000..9f82347ad --- /dev/null +++ b/pkg/crypto/mpc/caps.go @@ -0,0 +1,117 @@ +package mpc + +import ( + "fmt" + + "github.com/ucan-wg/go-ucan" +) + +// Capability hierarchy for smart account operations +// ---------------------------------------------- +// OWNER +// └─ OPERATOR +// ├─ EXECUTE +// ├─ PROPOSE +// └─ SIGN +// └─ SET_POLICY +// └─ SET_THRESHOLD +// └─ RECOVER +// └─ SOCIAL + +// Define capability hierarchy for smart account operations +const ( + // Root capabilities + CAP_OWNER = "OWNER" // Full account control + CAP_OPERATOR = "OPERATOR" // Can perform operations + CAP_OBSERVER = "OBSERVER" // Can view account state + + // Operation capabilities + CAP_EXECUTE = "EXECUTE" // Can execute transactions + CAP_PROPOSE = "PROPOSE" // Can propose transactions + CAP_SIGN = "SIGN" // Can sign transactions + + // Policy capabilities + CAP_SET_POLICY = "SET_POLICY" // Can modify account policies + CAP_SET_THRESHOLD = "SET_THRESHOLD" // Can modify signing threshold + + // Recovery capabilities + CAP_RECOVER = "RECOVER" // Can initiate recovery + CAP_SOCIAL = "SOCIAL" // Can act as social recovery +) + +// SmartAccountCapabilities defines the capability hierarchy +func NewSmartAccountCapabilities() ucan.NestedCapabilities { + return ucan.NewNestedCapabilities( + CAP_OWNER, + CAP_OPERATOR, + CAP_OBSERVER, + CAP_EXECUTE, + CAP_PROPOSE, + CAP_SIGN, + CAP_SET_POLICY, + CAP_SET_THRESHOLD, + CAP_RECOVER, + CAP_SOCIAL, + ) +} + +// Resource types for smart account operations +type ResourceType string + +const ( + RES_ACCOUNT = "account" + RES_TRANSACTION = "tx" + RES_POLICY = "policy" + RES_RECOVERY = "recovery" +) + +// NewSmartAccountResource creates a new resource identifier +func NewSmartAccountResource(resType ResourceType, path string) ucan.Resource { + return ucan.NewStringLengthResource(string(resType), path) +} + +// CreateSmartAccountAttenuations creates default attenuations for a smart account +func CreateSmartAccountAttenuations( + caps ucan.NestedCapabilities, + accountAddr string, +) ucan.Attenuations { + return ucan.Attenuations{ + // Owner capabilities + {caps.Cap(CAP_OWNER), NewSmartAccountResource(RES_ACCOUNT, accountAddr)}, + + // Operation capabilities + {caps.Cap(CAP_EXECUTE), NewSmartAccountResource(RES_TRANSACTION, fmt.Sprintf("%s:*", accountAddr))}, + {caps.Cap(CAP_PROPOSE), NewSmartAccountResource(RES_TRANSACTION, fmt.Sprintf("%s:*", accountAddr))}, + {caps.Cap(CAP_SIGN), NewSmartAccountResource(RES_TRANSACTION, fmt.Sprintf("%s:*", accountAddr))}, + + // Policy capabilities + {caps.Cap(CAP_SET_POLICY), NewSmartAccountResource(RES_POLICY, fmt.Sprintf("%s:*", accountAddr))}, + {caps.Cap(CAP_SET_THRESHOLD), NewSmartAccountResource(RES_POLICY, fmt.Sprintf("%s:threshold", accountAddr))}, + } +} + +// Policy represents smart account execution policies +type PolicyType string + +const ( + POLICY_THRESHOLD = "threshold" + POLICY_TIMELOCK = "timelock" + POLICY_WHITELIST = "whitelist" +) + +// CreatePolicyAttenuation creates attenuations for policy management +func CreatePolicyAttenuation( + caps ucan.NestedCapabilities, + accountAddr string, + policyType PolicyType, +) ucan.Attenuations { + return ucan.Attenuations{ + { + caps.Cap(CAP_SET_POLICY), + NewSmartAccountResource( + RES_POLICY, + fmt.Sprintf("%s:%s", accountAddr, policyType), + ), + }, + } +} diff --git a/pkg/crypto/mpc/jwt.go b/pkg/crypto/mpc/jwt.go new file mode 100644 index 000000000..7741034b1 --- /dev/null +++ b/pkg/crypto/mpc/jwt.go @@ -0,0 +1,97 @@ +package mpc + +import ( + "crypto/sha256" + "encoding/base64" + "fmt" + + "github.com/golang-jwt/jwt" +) + +// MPCSigningMethod implements the SigningMethod interface for MPC-based signing +type MPCSigningMethod struct { + Name string + ks keyshareSource +} + +// newMPCSigningMethod creates a new MPC signing method with the given keyshare source +func newMPCSigningMethod(name string, ks keyshareSource) *MPCSigningMethod { + return &MPCSigningMethod{ + Name: name, + ks: ks, + } +} + +// Alg returns the signing method's name +func (m *MPCSigningMethod) Alg() string { + return m.Name +} + +// Verify verifies the signature using the MPC public key +func (m *MPCSigningMethod) Verify(signingString, signature string, key interface{}) error { + // Decode the signature + sig, err := base64.RawURLEncoding.DecodeString(signature) + if err != nil { + return err + } + + // Hash the signing string + hasher := sha256.New() + hasher.Write([]byte(signingString)) + digest := hasher.Sum(nil) + + // Verify using the keyshare's public key + valid, err := VerifySignature(m.ks.valShare.PublicKey, digest, sig) + if err != nil { + return fmt.Errorf("failed to verify signature: %w", err) + } + if !valid { + return fmt.Errorf("invalid signature") + } + + return nil +} + +// Sign signs the data using MPC +func (m *MPCSigningMethod) Sign(signingString string, key interface{}) (string, error) { + // Hash the signing string + hasher := sha256.New() + hasher.Write([]byte(signingString)) + digest := hasher.Sum(nil) + + // Create signing functions + signFunc, err := m.ks.userShare.SignFunc(digest) + if err != nil { + return "", fmt.Errorf("failed to create sign function: %w", err) + } + + valSignFunc, err := m.ks.valShare.SignFunc(digest) + if err != nil { + return "", fmt.Errorf("failed to create validator sign function: %w", err) + } + + // Run the signing protocol + sig, err := RunSignProtocol(valSignFunc, signFunc) + if err != nil { + return "", fmt.Errorf("failed to run sign protocol: %w", err) + } + + // Serialize the signature + sigBytes, err := SerializeSignature(sig) + if err != nil { + return "", fmt.Errorf("failed to serialize signature: %w", err) + } + + // Encode the signature + encoded := base64.RawURLEncoding.EncodeToString(sigBytes) + return encoded, nil +} + +func init() { + // Register the MPC signing method + jwt.RegisterSigningMethod("MPC256", func() jwt.SigningMethod { + return &MPCSigningMethod{ + Name: "MPC256", + } + }) +} diff --git a/pkg/crypto/mpc/mpc.go b/pkg/crypto/mpc/mpc.go new file mode 100644 index 000000000..43e5ac075 --- /dev/null +++ b/pkg/crypto/mpc/mpc.go @@ -0,0 +1,107 @@ +package mpc + +import ( + "crypto/ecdsa" + "errors" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/protocol" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1" +) + +// NewKeyshareSource generates a new MPC keyshare +func NewKeyshareSource() (KeyshareSource, error) { + curve := curves.K256() + valKs := dklsv1.NewAliceDkg(curve, protocol.Version1) + userKs := dklsv1.NewBobDkg(curve, protocol.Version1) + aErr, bErr := runIteratedProtocol(userKs, valKs) + if err := checkIteratedErrors(aErr, bErr); err != nil { + return nil, err + } + valRes, err := valKs.Result(protocol.Version1) + if err != nil { + return nil, err + } + valShare, err := NewValKeyshare(valRes) + if err != nil { + return nil, err + } + userRes, err := userKs.Result(protocol.Version1) + if err != nil { + return nil, err + } + userShare, err := NewUserKeyshare(userRes) + if err != nil { + return nil, err + } + return createKeyshareSource(valShare, userShare) +} + +// RunSignProtocol runs the MPC signing protocol +func RunSignProtocol(signFuncVal SignFunc, signFuncUser SignFunc) (Signature, error) { + aErr, bErr := runIteratedProtocol(signFuncVal, signFuncUser) + if err := checkIteratedErrors(aErr, bErr); err != nil { + return nil, err + } + out, err := signFuncUser.Result(protocol.Version1) + if err != nil { + return nil, err + } + return dklsv1.DecodeSignature(out) +} + +// RunRefreshProtocol runs the MPC refresh protocol +func RunRefreshProtocol(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc) (KeyshareSource, error) { + aErr, bErr := runIteratedProtocol(refreshFuncVal, refreshFuncUser) + if err := checkIteratedErrors(aErr, bErr); err != nil { + return nil, err + } + valRefreshResult, err := refreshFuncVal.Result(protocol.Version1) + if err != nil { + return nil, err + } + valShare, err := NewValKeyshare(valRefreshResult) + if err != nil { + return nil, err + } + userRefreshResult, err := refreshFuncUser.Result(protocol.Version1) + if err != nil { + return nil, err + } + userShare, err := NewUserKeyshare(userRefreshResult) + if err != nil { + return nil, err + } + return createKeyshareSource(valShare, userShare) +} + +// SerializeSecp256k1Signature serializes an ECDSA signature into a byte slice +func SerializeSignature(sig Signature) ([]byte, error) { + rBytes := sig.R.Bytes() + sBytes := sig.S.Bytes() + + sigBytes := make([]byte, 66) // V (1 byte) + R (32 bytes) + S (32 bytes) + sigBytes[0] = byte(sig.V) + copy(sigBytes[33-len(rBytes):33], rBytes) + copy(sigBytes[66-len(sBytes):66], sBytes) + return sigBytes, nil +} + +// DeserializeSecp256k1Signature deserializes an ECDSA signature from a byte slice +func DeserializeSignature(sigBytes []byte) (Signature, error) { + if len(sigBytes) != 66 { + return nil, errors.New("malformed signature: not the correct size") + } + sig := &curves.EcdsaSignature{ + V: int(sigBytes[0]), + R: new(big.Int).SetBytes(sigBytes[1:33]), + S: new(big.Int).SetBytes(sigBytes[33:66]), + } + return sig, nil +} + +// VerifyMPCSignature verifies an MPC signature +func VerifyMPCSignature(sig Signature, msg []byte, publicKey *ecdsa.PublicKey) bool { + return ecdsa.Verify(publicKey, msg, sig.R, sig.S) +} diff --git a/pkg/crypto/mpc/mpc_test.go b/pkg/crypto/mpc/mpc_test.go new file mode 100644 index 000000000..2df5979c3 --- /dev/null +++ b/pkg/crypto/mpc/mpc_test.go @@ -0,0 +1,35 @@ +package mpc_test + +import ( + "fmt" + "testing" + + "github.com/onsonr/sonr/pkg/crypto/mpc" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestKeyshareGeneration(t *testing.T) { + // Test data + testData := []byte("hello world") + + // Generate keyshares + src, err := mpc.NewKeyshareSource() + require.NoError(t, err) + src.Address() + + // Test signing with keyshares + sig, err := src.SignData(testData) + require.NoError(t, err) + require.NotNil(t, sig) + + // Verify signature + valid, err := src.VerifyData(testData, sig) + require.NoError(t, err) + assert.True(t, valid) + tk, err := src.DefaultOriginToken() + require.NoError(t, err) + cid, err := tk.CID() + require.NoError(t, err) + fmt.Println(cid) +} diff --git a/pkg/crypto/mpc/share.go b/pkg/crypto/mpc/share.go new file mode 100644 index 000000000..5f48ca266 --- /dev/null +++ b/pkg/crypto/mpc/share.go @@ -0,0 +1,198 @@ +package mpc + +import ( + "crypto/ecdsa" + "encoding/json" + "errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/protocol" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1" + "golang.org/x/crypto/sha3" +) + +var ErrInvalidKeyshareRole = errors.New("invalid keyshare role") + +type Role int + +const ( + RoleUnknown Role = iota + RoleUser + RoleValidator +) + +func (r Role) IsUser() bool { + return r == RoleUser +} + +func (r Role) IsValidator() bool { + return r == RoleValidator +} + +// Message is the protocol.Message that is used for MPC +type Message *protocol.Message + +type PublicKey *ecdsa.PublicKey + +type Signature *curves.EcdsaSignature + +// RefreshFunc is the type for the refresh function +type RefreshFunc interface { + protocol.Iterator +} + +// SignFunc is the type for the sign function +type SignFunc interface { + protocol.Iterator +} + +type ValKeyshare struct { + Message Message `json:"message"` + Role int `json:"role"` // 1 for validator, 2 for user + PublicKey []byte `json:"public-key"` +} + +func NewValKeyshare(msg Message) (*ValKeyshare, error) { + valShare, err := dklsv1.DecodeAliceDkgResult(msg) + if err != nil { + return nil, err + } + return &ValKeyshare{ + Message: msg, + Role: 1, + PublicKey: valShare.PublicKey.ToAffineUncompressed(), + }, nil +} + +func (v ValKeyshare) GetPayloads() map[string][]byte { + return v.Message.Payloads +} + +func (v ValKeyshare) GetMetadata() map[string]string { + return v.Message.Metadata +} + +func (v ValKeyshare) GetPublicKey() []byte { + return v.PublicKey +} + +func (v ValKeyshare) GetProtocol() string { + return v.Message.Protocol +} + +func (v ValKeyshare) GetRole() int32 { + return int32(v.Role) +} + +func (v ValKeyshare) GetVersion() uint32 { + return uint32(v.Message.Version) +} + +func (k ValKeyshare) ECDSAPublicKey() (*ecdsa.PublicKey, error) { + return ComputeEcdsaPublicKey(k.PublicKey) +} + +func (k ValKeyshare) ExtractMessage() *protocol.Message { + return &protocol.Message{ + Payloads: k.GetPayloads(), + Metadata: k.GetMetadata(), + Protocol: k.GetProtocol(), + Version: uint(k.GetVersion()), + } +} + +func (k ValKeyshare) RefreshFunc() (RefreshFunc, error) { + curve := curves.K256() + return dklsv1.NewAliceRefresh(curve, k.ExtractMessage(), protocol.Version1) +} + +func (k ValKeyshare) SignFunc(msg []byte) (SignFunc, error) { + curve := curves.K256() + return dklsv1.NewAliceSign(curve, sha3.New256(), msg, k.ExtractMessage(), protocol.Version1) +} + +func (v ValKeyshare) Marshal() (string, error) { + jsonBytes, err := json.Marshal(v) + return string(jsonBytes), err +} + +func (v ValKeyshare) Unmarshal(data string) error { + return json.Unmarshal([]byte(data), &v) +} + +type UserKeyshare struct { + Message Message `json:"message"` // BobOutput + Role int `json:"role"` // 2 for user, 1 for validator + PublicKey []byte `json:"public-key"` +} + +func NewUserKeyshare(msg Message) (*UserKeyshare, error) { + out, err := dklsv1.DecodeBobDkgResult(msg) + if err != nil { + return nil, err + } + return &UserKeyshare{ + Message: msg, + Role: 2, + PublicKey: out.PublicKey.ToAffineUncompressed(), + }, nil +} + +func (u UserKeyshare) GetPayloads() map[string][]byte { + return u.Message.Payloads +} + +func (u UserKeyshare) GetMetadata() map[string]string { + return u.Message.Metadata +} + +func (u UserKeyshare) GetPublicKey() []byte { + return u.PublicKey +} + +func (u UserKeyshare) GetProtocol() string { + return u.Message.Protocol +} + +func (u UserKeyshare) GetRole() int32 { + return int32(u.Role) +} + +func (u UserKeyshare) GetVersion() uint32 { + return uint32(u.Message.Version) +} + +func (k UserKeyshare) ECDSAPublicKey() (*ecdsa.PublicKey, error) { + return ComputeEcdsaPublicKey(k.PublicKey) +} + +func (k UserKeyshare) ExtractMessage() *protocol.Message { + return &protocol.Message{ + Payloads: k.GetPayloads(), + Metadata: k.GetMetadata(), + Protocol: k.GetProtocol(), + Version: uint(k.GetVersion()), + } +} + +func (k UserKeyshare) RefreshFunc() (RefreshFunc, error) { + curve := curves.K256() + return dklsv1.NewBobRefresh(curve, k.ExtractMessage(), protocol.Version1) +} + +func (k UserKeyshare) SignFunc(msg []byte) (SignFunc, error) { + curve := curves.K256() + return dklsv1.NewBobSign(curve, sha3.New256(), msg, k.ExtractMessage(), protocol.Version1) +} + +func (u UserKeyshare) Marshal() (string, error) { + jsonBytes, err := json.Marshal(u) + if err != nil { + return "", err + } + return string(jsonBytes), nil +} + +func (u UserKeyshare) Unmarshal(data string) error { + return json.Unmarshal([]byte(data), &u) +} diff --git a/pkg/crypto/mpc/source.go b/pkg/crypto/mpc/source.go new file mode 100644 index 000000000..d29bab935 --- /dev/null +++ b/pkg/crypto/mpc/source.go @@ -0,0 +1,112 @@ +package mpc + +import ( + "fmt" + "time" + + "github.com/ucan-wg/go-ucan" +) + +type KeyshareSource interface { + ucan.Source + + Address() string + Issuer() string + DefaultOriginToken() (*Token, error) + PublicKey() []byte + TokenParser() *ucan.TokenParser + SignData(data []byte) ([]byte, error) + VerifyData(data []byte, sig []byte) (bool, error) +} + +func createKeyshareSource(val *ValKeyshare, user *UserKeyshare) (KeyshareSource, error) { + iss, addr, err := ComputeIssuerDID(val.GetPublicKey()) + if err != nil { + return nil, err + } + return keyshareSource{ + userShare: user, + valShare: val, + addr: addr, + issuerDID: iss, + }, nil +} + +// Address returns the address of the keyshare +func (k keyshareSource) Address() string { + return k.addr +} + +// Issuer returns the DID of the issuer of the keyshare +func (k keyshareSource) Issuer() string { + return k.issuerDID +} + +// PublicKey returns the public key of the keyshare +func (k keyshareSource) PublicKey() []byte { + return k.valShare.PublicKey +} + +// DefaultOriginToken returns a default token with the keyshare's issuer as the audience +func (k keyshareSource) DefaultOriginToken() (*Token, error) { + caps := NewSmartAccountCapabilities() + att := CreateSmartAccountAttenuations(caps, k.addr) + zero := time.Time{} + return k.NewOriginToken(k.issuerDID, att, nil, zero, zero) +} + +// TokenParser returns a token parser that can be used to parse tokens +func (k keyshareSource) TokenParser() *ucan.TokenParser { + caps := NewSmartAccountCapabilities() + ac := func(m map[string]interface{}) (ucan.Attenuation, error) { + var ( + cap string + rsc ucan.Resource + ) + for key, vali := range m { + val, ok := vali.(string) + if !ok { + return ucan.Attenuation{}, fmt.Errorf(`expected attenuation value to be a string`) + } + + if key == ucan.CapKey { + cap = val + } else { + rsc = ucan.NewStringLengthResource(key, val) + } + } + + return ucan.Attenuation{ + Rsc: rsc, + Cap: caps.Cap(cap), + }, nil + } + + store := ucan.NewMemTokenStore() + return ucan.NewTokenParser(ac, ucan.StringDIDPubKeyResolver{}, store.(ucan.CIDBytesResolver)) +} + +func (k keyshareSource) SignData(data []byte) ([]byte, error) { + + // Create signing functions + signFunc, err := k.userShare.SignFunc(data) + if err != nil { + return nil, fmt.Errorf("failed to create sign function: %w", err) + } + + valSignFunc, err := k.valShare.SignFunc(data) + if err != nil { + return nil, fmt.Errorf("failed to create validator sign function: %w", err) + } + + // Run the signing protocol + sig, err := RunSignProtocol(valSignFunc, signFunc) + if err != nil { + return nil, fmt.Errorf("failed to run sign protocol: %w", err) + } + return SerializeSignature(sig) +} + +func (k keyshareSource) VerifyData(data []byte, sig []byte) (bool, error) { + return VerifySignature(k.userShare.PublicKey, data, sig) +} diff --git a/pkg/crypto/mpc/ucan.go b/pkg/crypto/mpc/ucan.go new file mode 100644 index 000000000..a7555d660 --- /dev/null +++ b/pkg/crypto/mpc/ucan.go @@ -0,0 +1,95 @@ +package mpc + +import ( + "fmt" + "time" + + "github.com/golang-jwt/jwt" + "github.com/ucan-wg/go-ucan" +) + +type ( + Token = ucan.Token + Claims = ucan.Claims + Proof = ucan.Proof + + Attenuations = ucan.Attenuations + Fact = ucan.Fact +) + +var ( + UCANVersion = ucan.UCANVersion + UCANVersionKey = ucan.UCANVersionKey + PrfKey = ucan.PrfKey + FctKey = ucan.FctKey + AttKey = ucan.AttKey + CapKey = ucan.CapKey +) + +type keyshareSource struct { + userShare *UserKeyshare + valShare *ValKeyshare + + addr string + issuerDID string +} + +func (k keyshareSource) NewOriginToken(audienceDID string, att Attenuations, fct []Fact, notBefore, expires time.Time) (*ucan.Token, error) { + return k.newToken(audienceDID, nil, att, fct, notBefore, expires) +} + +func (k keyshareSource) NewAttenuatedToken(parent *Token, audienceDID string, att ucan.Attenuations, fct []ucan.Fact, nbf, exp time.Time) (*Token, error) { + if !parent.Attenuations.Contains(att) { + return nil, fmt.Errorf("scope of ucan attenuations must be less than it's parent") + } + return k.newToken(audienceDID, append(parent.Proofs, Proof(parent.Raw)), att, fct, nbf, exp) +} + +func (k keyshareSource) newToken(audienceDID string, prf []Proof, att Attenuations, fct []Fact, nbf, exp time.Time) (*ucan.Token, error) { + t := jwt.New(newMPCSigningMethod("MPC256", k)) + + // if _, err := did.Parse(audienceDID); err != nil { + // return nil, fmt.Errorf("invalid audience DID: %w", err) + // } + + t.Header[UCANVersionKey] = UCANVersion + + var ( + nbfUnix int64 + expUnix int64 + ) + + if !nbf.IsZero() { + nbfUnix = nbf.Unix() + } + if !exp.IsZero() { + expUnix = exp.Unix() + } + + // set our claims + t.Claims = &Claims{ + StandardClaims: &jwt.StandardClaims{ + Issuer: k.issuerDID, + Audience: audienceDID, + NotBefore: nbfUnix, + // set the expire time + // see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4.1.4 + ExpiresAt: expUnix, + }, + Attenuations: att, + Facts: fct, + Proofs: prf, + } + + raw, err := t.SignedString(nil) + if err != nil { + return nil, err + } + + return &Token{ + Raw: raw, + Attenuations: att, + Facts: fct, + Proofs: prf, + }, nil +} diff --git a/pkg/crypto/mpc/utils.go b/pkg/crypto/mpc/utils.go new file mode 100644 index 000000000..caacdb5d1 --- /dev/null +++ b/pkg/crypto/mpc/utils.go @@ -0,0 +1,107 @@ +package mpc + +import ( + genericecdsa "crypto/ecdsa" + "fmt" + "math/big" + + "github.com/cosmos/cosmos-sdk/types/bech32" + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/protocol" + "golang.org/x/crypto/sha3" +) + +func ComputeIssuerDID(pk []byte) (string, string, error) { + addr, err := ComputeSonrAddr(pk) + if err != nil { + return "", "", err + } + return fmt.Sprintf("did:sonr:%s", addr), addr, nil +} + +func ComputeSonrAddr(pk []byte) (string, error) { + sonrAddr, err := bech32.ConvertAndEncode("idx", pk) + if err != nil { + return "", err + } + return sonrAddr, nil +} + +// For DKG bob starts first. For refresh and sign, Alice starts first. +func runIteratedProtocol(firstParty protocol.Iterator, secondParty protocol.Iterator) (error, error) { + var ( + message *protocol.Message + aErr error + bErr error + ) + + for aErr != protocol.ErrProtocolFinished || bErr != protocol.ErrProtocolFinished { + // Crank each protocol forward one iteration + message, bErr = firstParty.Next(message) + if bErr != nil && bErr != protocol.ErrProtocolFinished { + return nil, bErr + } + + message, aErr = secondParty.Next(message) + if aErr != nil && aErr != protocol.ErrProtocolFinished { + return aErr, nil + } + } + return aErr, bErr +} + +// ComputeEcPoint builds an elliptic curve point from a compressed byte slice +func ComputeEcPoint(pubKey []byte) (*curves.EcPoint, error) { + crv := curves.K256() + x := new(big.Int).SetBytes(pubKey[1:33]) + y := new(big.Int).SetBytes(pubKey[33:]) + ecCurve, err := crv.ToEllipticCurve() + if err != nil { + return nil, fmt.Errorf("error converting curve: %v", err) + } + return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil +} + +func ComputeEcdsaPublicKey(pubKey []byte) (*genericecdsa.PublicKey, error) { + pk, err := ComputeEcPoint(pubKey) + if err != nil { + return nil, err + } + return &genericecdsa.PublicKey{ + Curve: pk.Curve, + X: pk.X, + Y: pk.Y, + }, nil +} + +// VerifySignature verifies the signature of a message +func VerifySignature(pk []byte, msg []byte, sig []byte) (bool, error) { + pp, err := ComputeEcPoint(pk) + if err != nil { + return false, err + } + sigEd, err := DeserializeSignature(sig) + if err != nil { + return false, err + } + hash := sha3.New256() + _, err = hash.Write(msg) + if err != nil { + return false, err + } + digest := hash.Sum(nil) + return curves.VerifyEcdsa(pp, digest[:], sigEd), nil +} + +func checkIteratedErrors(aErr, bErr error) error { + if aErr == protocol.ErrProtocolFinished && bErr == protocol.ErrProtocolFinished { + return nil + } + if aErr != protocol.ErrProtocolFinished { + return aErr + } + if bErr != protocol.ErrProtocolFinished { + return bErr + } + return nil +} diff --git a/pkg/crypto/ot/base/simplest/ot.go b/pkg/crypto/ot/base/simplest/ot.go new file mode 100755 index 000000000..7df60c827 --- /dev/null +++ b/pkg/crypto/ot/base/simplest/ot.go @@ -0,0 +1,392 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package simplest implements the "Verified Simplest OT", as defined in "protocol 7" of [DKLs18](https://eprint.iacr.org/2018/499.pdf). +// The original "Simplest OT" protocol is presented in [CC15](https://eprint.iacr.org/2015/267.pdf). +// In our implementation, we run OTs for multiple choice bits in parallel. Furthermore, as described in the DKLs paper, +// we implement this as Random OT protocol. We also add encryption and decryption steps as defined in the protocol, but +// emphasise that these steps are optional. Specifically, in the setting where this OT is used as the seed OT in an +// OT Extension protocol, the encryption and decryption steps are not needed. +// +// Limitation: currently we only support batch OTs that are multiples of 8. +// +// Ideal functionalities: +// - We have used ZKP Schnorr for the F^{R_{DL}}_{ZK} +// - We have used HMAC for realizing the Random Oracle Hash function, the key for HMAC is received as input to the protocol. +package simplest + +import ( + "crypto/rand" + "crypto/subtle" + "fmt" + + "github.com/gtank/merlin" + "github.com/pkg/errors" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/zkp/schnorr" +) + +const ( + // keyCount is the number of encryption keys created. Since this is a 1-out-of-2 OT, the key count is set to 2. + keyCount = 2 + + // DigestSize is the length of hash. Similarly, when it comes to encrypting and decryption, it is the size of the + // plaintext and ciphertext. + DigestSize = 32 +) + +type ( + // OneTimePadDecryptionKey is the type of Rho^w, Rho^0, and RHo^1 in the paper. + OneTimePadDecryptionKey = [DigestSize]byte + + // OneTimePadEncryptionKeys is the type of Rho^0, and RHo^1 in the paper. + OneTimePadEncryptionKeys = [keyCount][DigestSize]byte + + // OtChallenge is the type of xi in the paper. + OtChallenge = [DigestSize]byte + + // OtChallengeResponse is the type of Rho' in the paper. + OtChallengeResponse = [DigestSize]byte + + // ChallengeOpening is the type of hashed Rho^0 and Rho^1 + ChallengeOpening = [keyCount][DigestSize]byte + + // ReceiversMaskedChoices corresponds to the "A" value in the paper in compressed format. + ReceiversMaskedChoices = []byte +) + +// SenderOutput are the outputs that the sender will obtain as a result of running the "random" OT protocol. +type SenderOutput struct { + // OneTimePadEncryptionKeys are Rho^0 and Rho^1, the output of the random OT. + // These can be used to encrypt and send two messages to the receiver. + // Therefore, for readability they are called OneTimePadEncryptionKeys in the code. + OneTimePadEncryptionKeys []OneTimePadEncryptionKeys +} + +// ReceiverOutput are the outputs that the receiver will obtain as a result of running the "random" OT protocol. +type ReceiverOutput struct { + // PackedRandomChoiceBits is a packed version of the choice vector, the packing is done for performance reasons. + PackedRandomChoiceBits []byte + + // RandomChoiceBits is the choice vector represented as unpacked int array. Initialed from PackedRandomChoiceBits. + RandomChoiceBits []int + + // OneTimePadDecryptionKey is Rho^w, the output of the random OT. For the receiver, there is just 1 output per execution. + // This value will be used to decrypt one of the messages sent by the sender. + // Therefore, for readability this is called OneTimePadDecryptionKey in the code. + OneTimePadDecryptionKey []OneTimePadDecryptionKey +} + +// Sender stores state for the "sender" role in OT. see Protocol 7 in Appendix A of DKLs18. +type Sender struct { + // Output is the output that is produced as a result of running random OT protocol. + Output *SenderOutput + + curve *curves.Curve + + // secretKey is the value `b` in the paper, which is the discrete log of B, which will be (re)used in _all_ executions of the OT. + secretKey curves.Scalar + + // publicKey is the public key of the secretKey. + publicKey curves.Point + + // batchSize is the number of parallel OTs. + batchSize int + + transcript *merlin.Transcript +} + +// Receiver stores state for the "receiver" role in OT. Protocol 7, Appendix A, of DKLs. +type Receiver struct { + // Output is the output that is produced as a result of running random OT protocol. + Output *ReceiverOutput + + curve *curves.Curve + + // senderPublicKey corresponds to "B" in the paper. + senderPublicKey curves.Point + + // senderChallenge is "xi" in the protocol. + senderChallenge []OtChallenge + + // batchSize is the number of parallel OTs. + batchSize int + + transcript *merlin.Transcript +} + +// NewSender creates a new "sender" object, ready to participate in a _random_ verified simplest OT in the role of the sender. +// no messages are specified by the sender, because random ones will be sent (hence the random OT). +// ultimately, the `Sender`'s `Output` field will be appropriately populated. +// you can use it directly, or alternatively bootstrap it into an _actual_ (non-random) OT using `Round7Encrypt` below +func NewSender(curve *curves.Curve, batchSize int, uniqueSessionId [DigestSize]byte) (*Sender, error) { + if batchSize&0x07 != 0 { // This is the same as `batchSize % 8 != 0`, but is constant time + return nil, errors.New("batch size should be a multiple of 8") + } + transcript := merlin.NewTranscript("Coinbase_DKLs_SeedOT") + transcript.AppendMessage([]byte("session_id"), uniqueSessionId[:]) + return &Sender{ + Output: &SenderOutput{}, + curve: curve, + batchSize: batchSize, + transcript: transcript, + }, nil +} + +// NewReceiver is a Random OT receiver. Therefore, the choice bits are created randomly. +// The choice bits are stored in a packed format (e.g., each choice is a single bit in a byte array). +func NewReceiver(curve *curves.Curve, batchSize int, uniqueSessionId [DigestSize]byte) (*Receiver, error) { + // This is the same as `batchSize % 8 != 0`, but is constant time + if batchSize&0x07 != 0 { + return nil, errors.New("batch size should be a multiple of 8") + } + + transcript := merlin.NewTranscript("Coinbase_DKLs_SeedOT") + transcript.AppendMessage([]byte("session_id"), uniqueSessionId[:]) + + receiver := &Receiver{ + Output: &ReceiverOutput{}, + curve: curve, + batchSize: batchSize, + transcript: transcript, + } + batchSizeBytes := batchSize >> 3 // divide by 8 + receiver.Output.PackedRandomChoiceBits = make([]byte, batchSizeBytes) + if _, err := rand.Read(receiver.Output.PackedRandomChoiceBits[:]); err != nil { + return nil, errors.Wrap(err, "choosing random choice bits") + } + // Unpack into Choice bits + receiver.initChoice() + return receiver, nil +} + +// Round1ComputeAndZkpToPublicKey is the first phase of the protocol. +// computes and stores public key and returns the schnorr proof. serialized / packed. +// This implements step 1 of Protocol 7 of DKLs18, page 16. +func (sender *Sender) Round1ComputeAndZkpToPublicKey() (*schnorr.Proof, error) { + var err error + // Sample the secret key and compute the public key. + sender.secretKey = sender.curve.Scalar.Random(rand.Reader) + sender.publicKey = sender.curve.ScalarBaseMult(sender.secretKey) + + // Generate the ZKP proof. + uniqueSessionId := [DigestSize]byte{} + copy(uniqueSessionId[:], sender.transcript.ExtractBytes([]byte("sender schnorr proof"), DigestSize)) + prover := schnorr.NewProver(sender.curve, nil, uniqueSessionId[:]) + proof, err := prover.Prove(sender.secretKey) + if err != nil { + return nil, errors.Wrap(err, "creating zkp proof for secret key in seed OT sender round 1") + } + return proof, nil +} + +// Round2VerifySchnorrAndPadTransfer verifies the schnorr proof of the public key sent by the sender, i.e., step 2), +// and then does receiver's "Pad Transfer" phase in OT, i.e., step 3), of Protocol 7 (page 16) of the paper. +func (receiver *Receiver) Round2VerifySchnorrAndPadTransfer(proof *schnorr.Proof) ([]ReceiversMaskedChoices, error) { + receiver.senderPublicKey = proof.Statement + uniqueSessionId := [DigestSize]byte{} + copy(uniqueSessionId[:], receiver.transcript.ExtractBytes([]byte("sender schnorr proof"), DigestSize)) + if err := schnorr.Verify(proof, receiver.curve, nil, uniqueSessionId[:]); err != nil { + return nil, errors.Wrap(err, "verifying schnorr proof in seed OT receiver round 2") + } + + result := make([]ReceiversMaskedChoices, receiver.batchSize) + receiver.Output.OneTimePadDecryptionKey = make([]OneTimePadDecryptionKey, receiver.batchSize) + copy(uniqueSessionId[:], receiver.transcript.ExtractBytes([]byte("random oracle salts"), DigestSize)) + for i := 0; i < receiver.batchSize; i++ { + a := receiver.curve.Scalar.Random(rand.Reader) + // Computing `A := a . G + w . B` in constant time, by first computing option0 = a.G and option1 = a.G+B and then + // constant time choosing one of them by first assuming that the output is option0, and overwrite it if the choice bit is 1. + + option0 := receiver.curve.ScalarBaseMult(a) + option0Bytes := option0.ToAffineCompressed() + option1 := option0.Add(receiver.senderPublicKey) + option1Bytes := option1.ToAffineCompressed() + + result[i] = option0Bytes + subtle.ConstantTimeCopy(receiver.Output.RandomChoiceBits[i], result[i], option1Bytes) + // compute the internal rho + rho := receiver.senderPublicKey.Mul(a) + hash := sha3.New256() + if _, err := hash.Write(uniqueSessionId[:]); err != nil { + return nil, errors.Wrap(err, "writing seed to hash in round 2 pad transfer") + } + if _, err := hash.Write([]byte{byte(i)}); err != nil { + return nil, errors.Wrap(err, "writing i to hash in round 2 pad transfer") + } + if _, err := hash.Write(rho.ToAffineCompressed()); err != nil { + return nil, errors.Wrap(err, "writing point to hash in round 2 pad transfer") + } + copy(receiver.Output.OneTimePadDecryptionKey[i][:], hash.Sum(nil)) + } + return result, nil +} + +// Round3PadTransfer is the sender's "Pad Transfer" phase in OT; see steps 4 and 5 of page 16 of the paper. +// Returns the challenges xi +func (sender *Sender) Round3PadTransfer(compressedReceiversMaskedChoice []ReceiversMaskedChoices) ([]OtChallenge, error) { + var err error + challenge := make([]OtChallenge, sender.batchSize) + sender.Output.OneTimePadEncryptionKeys = make([]OneTimePadEncryptionKeys, sender.batchSize) + negSenderPublicKey := sender.publicKey.Neg() + + receiversMaskedChoice := make([]curves.Point, len(compressedReceiversMaskedChoice)) + for i := 0; i < len(compressedReceiversMaskedChoice); i++ { + if receiversMaskedChoice[i], err = sender.curve.Point.FromAffineCompressed(compressedReceiversMaskedChoice[i]); err != nil { + return nil, errors.Wrap(err, "uncompress the point") + } + } + + baseEncryptionKeyMaterial := make([]curves.Point, keyCount) + var hashedKey [keyCount][DigestSize]byte + uniqueSessionId := [DigestSize]byte{} + copy(uniqueSessionId[:], sender.transcript.ExtractBytes([]byte("random oracle salts"), DigestSize)) + + for i := 0; i < sender.batchSize; i++ { + // Sender creates two options that will eventually be used as her encryption keys. + // `baseEncryptionKeyMaterial[0]` and `baseEncryptionKeyMaterial[0]` correspond to rho_0 and rho_1 in the paper, respectively. + baseEncryptionKeyMaterial[0] = receiversMaskedChoice[i].Mul(sender.secretKey) + + receiverChoiceMinusSenderPublicKey := receiversMaskedChoice[i].Add(negSenderPublicKey) + baseEncryptionKeyMaterial[1] = receiverChoiceMinusSenderPublicKey.Mul(sender.secretKey) + + for k := 0; k < keyCount; k++ { + hash := sha3.New256() + if _, err = hash.Write(uniqueSessionId[:]); err != nil { + return nil, errors.Wrap(err, "writing seed to hash in round 3 pad transfer") + } + if _, err = hash.Write([]byte{byte(i)}); err != nil { + return nil, errors.Wrap(err, "writing i to hash in round 3 pad transfer") + } + if _, err = hash.Write(baseEncryptionKeyMaterial[k].ToAffineCompressed()); err != nil { + return nil, errors.Wrap(err, "writing point to hash in round 3 pad transfer") + } + copy(sender.Output.OneTimePadEncryptionKeys[i][k][:], hash.Sum(nil)) + if err != nil { + return nil, errors.Wrap(err, "compute the encryption keys") + } + + // Compute a challenge by XORing the hash of the hash of the key. Not a typo ;) + hashedKey[k] = sha3.Sum256(sender.Output.OneTimePadEncryptionKeys[i][k][:]) + hashedKey[k] = sha3.Sum256(hashedKey[k][:]) + } + + challenge[i] = xorBytes(hashedKey[0], hashedKey[1]) + } + return challenge, nil +} + +// Round4RespondToChallenge corresponds to initial round of the receiver's "Verify" phase; see step 6 of page 16 of the paper. +// this is just the start of Verification. In this round, the receiver outputs "rho'", which the sender will check. +func (receiver *Receiver) Round4RespondToChallenge(challenge []OtChallenge) ([]OtChallengeResponse, error) { + // store to be used in future steps + receiver.senderChallenge = challenge + // challengeResponses is Rho' in the paper. + challengeResponses := make([]OtChallengeResponse, receiver.batchSize) + for i := 0; i < receiver.batchSize; i++ { + // Constant-time xor of the hashed key and the challenge, based on the choice bit. + hashedKey := sha3.Sum256(receiver.Output.OneTimePadDecryptionKey[i][:]) + hashedKey = sha3.Sum256(hashedKey[:]) + challengeResponses[i] = hashedKey + alternativeChallengeResponse := xorBytes(receiver.senderChallenge[i], hashedKey) + subtle.ConstantTimeCopy(receiver.Output.RandomChoiceBits[i], challengeResponses[i][:], alternativeChallengeResponse[:]) + } + return challengeResponses, nil +} + +// Round5Verify verifies the challenge response. If the verification passes, sender opens his challenges to the receiver. +// See step 7 of page 16 of the paper. +// Abort if Rho' != H(H(Rho^0)) in other words, if challengeResponse != H(H(encryption key 0)). +// opening is H(encryption key) +func (sender *Sender) Round5Verify(challengeResponses []OtChallengeResponse) ([]ChallengeOpening, error) { + opening := make([]ChallengeOpening, sender.batchSize) + for i := 0; i < sender.batchSize; i++ { + for k := 0; k < keyCount; k++ { + opening[i][k] = sha3.Sum256(sender.Output.OneTimePadEncryptionKeys[i][k][:]) + } + + // Verify + hashedKey0 := sha3.Sum256(opening[i][0][:]) + if subtle.ConstantTimeCompare(hashedKey0[:], challengeResponses[i][:]) != 1 { + return nil, errors.New("receiver's challenge response didn't match H(H(rho^0))") + } + } + return opening, nil +} + +// Round6Verify is the _last_ part of the "Verification" phase of OT; see p. 16 of https://eprint.iacr.org/2018/499.pdf. +// See step 8 of page 16 of the paper. +// Abort if H(Rho^w) != the one it calculated itself or +// +// if Xi != H(H(Rho^0)) XOR H(H(Rho^1)) +// +// In other words, +// +// if opening_w != H(decryption key) or +// if challenge != H(opening 0) XOR H(opening 0) +func (receiver *Receiver) Round6Verify(challengeOpenings []ChallengeOpening) error { + for i := 0; i < receiver.batchSize; i++ { + hashedDecryptionKey := sha3.Sum256(receiver.Output.OneTimePadDecryptionKey[i][:]) + w := receiver.Output.RandomChoiceBits[i] + if subtle.ConstantTimeCompare(hashedDecryptionKey[:], challengeOpenings[i][w][:]) != 1 { + return fmt.Errorf("sender's supposed H(rho^omega) doesn't match our own") + } + hashedKey0 := sha3.Sum256(challengeOpenings[i][0][:]) + hashedKey1 := sha3.Sum256(challengeOpenings[i][1][:]) + reconstructedChallenge := xorBytes(hashedKey0, hashedKey1) + if subtle.ConstantTimeCompare(reconstructedChallenge[:], receiver.senderChallenge[i][:]) != 1 { + return fmt.Errorf("sender's openings H(rho^0) and H(rho^1) didn't decommit to its prior message") + } + } + return nil +} + +// Round7Encrypt wraps an `Encrypt` operation on the Sender's underlying output from the random OT; see `Encrypt` below. +// this is optional; it will be used only in circumstances when you want to run "actual" (i.e., non-random) OT +func (sender *Sender) Round7Encrypt(messages [][keyCount][DigestSize]byte) ([][keyCount][DigestSize]byte, error) { + return sender.Output.Encrypt(messages) +} + +// Round8Decrypt wraps a `Decrypt` operation on the Receiver's underlying output from the random OT; see `Decrypt` below +// this is optional; it will be used only in circumstances when you want to run "actual" (i.e., non-random) OT +func (receiver *Receiver) Round8Decrypt(ciphertext [][keyCount][DigestSize]byte) ([][DigestSize]byte, error) { + return receiver.Output.Decrypt(ciphertext) +} + +// Encrypt runs step 9) of the seed OT Protocol 7) of https://eprint.iacr.org/2018/499.pdf, +// in which the seed OT sender "encrypts" both messages under the "one-time keys" output by the random OT. +func (s *SenderOutput) Encrypt(plaintexts [][keyCount][DigestSize]byte) ([][keyCount][DigestSize]byte, error) { + batchSize := len(s.OneTimePadEncryptionKeys) + if len(plaintexts) != batchSize { + return nil, errors.New("message size should be same as batch size") + } + ciphertexts := make([][keyCount][DigestSize]byte, batchSize) + + for i := 0; i < len(plaintexts); i++ { + for k := 0; k < keyCount; k++ { + ciphertexts[i][k] = xorBytes(s.OneTimePadEncryptionKeys[i][k], plaintexts[i][k]) + } + } + return ciphertexts, nil +} + +// Decrypt is step 10) of the seed OT Protocol 7) of https://eprint.iacr.org/2018/499.pdf, +// where the seed OT receiver "decrypts" the message it's receiving using the "key" it received in the random OT. +func (r *ReceiverOutput) Decrypt(ciphertexts [][keyCount][DigestSize]byte) ([][DigestSize]byte, error) { + batchSize := len(r.OneTimePadDecryptionKey) + if len(ciphertexts) != batchSize { + return nil, errors.New("number of ciphertexts should be same as batch size") + } + plaintexts := make([][DigestSize]byte, batchSize) + + for i := 0; i < len(ciphertexts); i++ { + choice := r.RandomChoiceBits[i] + plaintexts[i] = xorBytes(r.OneTimePadDecryptionKey[i], ciphertexts[i][choice]) + } + return plaintexts, nil +} diff --git a/pkg/crypto/ot/base/simplest/ot_test.go b/pkg/crypto/ot/base/simplest/ot_test.go new file mode 100755 index 000000000..054693bf1 --- /dev/null +++ b/pkg/crypto/ot/base/simplest/ot_test.go @@ -0,0 +1,85 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package simplest_test + +import ( + "crypto/rand" + "crypto/sha256" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/ottest" +) + +func TestOtOnMultipleCurves(t *testing.T) { + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + batchSize := 256 + hashKeySeed := [32]byte{} + _, err := rand.Read(hashKeySeed[:]) + require.NoError(t, err) + sender, receiver, err := ottest.RunSimplestOT(curve, batchSize, hashKeySeed) + require.NoError(t, err) + + for i := 0; i < batchSize; i++ { + require.Equal(t, receiver.OneTimePadDecryptionKey[i], sender.OneTimePadEncryptionKeys[i][receiver.RandomChoiceBits[i]]) + } + + // Transfer messages + messages := make([][2][32]byte, batchSize) + for i := 0; i < batchSize; i++ { + messages[i] = [2][32]byte{ + sha256.Sum256([]byte(fmt.Sprintf("message[%d][0]", i))), + sha256.Sum256([]byte(fmt.Sprintf("message[%d][1]", i))), + } + } + ciphertexts, err := sender.Encrypt(messages) + require.NoError(t, err) + decrypted, err := receiver.Decrypt(ciphertexts) + require.NoError(t, err) + + for i := 0; i < batchSize; i++ { + choice := receiver.RandomChoiceBits[i] + require.Equal(t, messages[i][choice], decrypted[i]) + require.NotEqual(t, messages[i][1-choice], decrypted[i]) + } + } +} + +func TestOTStreaming(t *testing.T) { + batchSize := 256 + curve := curves.K256() + hashKeySeed := [32]byte{} + _, err := rand.Read(hashKeySeed[:]) + require.NoError(t, err) + sender, err := simplest.NewSender(curve, batchSize, hashKeySeed) + require.Nil(t, err) + receiver, err := simplest.NewReceiver(curve, batchSize, hashKeySeed) + require.Nil(t, err) + + senderPipe, receiverPipe := simplest.NewPipeWrappers() + errorsChannel := make(chan error, 2) // warning: if one party errors, the other will sit there forever. add timeouts. + go func() { + errorsChannel <- simplest.SenderStreamOTRun(sender, senderPipe) + }() + go func() { + errorsChannel <- simplest.ReceiverStreamOTRun(receiver, receiverPipe) + }() + for i := 0; i < 2; i++ { + require.Nil(t, <-errorsChannel) + } + for i := 0; i < batchSize; i++ { + require.Equal(t, receiver.Output.OneTimePadDecryptionKey[i], sender.Output.OneTimePadEncryptionKeys[i][receiver.Output.RandomChoiceBits[i]]) + } +} diff --git a/pkg/crypto/ot/base/simplest/stream.go b/pkg/crypto/ot/base/simplest/stream.go new file mode 100755 index 000000000..15066955d --- /dev/null +++ b/pkg/crypto/ot/base/simplest/stream.go @@ -0,0 +1,100 @@ +package simplest + +import ( + "encoding/gob" + "io" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/zkp/schnorr" +) + +// ReceiverStreamOTRun exposes the entire seed OT process for the receiver in "stream mode" to the user. +// what this means is that instead of calling the component methods in the process manually, and manually handling +// the encoding and decoding of the resulting output and input structs, the user needs _only_ to pass a ReadWriter +// (in practice this will be something like a websocket object), and this method will handle the entire process. +// this serves the dual (though related) purpose of conveniently bundling up the entire seed OT process, +// for use in tests, both in this package, as well as in the other packages which use this one (like cOT and mult). +func ReceiverStreamOTRun(receiver *Receiver, rw io.ReadWriter) error { + enc := gob.NewEncoder(rw) + dec := gob.NewDecoder(rw) + gob.Register(&curves.ScalarK256{}) + gob.Register(&curves.PointK256{}) + + proof := &schnorr.Proof{} + + if err := dec.Decode(proof); err != nil { + return errors.Wrap(err, "failed to decode proof in receiver stream OT") + } + + receiversMaskedChoice, err := receiver.Round2VerifySchnorrAndPadTransfer(proof) + if err != nil { + return errors.Wrap(err, "error in round 2 in receiver stream OT") + } + if err = enc.Encode(receiversMaskedChoice); err != nil { + return errors.Wrap(err, "error encoding result of round 1 in receiver stream OT") + } + var challenge []OtChallenge + err = dec.Decode(&challenge) + if err != nil { + return errors.Wrap(err, "error decoding challenge in receiver stream OT") + } + challengeResponse, err := receiver.Round4RespondToChallenge(challenge) + if err != nil { + return errors.Wrap(err, "error computing round 2 challenge response in receiver stream OT") + } + if err = enc.Encode(challengeResponse); err != nil { + return errors.Wrap(err, "error encoding challenge response in receiver stream OT") + } + var openings []ChallengeOpening + err = dec.Decode(&openings) + if err != nil { + return errors.Wrap(err, "error decoding challenge openings in receiver stream OT") + } + return receiver.Round6Verify(openings) +} + +// SenderStreamOTRun exposes the entire seed OT process for the sender in "stream mode" to the user. +// similarly to the above, this means that the user needs only to pass a `ReadWriter` representing the comm channel; +// this method will handle all encoding and decoding + writing and reading to the channel. +func SenderStreamOTRun(sender *Sender, rw io.ReadWriter) error { + // again a high-level helper method showing the overall flow, this time for the sender. + enc := gob.NewEncoder(rw) + dec := gob.NewDecoder(rw) + gob.Register(&curves.ScalarK256{}) + gob.Register(&curves.PointK256{}) + + proof, err := sender.Round1ComputeAndZkpToPublicKey() + if err != nil { + return err + } + if err = enc.Encode(proof); err != nil { + return err + } + + var receiversMaskedChoice []ReceiversMaskedChoices + err = dec.Decode(&receiversMaskedChoice) + if err != nil { + return errors.Wrap(err, "error decoding receiver's masked choice in sender stream OT") + } + + challenge, err := sender.Round3PadTransfer(receiversMaskedChoice) + if err != nil { + return errors.Wrap(err, "error during round 2 pad transfer in sender stream OT") + } + err = enc.Encode(challenge) + if err != nil { + return errors.Wrap(err, "error encoding challenge in sender stream OT") + } + var challengeResponses []OtChallengeResponse + err = dec.Decode(&challengeResponses) + if err != nil { + return errors.Wrap(err, "error decoding challenges responses in sender stream OT") + } + opening, err := sender.Round5Verify(challengeResponses) + if err != nil { + return errors.Wrap(err, "error in round 3 verify in sender stream OT") + } + return enc.Encode(opening) +} diff --git a/pkg/crypto/ot/base/simplest/util.go b/pkg/crypto/ot/base/simplest/util.go new file mode 100755 index 000000000..0555a7e73 --- /dev/null +++ b/pkg/crypto/ot/base/simplest/util.go @@ -0,0 +1,53 @@ +package simplest + +import ( + "io" +) + +// xorBytes computes c = a xor b. +func xorBytes(a, b [DigestSize]byte) (c [DigestSize]byte) { + for i := 0; i < DigestSize; i++ { + c[i] = a[i] ^ b[i] + } + return +} + +// initChoice initializes the receiver's choice array from the PackedRandomChoiceBits array +func (receiver *Receiver) initChoice() { + // unpack the random values in PackedRandomChoiceBits into bits in Choice + receiver.Output.RandomChoiceBits = make([]int, receiver.batchSize) + for i := 0; i < len(receiver.Output.RandomChoiceBits); i++ { + receiver.Output.RandomChoiceBits[i] = int(ExtractBitFromByteVector(receiver.Output.PackedRandomChoiceBits, i)) + } +} + +// ExtractBitFromByteVector interprets the byte-vector `vector` as if it were a _bit_-vector with len(vector) * 8 bits. +// it extracts the `index`th such bit, interpreted in the little-endian way (i.e., both across bytes and within bytes). +func ExtractBitFromByteVector(vector []byte, index int) byte { + // the bitwise tricks index >> 3 == index // 8 and index & 0x07 == index % 8 are designed to avoid CPU division. + return vector[index>>3] >> (index & 0x07) & 0x01 +} + +type pipeWrapper struct { + r *io.PipeReader + w *io.PipeWriter + exchanged int // used this during testing, to track bytes exchanged +} + +func (wrapper *pipeWrapper) Write(p []byte) (n int, err error) { + n, err = wrapper.w.Write(p) + wrapper.exchanged += n + return +} + +func (wrapper *pipeWrapper) Read(p []byte) (n int, err error) { + n, err = wrapper.r.Read(p) + wrapper.exchanged += n + return +} + +func NewPipeWrappers() (*pipeWrapper, *pipeWrapper) { + leftOut, leftIn := io.Pipe() + rightOut, rightIn := io.Pipe() + return &pipeWrapper{r: leftOut, w: rightIn}, &pipeWrapper{r: rightOut, w: leftIn} +} diff --git a/pkg/crypto/ot/extension/kos/kos.go b/pkg/crypto/ot/extension/kos/kos.go new file mode 100755 index 000000000..0dee042b9 --- /dev/null +++ b/pkg/crypto/ot/extension/kos/kos.go @@ -0,0 +1,400 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package kos in an implementation of maliciously secure OT extension protocol defined in "Protocol 9" of +// [DKLs18](https://eprint.iacr.org/2018/499.pdf). The original protocol was presented in +// [KOS15](https://eprint.iacr.org/2015/546.pdf). +package kos + +import ( + "crypto/rand" + "crypto/subtle" + "encoding/binary" + "fmt" + + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/pkg/errors" +) + +const ( + // below are the "cryptographic parameters", including computational and statistical, + // as well as the cOT block size parameters, which depend on these in a pre-defined way. + + // Kappa is the computational security parameter. + Kappa = 256 + + // KappaBytes is same as Kappa // 8, but avoids cpu division. + KappaBytes = Kappa >> 3 + + // L is the batch size used in the cOT functionality. + L = 2*Kappa + 2*s + + // COtBlockSizeBytes is same as L // 8, but avoids cpu division. + COtBlockSizeBytes = L >> 3 + + // OtWidth is the number of scalars processed per "slot" of the cOT. by definition of this parameter, + // for each of the receiver's choice bits, the sender will provide `OTWidth` scalars. + // in turn, both the sender and receiver will obtain `OTWidth` shares _per_ slot / bit of the cOT. + // by definition of the cOT, these "vectors of" scalars will add (componentwise) to the sender's original scalars. + OtWidth = 2 + + s = 80 // statistical security parameter. + kappaOT = Kappa + s + lPrime = L + kappaOT // length of pseudorandom seed expansion, used within cOT protocol + cOtExtendedBlockSizeBytes = lPrime >> 3 +) + +type Receiver struct { + // OutputAdditiveShares are the ultimate output received. basically just the "pads". + OutputAdditiveShares [L][OtWidth]curves.Scalar + + // seedOtResults are the results that this party has received by playing the sender role in a base OT protocol. + seedOtResults *simplest.SenderOutput + + // extendedPackedChoices is storage for "choice vector || gamma^{ext}" in a packed format. + extendedPackedChoices [cOtExtendedBlockSizeBytes]byte + psi [lPrime][KappaBytes]byte // transpose of v^0. gets retained between messages + + curve *curves.Curve + uniqueSessionId [simplest.DigestSize]byte // store this between rounds +} + +type Sender struct { + // OutputAdditiveShares are the ultimate output received. basically just the "pads". + OutputAdditiveShares [L][OtWidth]curves.Scalar + + // seedOtResults are the results that this party has received by playing the receiver role in a base OT protocol. + seedOtResults *simplest.ReceiverOutput + + curve *curves.Curve +} + +func binaryFieldMul(A []byte, B []byte) []byte { + // multiplies `A` and `B` in the finite field of order 2^256. + // The reference is Hankerson, Vanstone and Menezes, Guide to Elliptic Curve Cryptography. https://link.springer.com/book/10.1007/b97644 + // `A` and `B` are both assumed to be 32-bytes slices. here we view them as little-endian coordinate representations of degree-255 polynomials. + // the multiplication takes place modulo the irreducible (over F_2) polynomial f(X) = X^256 + X^10 + X^5 + X^2 + 1. see Table A.1. + // the techniques we use are given in section 2.3, Binary field arithmetic. + // for the multiplication part, we use Algorithm 2.34, "Right-to-left comb method for polynomial multiplication". + // for the reduction part, we use a variant of the idea of Figure 2.9, customized to our setting. + const W = 64 // the machine word width, in bits. + const t = 4 // the number of words needed to represent a polynomial. + c := make([]uint64, 2*t) // result + a := make([]uint64, t) + b := make([]uint64, t+1) // will hold a copy of b, shifted by some amount + for i := 0; i < 32; i++ { // "condense" `A` and `B` into word-vectors, instead of byte-vectors + a[i>>3] |= uint64(A[i]) << (i & 0x07 << 3) + b[i>>3] |= uint64(B[i]) << (i & 0x07 << 3) + } + for k := 0; k < W; k++ { + for j := 0; j < t; j++ { + // conditionally add a copy of (the appropriately shifted) B to C, depending on the appropriate bit of A + // do this in constant-time; i.e., independent of A. + // technically, in each time we call this, the right-hand argument is a public datum, + // so we could arrange things so that it's _not_ constant-time, but the variable-time stuff always depends on something public. + // better to just be safe here though and make it constant-time anyway. + mask := -(a[j] >> k & 0x01) // if A[j] >> k & 0x01 == 1 then 0xFFFFFFFFFFFFFFFF else 0x0000000000000000 + for i := 0; i < t+1; i++ { + c[j+i] ^= b[i] & mask // conditionally add B to C{j} + } + } + for i := t; i > 0; i-- { + b[i] = b[i]<<1 | b[i-1]>>63 + } + b[0] <<= 1 + } + // multiplication complete; begin reduction. + // things become actually somewhat simpler in our case, because the degree of the polynomial is a multiple of the word size + // the technique to come up with the numbers below comes essentially from going through the exact same process as on page 54, + // but with the polynomial f(X) = X^256 + X^10 + X^5 + X^2 + 1 above instead, and with parameters m = 256, W = 64, t = 4. + // the idea is exactly as described informally on that page, even though this particular polynomial isn't explicitly treated. + for i := 2*t - 1; i >= t; i-- { + c[i-4] ^= c[i] << 10 + c[i-3] ^= c[i] >> 54 + c[i-4] ^= c[i] << 5 + c[i-3] ^= c[i] >> 59 + c[i-4] ^= c[i] << 2 + c[i-3] ^= c[i] >> 62 + c[i-4] ^= c[i] + } + C := make([]byte, 32) + for i := 0; i < 32; i++ { + C[i] = byte(c[i>>3] >> (i & 0x07 << 3)) // truncate word to byte + } + return C +} + +// NewCOtReceiver creates a `Receiver` instance, ready for use as the receiver in the KOS cOT protocol +// you must supply the output gotten by running an instance of seed OT as the _sender_ (note the reversal of roles) +func NewCOtReceiver(seedOTResults *simplest.SenderOutput, curve *curves.Curve) *Receiver { + return &Receiver{ + seedOtResults: seedOTResults, + curve: curve, + } +} + +// NewCOtSender creates a `Sender` instance, ready for use as the sender in the KOS cOT protocol. +// you must supply the output gotten by running an instance of seed OT as the _receiver_ (note the reversal of roles) +func NewCOtSender(seedOTResults *simplest.ReceiverOutput, curve *curves.Curve) *Sender { + return &Sender{ + seedOtResults: seedOTResults, + curve: curve, + } +} + +// Round1Output is Bob's first message to Alice during cOT extension; +// these outputs are described in step 4) of Protocol 9) https://eprint.iacr.org/2018/499.pdf +type Round1Output struct { + U [Kappa][cOtExtendedBlockSizeBytes]byte + WPrime [simplest.DigestSize]byte + VPrime [simplest.DigestSize]byte +} + +// Round2Output this is Alice's response to Bob in cOT extension; +// the values `tau` are specified in Alice's step 6) of Protocol 9) https://eprint.iacr.org/2018/499.pdf +type Round2Output struct { + Tau [L][OtWidth]curves.Scalar +} + +// convertBitToBitmask converts a "bit"---i.e., a `byte` which is _assumed to be_ either 0 or 1---into a bitmask, +// namely, it outputs 0x00 if `bit == 0` and 0xFF if `bit == 1`. +func convertBitToBitmask(bit byte) byte { + return ^(bit - 0x01) +} + +// the below code takes as input a `kappa` by `lPrime` _boolean_ matrix, whose rows are actually "compacted" as bytes. +// so in actuality, it's a `kappa` by `lPrime >> 3 == cOtExtendedBlockSizeBytes` matrix of _bytes_. +// its output is the same boolean matrix, but transposed, so it has dimensions `lPrime` by `kappa`. +// but likewise we want to compact the output matrix as bytes, again _row-wise_. +// so the output matrix's dimensions are lPrime by `kappa >> 3 == KappaBytes`, as a _byte_ matrix. +// the technique is fairly straightforward, but involves some bitwise operations. +func transposeBooleanMatrix(input [Kappa][cOtExtendedBlockSizeBytes]byte) [lPrime][KappaBytes]byte { + output := [lPrime][KappaBytes]byte{} + for rowByte := 0; rowByte < KappaBytes; rowByte++ { + for rowBitWithinByte := 0; rowBitWithinByte < 8; rowBitWithinByte++ { + for columnByte := 0; columnByte < cOtExtendedBlockSizeBytes; columnByte++ { + for columnBitWithinByte := 0; columnBitWithinByte < 8; columnBitWithinByte++ { + rowBit := rowByte<<3 + rowBitWithinByte + columnBit := columnByte<<3 + columnBitWithinByte + // the below code grabs the _bit_ at input[rowBit][columnBit], if input were a viewed as a boolean matrix. + // in reality, it's packed into bytes, so instead we have to grab the `columnBitWithinByte`th bit within the appropriate byte. + bitAtInputRowBitColumnBit := input[rowBit][columnByte] >> columnBitWithinByte & 0x01 + // now that we've grabbed the bit we care about, we need to write it into the appropriate place in the output matrix + // the output matrix is also packed---but in the "opposite" way (the short dimension is packed, instead of the long one) + // what we're going to do is take the _bit_ we got, and shift it by rowBitWithinByte. + // this has the effect of preparing for us to write it into the appropriate place into the output matrix. + shiftedBit := bitAtInputRowBitColumnBit << rowBitWithinByte + output[columnBit][rowByte] |= shiftedBit + } + } + } + } + return output +} + +// Round1Initialize initializes the OT Extension. see page 17, steps 1), 2), 3) and 4) of Protocol 9 of the paper. +// The input `choice` vector is "packed" (i.e., the underlying abstract vector of `L` bits is represented as a `cOTBlockSizeBytes` bytes). +func (receiver *Receiver) Round1Initialize(uniqueSessionId [simplest.DigestSize]byte, choice [COtBlockSizeBytes]byte) (*Round1Output, error) { + // salt the transcript with the OT-extension session ID + receiver.uniqueSessionId = uniqueSessionId + + // write the input choice vector into our local data. Since `otBatchSize` is the number of bits, we are working with + // bytes, we first need to calculate how many bytes are needed to store that many bits. + copy(receiver.extendedPackedChoices[0:COtBlockSizeBytes], choice[:]) + + // Fill the rest of the extended choice vector with random values. These random values correspond to `gamma^{ext}`. + if _, err := rand.Read(receiver.extendedPackedChoices[COtBlockSizeBytes:]); err != nil { + return nil, errors.Wrap(err, "sampling random coins for gamma^{ext}") + } + + v := [2][Kappa][cOtExtendedBlockSizeBytes]byte{} // kappa * L array of _bits_, in "dense" form. contains _both_ v_0 and v_1. + result := &Round1Output{} + + hash := sha3.New256() // basically this will contain a hash of the matrix U. + for i := 0; i < Kappa; i++ { + for j := 0; j < 2; j++ { + shake := sha3.NewCShake256(uniqueSessionId[:], []byte("Coinbase_DKLs_cOT")) + if _, err := shake.Write(receiver.seedOtResults.OneTimePadEncryptionKeys[i][j][:]); err != nil { + return nil, errors.Wrap(err, "writing seed OT into shake in cOT receiver round 1") + } + // this is the core pseudorandom expansion of the secret OT input seeds s_i^0 and s_i^1 + // see Extension, 2), in Protocol 9, page 17 of DKLs https://eprint.iacr.org/2018/499.pdf + // use the uniqueSessionId as the "domain separator", and the _secret_ seed rho as the input! + if _, err := shake.Read(v[j][i][:]); err != nil { + return nil, errors.Wrap(err, "reading from shake to compute v^j in cOT receiver round 1") + } + } + for j := 0; j < cOtExtendedBlockSizeBytes; j++ { + result.U[i][j] = v[0][i][j] ^ v[1][i][j] ^ receiver.extendedPackedChoices[j] + // U := v_i^0 ^ v_i^1 ^ w. note: in step 4) of Prot. 9, i think `w` should be bolded? + } + if _, err := hash.Write(result.U[i][:]); err != nil { + return nil, err + } + } + receiver.psi = transposeBooleanMatrix(v[0]) + digest := hash.Sum(nil) // go ahead and record this, so that we only have to hash the big matrix U once. + for j := 0; j < lPrime; j++ { + hash = sha3.New256() + jBytes := [2]byte{} + binary.BigEndian.PutUint16(jBytes[:], uint16(j)) + if _, err := hash.Write(jBytes[:]); err != nil { // write j into shake + return nil, errors.Wrap(err, "writing nonce into hash while computing chiJ in cOT receiver round 1") + } + if _, err := hash.Write(digest); err != nil { + return nil, errors.Wrap(err, "writing input digest into hash while computing chiJ in cOT receiver round 1") + } + chiJ := hash.Sum(nil) + wJ := convertBitToBitmask(simplest.ExtractBitFromByteVector(receiver.extendedPackedChoices[:], j)) // extract j^th bit from vector of bytes w. + psiJTimesChiJ := binaryFieldMul(receiver.psi[j][:], chiJ) + for k := 0; k < KappaBytes; k++ { + result.WPrime[k] ^= wJ & chiJ[k] + result.VPrime[k] ^= psiJTimesChiJ[k] + } + } + return result, nil +} + +// Round2Transfer computes the OT sender ("Alice")'s part of cOT; this includes steps 2) 5) and 6) of Protocol 9 +// `input` is the sender's main vector of inputs alpha_j; these are the things tA_j and tB_j will add to if w_j == 1. +// `message` contains the message the receiver ("Bob") sent us. this itself contains Bob's values WPrime, VPrime, and U +// the output is just the values `Tau` we send back to Bob. +// as a side effect of this function, our (i.e., the sender's) outputs tA_j from the cOT will be populated. +func (sender *Sender) Round2Transfer(uniqueSessionId [simplest.DigestSize]byte, input [L][OtWidth]curves.Scalar, round1Output *Round1Output) (*Round2Output, error) { + z := [Kappa][cOtExtendedBlockSizeBytes]byte{} + hash := sha3.New256() // basically this will contain a hash of the matrix U. + + for i := 0; i < Kappa; i++ { + v := make([]byte, cOtExtendedBlockSizeBytes) // will contain alice's expanded PRG output for the row i, namely v_i^{\Nabla_i}. + shake := sha3.NewCShake256(uniqueSessionId[:], []byte("Coinbase_DKLs_cOT")) + if _, err := shake.Write(sender.seedOtResults.OneTimePadDecryptionKey[i][:]); err != nil { + return nil, errors.Wrap(err, "sender writing seed OT decryption key into shake in sender round 2 transfer") + } + if _, err := shake.Read(v); err != nil { + return nil, errors.Wrap(err, "reading from shake into row `v` in sender round 2 transfer") + } + // use the idExt as the domain separator, and the _secret_ seed rho as the input! + mask := convertBitToBitmask(byte(sender.seedOtResults.RandomChoiceBits[i])) + for j := 0; j < cOtExtendedBlockSizeBytes; j++ { + z[i][j] = v[j] ^ mask&round1Output.U[i][j] + } + if _, err := hash.Write(round1Output.U[i][:]); err != nil { + return nil, errors.Wrap(err, "writing matrix U to hash in cOT sender round 2 transfer") + } + } + zeta := transposeBooleanMatrix(z) + digest := hash.Sum(nil) // go ahead and record this, so that we only have to hash the big matrix U once. + zPrime := [simplest.DigestSize]byte{} + for j := 0; j < lPrime; j++ { + hash = sha3.New256() + jBytes := [2]byte{} + binary.BigEndian.PutUint16(jBytes[:], uint16(j)) + if _, err := hash.Write(jBytes[:]); err != nil { // write j into hash + return nil, errors.Wrap(err, "writing nonce into hash while computing chiJ in cOT sender round 2 transfer") + } + if _, err := hash.Write(digest); err != nil { + return nil, errors.Wrap(err, "writing input digest into hash while computing chiJ in cOT sender round 2 transfer") + } + chiJ := hash.Sum(nil) + zetaJTimesChiJ := binaryFieldMul(zeta[j][:], chiJ) + for k := 0; k < KappaBytes; k++ { + zPrime[k] ^= zetaJTimesChiJ[k] + } + } + rhs := [simplest.DigestSize]byte{} + nablaTimesWPrime := binaryFieldMul(sender.seedOtResults.PackedRandomChoiceBits, round1Output.WPrime[:]) + for i := 0; i < KappaBytes; i++ { + rhs[i] = round1Output.VPrime[i] ^ nablaTimesWPrime[i] + } + if subtle.ConstantTimeCompare(zPrime[:], rhs[:]) != 1 { + return nil, fmt.Errorf("cOT receiver's consistency check failed; this may be an attempted attack; do NOT re-run the protocol") + } + result := &Round2Output{} + for j := 0; j < L; j++ { + column := make([]byte, OtWidth*simplest.DigestSize) + shake := sha3.NewCShake256(uniqueSessionId[:], []byte("Coinbase_DKLs_cOT")) + jBytes := [2]byte{} + binary.BigEndian.PutUint16(jBytes[:], uint16(j)) + if _, err := shake.Write(jBytes[:]); err != nil { // write j into hash + return nil, errors.Wrap(err, "writing nonce into shake while computing OutputAdditiveShares in cOT sender round 2 transfer") + } + if _, err := shake.Write(zeta[j][:]); err != nil { + return nil, errors.Wrap(err, "writing input zeta_j into shake while computing OutputAdditiveShares in cOT sender round 2 transfer") + } + if _, err := shake.Read(column[:]); err != nil { + return nil, errors.Wrap(err, "reading shake into column while computing OutputAdditiveShares in cOT sender round 2 transfer") + } + var err error + for k := 0; k < OtWidth; k++ { + sender.OutputAdditiveShares[j][k], err = sender.curve.Scalar.SetBytes(column[k*simplest.DigestSize : (k+1)*simplest.DigestSize]) + if err != nil { + return nil, errors.Wrap(err, "OutputAdditiveShares scalar from bytes") + } + } + for i := 0; i < KappaBytes; i++ { + zeta[j][i] ^= sender.seedOtResults.PackedRandomChoiceBits[i] // note: overwrites zeta_j. just using it as a place to store + } + column = make([]byte, OtWidth*simplest.DigestSize) + shake = sha3.NewCShake256(uniqueSessionId[:], []byte("Coinbase_DKLs_cOT")) + binary.BigEndian.PutUint16(jBytes[:], uint16(j)) + if _, err := shake.Write(jBytes[:]); err != nil { // write j into hash + return nil, errors.Wrap(err, "writing nonce into shake while computing tau in cOT sender round 2 transfer") + } + if _, err := shake.Write(zeta[j][:]); err != nil { + return nil, errors.Wrap(err, "writing input zeta_j into shake while computing tau in cOT sender round 2 transfer") + } + if _, err := shake.Read(column[:]); err != nil { + return nil, errors.Wrap(err, "reading shake into column while computing tau in cOT sender round 2 transfer") + } + for k := 0; k < OtWidth; k++ { + result.Tau[j][k], err = sender.curve.Scalar.SetBytes(column[k*simplest.DigestSize : (k+1)*simplest.DigestSize]) + if err != nil { + return nil, errors.Wrap(err, "scalar Tau from bytes") + } + result.Tau[j][k] = result.Tau[j][k].Sub(sender.OutputAdditiveShares[j][k]) + result.Tau[j][k] = result.Tau[j][k].Add(input[j][k]) + } + } + return result, nil +} + +// Round3Transfer does the receiver (Bob)'s step 7) of Protocol 9, namely the computation of the outputs tB. +func (receiver *Receiver) Round3Transfer(round2Output *Round2Output) error { + for j := 0; j < L; j++ { + column := make([]byte, OtWidth*simplest.DigestSize) + shake := sha3.NewCShake256(receiver.uniqueSessionId[:], []byte("Coinbase_DKLs_cOT")) + jBytes := [2]byte{} + binary.BigEndian.PutUint16(jBytes[:], uint16(j)) + if _, err := shake.Write(jBytes[:]); err != nil { // write j into hash + return errors.Wrap(err, "writing nonce into shake while computing tB in cOT receiver round 3 transfer") + } + if _, err := shake.Write(receiver.psi[j][:]); err != nil { + return errors.Wrap(err, "writing input zeta_j into shake while computing tB in cOT receiver round 3 transfer") + } + if _, err := shake.Read(column[:]); err != nil { + return errors.Wrap(err, "reading shake into column while computing tB in cOT receiver round 3 transfer") + } + bit := int(simplest.ExtractBitFromByteVector(receiver.extendedPackedChoices[:], j)) + var err error + for k := 0; k < OtWidth; k++ { + receiver.OutputAdditiveShares[j][k], err = receiver.curve.Scalar.SetBytes(column[k*simplest.DigestSize : (k+1)*simplest.DigestSize]) + if err != nil { + return errors.Wrap(err, "scalar output additive shares from bytes") + } + receiver.OutputAdditiveShares[j][k] = receiver.OutputAdditiveShares[j][k].Neg() + wj0 := receiver.OutputAdditiveShares[j][k].Bytes() + wj1 := receiver.OutputAdditiveShares[j][k].Add(round2Output.Tau[j][k]).Bytes() + subtle.ConstantTimeCopy(bit, wj0, wj1) + if receiver.OutputAdditiveShares[j][k], err = receiver.curve.Scalar.SetBytes(wj0); err != nil { + return errors.Wrap(err, "scalar output additive shares from bytes") + } + } + } + return nil +} diff --git a/pkg/crypto/ot/extension/kos/kos_test.go b/pkg/crypto/ot/extension/kos/kos_test.go new file mode 100755 index 000000000..e277cf630 --- /dev/null +++ b/pkg/crypto/ot/extension/kos/kos_test.go @@ -0,0 +1,141 @@ +package kos + +import ( + "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/ottest" +) + +func TestBinaryMult(t *testing.T) { + for i := 0; i < 100; i++ { + temp := make([]byte, 32) + _, err := rand.Read(temp) + require.NoError(t, err) + expected := make([]byte, 32) + copy(expected, temp) + // this test is based on Fermat's little theorem. + // the multiplicative group of units of a finite field has order |F| - 1 + // (in fact, it's necessarily cyclic; see e.g. https://math.stackexchange.com/a/59911, but this test doesn't rely on that fact) + // thus raising any element to the |F|th power should yield that element itself. + // this is a good test because it relies on subtle facts about the field structure, and will fail if anything goes wrong. + for j := 0; j < 256; j++ { + expected = binaryFieldMul(expected, expected) + } + require.Equal(t, temp, expected) + } +} + +func TestCOTExtension(t *testing.T) { + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + uniqueSessionId := [simplest.DigestSize]byte{} + _, err := rand.Read(uniqueSessionId[:]) + require.NoError(t, err) + baseOtSenderOutput, baseOtReceiverOutput, err := ottest.RunSimplestOT(curve, Kappa, uniqueSessionId) + require.NoError(t, err) + for i := 0; i < Kappa; i++ { + require.Equal(t, baseOtReceiverOutput.OneTimePadDecryptionKey[i], baseOtSenderOutput.OneTimePadEncryptionKeys[i][baseOtReceiverOutput.RandomChoiceBits[i]]) + } + + sender := NewCOtSender(baseOtReceiverOutput, curve) + receiver := NewCOtReceiver(baseOtSenderOutput, curve) + choice := [COtBlockSizeBytes]byte{} // receiver's input, namely choice vector. just random + _, err = rand.Read(choice[:]) + require.NoError(t, err) + input := [L][OtWidth]curves.Scalar{} // sender's input, namely integer "sums" in case w_j == 1. + for i := 0; i < L; i++ { + for j := 0; j < OtWidth; j++ { + input[i][j] = curve.Scalar.Random(rand.Reader) + require.NoError(t, err) + } + } + firstMessage, err := receiver.Round1Initialize(uniqueSessionId, choice) + require.NoError(t, err) + responseTau, err := sender.Round2Transfer(uniqueSessionId, input, firstMessage) + require.NoError(t, err) + err = receiver.Round3Transfer(responseTau) + require.NoError(t, err) + for j := 0; j < L; j++ { + bit := simplest.ExtractBitFromByteVector(choice[:], j) == 1 + for k := 0; k < OtWidth; k++ { + temp := sender.OutputAdditiveShares[j][k].Add(receiver.OutputAdditiveShares[j][k]) + if bit { + require.Equal(t, temp, input[j][k]) + } else { + require.Equal(t, temp, curve.Scalar.Zero()) + } + } + } + } +} + +func TestCOTExtensionStreaming(t *testing.T) { + curve := curves.K256() + hashKeySeed := [simplest.DigestSize]byte{} + _, err := rand.Read(hashKeySeed[:]) + require.NoError(t, err) + baseOtReceiver, err := simplest.NewReceiver(curve, Kappa, hashKeySeed) + require.NoError(t, err) + sender := NewCOtSender(baseOtReceiver.Output, curve) + baseOtSender, err := simplest.NewSender(curve, Kappa, hashKeySeed) + require.NoError(t, err) + receiver := NewCOtReceiver(baseOtSender.Output, curve) + + // first run the seed OT + senderPipe, receiverPipe := simplest.NewPipeWrappers() + errorsChannel := make(chan error, 2) + go func() { + errorsChannel <- simplest.SenderStreamOTRun(baseOtSender, senderPipe) + }() + go func() { + errorsChannel <- simplest.ReceiverStreamOTRun(baseOtReceiver, receiverPipe) + }() + for i := 0; i < 2; i++ { + require.Nil(t, <-errorsChannel) + } + for i := 0; i < Kappa; i++ { + require.Equal(t, baseOtReceiver.Output.OneTimePadDecryptionKey[i], baseOtSender.Output.OneTimePadEncryptionKeys[i][baseOtReceiver.Output.RandomChoiceBits[i]]) + } + + // begin test of cOT extension. first populate both parties' inputs randomly + choice := [COtBlockSizeBytes]byte{} // receiver's input, namely choice vector. just random + _, err = rand.Read(choice[:]) + require.NoError(t, err) + input := [L][OtWidth]curves.Scalar{} // sender's input, namely integer "sums" in case w_j == 1. random for the test + for i := 0; i < L; i++ { + for j := 0; j < OtWidth; j++ { + input[i][j] = curve.Scalar.Random(rand.Reader) + require.NoError(t, err) + } + } + + // now actually run it, stream-wise + go func() { + errorsChannel <- SenderStreamCOtRun(sender, hashKeySeed, input, receiverPipe) + }() + go func() { + errorsChannel <- ReceiverStreamCOtRun(receiver, hashKeySeed, choice, senderPipe) + }() + for i := 0; i < 2; i++ { + require.Nil(t, <-errorsChannel) + } + for j := 0; j < L; j++ { + bit := simplest.ExtractBitFromByteVector(choice[:], j) == 1 + for k := 0; k < OtWidth; k++ { + temp := sender.OutputAdditiveShares[j][k].Add(receiver.OutputAdditiveShares[j][k]) + if bit { + require.Equal(t, temp, input[j][k]) + } else { + require.Equal(t, temp, curve.Scalar.Zero()) + } + } + } +} diff --git a/pkg/crypto/ot/extension/kos/stream.go b/pkg/crypto/ot/extension/kos/stream.go new file mode 100755 index 000000000..1f5ff4f2c --- /dev/null +++ b/pkg/crypto/ot/extension/kos/stream.go @@ -0,0 +1,57 @@ +package kos + +import ( + "encoding/gob" + "io" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" +) + +// ReceiverStreamCOtRun exposes an end-to-end "streaming" version of the cOT process for the receiver. +// this is similar to what we're also doing in the base OT side. the user only passes an arbitrary `ReadWriter` here, +// together with the relevant inputs (namely a choice vector); this method handles all parts of the process, +// including both encoding / decoding and writing to / reading from the stream. +func ReceiverStreamCOtRun(receiver *Receiver, hashKeySeed [simplest.DigestSize]byte, choice [COtBlockSizeBytes]byte, rw io.ReadWriter) error { + enc := gob.NewEncoder(rw) + dec := gob.NewDecoder(rw) + + firstMessage, err := receiver.Round1Initialize(hashKeySeed, choice) + if err != nil { + return errors.Wrap(err, "computing first message in receiver stream cOT") + } + if err = enc.Encode(firstMessage); err != nil { + return errors.Wrap(err, "encoding first message in receiver stream cOT") + } + responseTau := &Round2Output{} + if err = dec.Decode(responseTau); err != nil { + return errors.Wrap(err, "decoding responseTau in receiver stream OT") + } + if err = receiver.Round3Transfer(responseTau); err != nil { + return errors.Wrap(err, "error during round 3 in receiver stream OT") + } + return nil +} + +// SenderStreamCOtRun exposes the end-to-end "streaming" version of cOT for the sender. +// the sender should pass an arbitrary ReadWriter together with their input; this will handle the whole process, +// including all component methods, plus reading to and writing from the network. +func SenderStreamCOtRun(sender *Sender, hashKeySeed [simplest.DigestSize]byte, input [L][OtWidth]curves.Scalar, rw io.ReadWriter) error { + enc := gob.NewEncoder(rw) + dec := gob.NewDecoder(rw) + + firstMessage := &Round1Output{} + if err := dec.Decode(firstMessage); err != nil { + return errors.Wrap(err, "decoding first message in sender stream cOT") + } + responseTau, err := sender.Round2Transfer(hashKeySeed, input, firstMessage) + if err != nil { + return errors.Wrap(err, "error in round 2 in sender stream cOT") + } + if err = enc.Encode(responseTau); err != nil { + return errors.Wrap(err, "encoding responseTau in sender stream cOT") + } + return nil +} diff --git a/pkg/crypto/ot/ottest/util.go b/pkg/crypto/ot/ottest/util.go new file mode 100755 index 000000000..9a574226b --- /dev/null +++ b/pkg/crypto/ot/ottest/util.go @@ -0,0 +1,50 @@ +// Package ottest contains some utilities to test ot functions. The main goal is to reduce the code duplication in +// various other packages that need to run an OT in their test setup stage. +package ottest + +import ( + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" +) + +// RunSimplestOT is a utility function used _only_ during various tests. +// essentially, it encapsulates the entire process of running a base OT, so that other tests can use it / bootstrap themselves. +// it handles the creation of the base OT sender and receiver, as well as orchestrates the rounds on them; +// it returns their outsputs, so that others can use them. +func RunSimplestOT(curve *curves.Curve, batchSize int, uniqueSessionId [simplest.DigestSize]byte) (*simplest.SenderOutput, *simplest.ReceiverOutput, error) { + receiver, err := simplest.NewReceiver(curve, batchSize, uniqueSessionId) + if err != nil { + return nil, nil, errors.Wrap(err, "constructing OT receiver in run simplest OT") + } + sender, err := simplest.NewSender(curve, batchSize, uniqueSessionId) + if err != nil { + return nil, nil, errors.Wrap(err, "constructing OT sender in run simplest OT") + } + proof, err := sender.Round1ComputeAndZkpToPublicKey() + if err != nil { + return nil, nil, errors.Wrap(err, "sender round 1 in run simplest OT") + } + receiversMaskedChoice, err := receiver.Round2VerifySchnorrAndPadTransfer(proof) + if err != nil { + return nil, nil, errors.Wrap(err, "receiver round 2 in run simplest OT") + } + challenge, err := sender.Round3PadTransfer(receiversMaskedChoice) + if err != nil { + return nil, nil, errors.Wrap(err, "sender round 3 in run simplest OT") + } + challengeResponse, err := receiver.Round4RespondToChallenge(challenge) + if err != nil { + return nil, nil, errors.Wrap(err, "receiver round 4 in run simplest OT") + } + challengeOpenings, err := sender.Round5Verify(challengeResponse) + if err != nil { + return nil, nil, errors.Wrap(err, "sender round 5 in run simplest OT") + } + err = receiver.Round6Verify(challengeOpenings) + if err != nil { + return nil, nil, errors.Wrap(err, "receiver round 6 in run simplest OT") + } + return sender.Output, receiver.Output, nil +} diff --git a/pkg/crypto/paillier/README.md b/pkg/crypto/paillier/README.md new file mode 100755 index 000000000..f59761cf0 --- /dev/null +++ b/pkg/crypto/paillier/README.md @@ -0,0 +1,23 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## Paillier Cryptosystem + +Package paillier contains [Paillier's cryptosystem (1999)](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.112.4035&rep=rep1&type=pdf). +All routines here from pseudocode §2.5. Fig 1: The Paillier Cryptosystem. + +This module provides APIs for: + +- generating a safe key pair +- encryption and decryption +- adding two encrypted values, `Enc(a)` and `Enc(b)`, and obtaining `Enc(a + b)`, and +- multiplying a plain value, `a`, and an encrypted value `Enc(b)`, and obtaining `Enc(a * b)`. + +The encrypted values are represented as `big.Int` and are serializable. +This module also provides JSON serialization for the PublicKey and the SecretKey. diff --git a/pkg/crypto/paillier/paillier.go b/pkg/crypto/paillier/paillier.go new file mode 100755 index 000000000..b9ea50bbe --- /dev/null +++ b/pkg/crypto/paillier/paillier.go @@ -0,0 +1,376 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package paillier contains Paillier's cryptosystem (1999) [P99]. +// Public-Key Cryptosystems Based on Composite Degree Residuosity Class. +// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.112.4035&rep=rep1&type=pdf +// All routines here from pseudocode §2.5. Fig 1: The Paillier Cryptosystem. +// +// This module provides APIs for: +// +// - generating a safe keypair, +// - encryption and decryption, +// - adding two encrypted values, Enc(a) and Enc(b), and obtaining Enc(a + b), and +// - multiplying a plain value, a, and an encrypted value Enc(b), and obtaining Enc(a * b). +// +// The encrypted values are represented as big.Int and are serializable. This module also provides +// JSON serialization for the PublicKey and the SecretKey. +package paillier + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// PaillierPrimeBits is the number of bits used to generate Paillier Safe Primes. +const PaillierPrimeBits = 1024 + +type ( + // PublicKey is a Paillier public key: N = P*Q; for safe primes P,Q. + PublicKey struct { + N *big.Int // N = PQ + N2 *big.Int // N² computed and cached to prevent re-computation. + } + + // PublicKeyJson encapsulates the data that is serialized to JSON. + // It is used internally and not for external use. Public so other pieces + // can use for serialization. + PublicKeyJson struct { + N *big.Int + } + + // SecretKey is a Paillier secret key. + SecretKey struct { + PublicKey + Lambda *big.Int // lcm(P - 1, Q - 1) + Totient *big.Int // Euler's totient: (P - 1) * (Q - 1) + U *big.Int // L((N + 1)^λ(N) mod N²)−1 mod N + } + + // SecretKeyJson encapsulates the data that is serialized to JSON. + // It is used internally and not for external use. Public so other pieces + // can use for serialization. + SecretKeyJson struct { + N, Lambda, Totient, U *big.Int + } + + // Ciphertext in Pailler's cryptosystem: a value $c \in Z_{N²}$ . + Ciphertext *big.Int +) + +var two = big.NewInt(2) // The odd prime + +// NewKeys generates Paillier keys with `bits` sized safe primes. +func NewKeys() (*PublicKey, *SecretKey, error) { + return keyGenerator(core.GenerateSafePrime, PaillierPrimeBits) +} + +// keyGenerator generates Paillier keys with `bits` sized safe primes using function +// `genSafePrime` to generate the safe primes. +func keyGenerator(genSafePrime func(uint) (*big.Int, error), bits uint) (*PublicKey, *SecretKey, error) { + values := make(chan *big.Int, 2) + errors := make(chan error, 2) + + var p, q *big.Int + + for p == q { + for range []int{1, 2} { + go func() { + value, err := genSafePrime(bits) + values <- value + errors <- err + }() + } + + for _, err := range []error{<-errors, <-errors} { + if err != nil { + return nil, nil, err + } + } + + p, q = <-values, <-values + } + + // Assemble the secret/public key pair. + sk, err := NewSecretKey(p, q) + if err != nil { + return nil, nil, err + } + return &sk.PublicKey, sk, nil +} + +// NewSecretKey computes intermediate values based on safe primes p, q. +func NewSecretKey(p, q *big.Int) (*SecretKey, error) { + if p == nil || q == nil { + return nil, internal.ErrNilArguments + } + // Pre-compute necessary values. + pm1 := new(big.Int).Sub(p, core.One) // P - 1 + qm1 := new(big.Int).Sub(q, core.One) // Q - 1 + n := new(big.Int).Mul(p, q) // N = PQ + nn := new(big.Int).Mul(n, n) // N² + lambda, err := lcm(pm1, qm1) // λ(N) = lcm(P-1, Q-1) + if err != nil { + // Code coverage note: lcm returns error only if the inputs are nil, which can never happen here. + return nil, err + } + totient := new(big.Int).Mul(pm1, qm1) // 𝝋(N) = (P-1)(Q-1) + pk := PublicKey{ + N: n, + N2: nn, + } + + // (N+1)^λ(N) mod N² + t := new(big.Int).Add(n, core.One) + t.Exp(t, lambda, nn) + + // L((N+1)^λ(N) mod N²) + u, err := pk.l(t) + if err != nil { + return nil, err + } + // L((N+1)^λ(N) mod N²)^-1 mod N + u.ModInverse(u, n) + + return &SecretKey{pk, lambda, totient, u}, nil +} + +// MarshalJSON converts the public key into json format. +func (pk PublicKey) MarshalJSON() ([]byte, error) { + data := PublicKeyJson{pk.N} + return json.Marshal(data) +} + +// UnmarshalJSON converts the json data into this public key. +func (pk *PublicKey) UnmarshalJSON(bytes []byte) error { + data := new(PublicKeyJson) + if err := json.Unmarshal(bytes, data); err != nil { + return err + } + if data.N == nil { + return nil + } + pk.N = data.N + pk.N2 = new(big.Int).Mul(data.N, data.N) + return nil +} + +// lcm calculates the least common multiple. +func lcm(x, y *big.Int) (*big.Int, error) { + if x == nil || y == nil { + return nil, internal.ErrNilArguments + } + gcd := new(big.Int).GCD(nil, nil, x, y) + if core.ConstantTimeEq(gcd, core.Zero) { + return core.Zero, nil + } + // Compute least common multiple: https://en.wikipedia.org/wiki/Least_common_multiple#Calculation . + b := new(big.Int) + return b.Abs(b.Mul(b.Div(x, gcd), y)), nil +} + +// l computes a residuosity class of n^2: (x - 1) / n. +// Where it is the quotient x - 1 divided by n not modular multiplication of x - 1 times +// the modular multiplicative inverse of n. The function name comes from [P99]. +func (pk *PublicKey) l(x *big.Int) (*big.Int, error) { + if x == nil { + return nil, internal.ErrNilArguments + } + + if core.ConstantTimeEq(pk.N, core.Zero) { + return nil, internal.ErrNCannotBeZero + } + + // Ensure x = 1 mod N + if !core.ConstantTimeEq(new(big.Int).Mod(x, pk.N), core.One) { + return nil, internal.ErrResidueOne + } + + // Ensure x ∈ Z_N² + if err := core.In(x, pk.N2); err != nil { + return nil, err + } + + // (x - 1) / n + b := new(big.Int).Sub(x, core.One) + return b.Div(b, pk.N), nil +} + +// NewPubkey initializes a Paillier public key with a given n. +func NewPubkey(n *big.Int) (*PublicKey, error) { + if n == nil { + return nil, errors.New("n cannot be nil") + } + return &PublicKey{ + N: n, + N2: new(big.Int).Mul(n, n), // Compute and cache N² + }, nil +} + +// Add combines two Paillier ciphertexts. +func (pk *PublicKey) Add(c, d Ciphertext) (Ciphertext, error) { + if c == nil || d == nil { + return nil, internal.ErrNilArguments + } + // Ensure c,d ∈ Z_N² + cErr := core.In(c, pk.N2) + dErr := core.In(d, pk.N2) + // Constant time error check + var err error + if cErr != nil { + err = cErr + } + if dErr != nil { + err = dErr + } + if err != nil { + return nil, err + } + + ctxt, err := core.Mul(c, d, pk.N2) + if err != nil { + // Code coverage note: core.Mul returns error only if the inputs are nil, which can never happen here. + return nil, err + } + return ctxt, nil +} + +// Mul is equivalent to adding two Paillier exponents. +func (pk *PublicKey) Mul(a *big.Int, c Ciphertext) (Ciphertext, error) { + if a == nil || c == nil { + return nil, internal.ErrNilArguments + } + + // Ensure a ∈ Z_N + aErr := core.In(a, pk.N) + // Ensure c ∈ Z_N² + cErr := core.In(c, pk.N2) + + var err error + + // Constant time error check + if aErr != nil { + err = aErr + } + if cErr != nil { + err = cErr + } + if err != nil { + return nil, err + } + return new(big.Int).Exp(c, a, pk.N2), nil +} + +// Encrypt produces a ciphertext on input message. +func (pk *PublicKey) Encrypt(msg *big.Int) (Ciphertext, *big.Int, error) { + // generate a nonce: r \in Z**_N + r, err := core.Rand(pk.N) + if err != nil { + return nil, nil, err + } + + // Generate and return the ciphertext + ct, err := pk.encrypt(msg, r) + return ct, r, err +} + +// encrypt produces a ciphertext on input a message and nonce. +func (pk *PublicKey) encrypt(msg, r *big.Int) (Ciphertext, error) { + if msg == nil || r == nil { + return nil, internal.ErrNilArguments + } + + // Ensure msg ∈ Z_N + if err := core.In(msg, pk.N); err != nil { + return nil, err + } + + // Ensure r ∈ Z^*_N: we use the method proved in docs/[EL20] + // ensure r ∈ Z^_N-{0} + if err := core.In(r, pk.N); err != nil { + return nil, err + } + if core.ConstantTimeEq(r, core.Zero) { + return nil, fmt.Errorf("r cannot be 0") + } + + // Compute the ciphertext components: ɑ, β + // ɑ = (N+1)^m (mod N²) + ɑ := new(big.Int).Add(pk.N, core.One) + ɑ.Exp(ɑ, msg, pk.N2) + β := new(big.Int).Exp(r, pk.N, pk.N2) // β = r^N (mod N²) + + // ciphertext = ɑ*β = (N+1)^m * r^N (mod N²) + c, err := core.Mul(ɑ, β, pk.N2) + if err != nil { + // Code coverage note: core.Mul returns error only if the inputs are nil, which can never happen here. + return nil, err + } + return c, nil +} + +// Decrypt is the reverse operation of Encrypt. +func (sk *SecretKey) Decrypt(c Ciphertext) (*big.Int, error) { + if c == nil { + return nil, internal.ErrNilArguments + } + + // Ensure C ∈ Z_N² + if err := core.In(c, sk.N2); err != nil { + return nil, err + } + + // Compute the msg in components + // ɑ ≡ c^{λ(N)} mod N² + ɑ := new(big.Int).Exp(c, sk.Lambda, sk.N2) + + // l = L(ɑ, N) + ell, err := sk.l(ɑ) + if err != nil { + return nil, err + } + + // Compute the msg + // m ≡ lu = L(ɑ)*u = L(c^{λ(N)})*u mod N + m, err := core.Mul(ell, sk.U, sk.N) + if err != nil { + return nil, err + } + return m, nil +} + +// MarshalJSON converts the secret key into json format. +func (sk SecretKey) MarshalJSON() ([]byte, error) { + data := SecretKeyJson{ + sk.N, + sk.Lambda, + sk.Totient, + sk.U, + } + return json.Marshal(data) +} + +// UnmarshalJSON converts the json data into this secret key. +func (sk *SecretKey) UnmarshalJSON(bytes []byte) error { + data := new(SecretKeyJson) + if err := json.Unmarshal(bytes, data); err != nil { + return err + } + if data.N != nil { + sk.N = data.N + sk.N2 = new(big.Int).Mul(data.N, data.N) + } + sk.U = data.U + sk.Totient = data.Totient + sk.Lambda = data.Lambda + return nil +} diff --git a/pkg/crypto/paillier/psf.go b/pkg/crypto/paillier/psf.go new file mode 100755 index 000000000..ca89d041a --- /dev/null +++ b/pkg/crypto/paillier/psf.go @@ -0,0 +1,222 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// +// This file contains proofs that Paillier moduli are square-free: [spec] fig 15 + +package paillier + +import ( + "crypto/elliptic" + "fmt" + "math/big" + + crypto "github.com/onsonr/sonr/pkg/crypto/core" + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// [spec] 10.2 and ProvePSF, VerifyPSF fig.15 +const PsfProofLength = 13 + +// PsfProofParams contains the inputs to ProvePSF +type PsfProofParams struct { + Curve elliptic.Curve + SecretKey *SecretKey + Pi uint32 + Y *curves.EcPoint +} + +// PsfVerifyParams contains the inputs to VerifyPSF +type PsfVerifyParams struct { + Curve elliptic.Curve + PublicKey *PublicKey + Pi uint32 + Y *curves.EcPoint +} + +// PsfProof is a slice of 13 big.Int's that prove that a Paillier modulus is square-free +type PsfProof []*big.Int + +// Prove that a Paillier modulus is square-free +// [spec] §10.fig 15 +func (p *PsfProofParams) Prove() (PsfProof, error) { + // Verify that params are sane + if p.Curve == nil || + p.SecretKey == nil || + p.Pi == 0 || + p.Y == nil { + return nil, internal.ErrNilArguments + } + + // 1. ell = 13 + // Note this is set above as PsfProofLength + + // 2. M = N^{-1} mod \phi(N) + M, err := crypto.Inv(p.SecretKey.N, p.SecretKey.Totient) + if err != nil { + return nil, err + } + + // 3. [x_1, ..., x_ell] <- GenerateChallenges(g,q,y,Pi,ell) + // NOTE: spec doesn't include N, but it's an oversight--should be part of the + // commitment + x, err := generateChallenges(p.Curve.Params(), p.SecretKey.N, p.Pi, p.Y) + if err != nil { + return nil, err + } + if len(x) != PsfProofLength { + return nil, fmt.Errorf("Challenges array is not correct length: want=%v got=%v", PsfProofLength, len(x)) + } + + // 4. For i = [1, ... \ell] + // NOTE: typo in spec: says j = ... but uses subscript i in loop + proof := make([]*big.Int, PsfProofLength) + for i, xj := range x { + // 5. Compute y_i = x_i^M mod N + // NOTE: the pseudocode shows mod phi(N) which is incorrect + // it should be mod N otherwise the reverse in Verify + // will fail. Using phi(N) puts M in the wrong group. + yi, err := crypto.Exp(xj, M, p.SecretKey.N) + if err != nil { + return nil, err + } + + // 6. Set \Pi = [y_1, ..., y_\ell] + // NOTE: typo in spec: says y_t not y_\ell + proof[i] = yi + } + + // 7. return \Pi + return proof, nil +} + +// Verify that a Paillier modulus is square-free +// [spec] §10.fig 15 +func (p PsfProof) Verify(psf *PsfVerifyParams) error { + // Verify that params are sane + if psf == nil || + psf.Curve == nil || + psf.PublicKey == nil || + psf.Pi == 0 || + psf.Y == nil { + return internal.ErrNilArguments + } + + // 1. ell = 13 + // Note this is set above as PsfProofLength + + // 2. t = 1000 + // NOTE not used anywhere + + // 3. if q|N return false + if new(big.Int).Mod(psf.PublicKey.N, psf.Curve.Params().N).Cmp(crypto.Zero) == 0 { + return fmt.Errorf("paillier public key is a multiple of the curve subgroup") + } + + // 4. [x_1, ..., x_ell] <- GenerateChallenges(g,q,y,Pi,ell) + // NOTE: spec doesn't include N, but it's an oversight--should be part of the + // commitment + x, err := generateChallenges(psf.Curve.Params(), psf.PublicKey.N, psf.Pi, psf.Y) + if err != nil { + return err + } + if len(x) != PsfProofLength { + return fmt.Errorf("challenges array is not correct length: want=%v got=%v", PsfProofLength, len(x)) + } + + // 5. for j in [1,...,l] + for j, xj := range x { + // 6. yj^N != x mod N return false + // NOTE: pseudocode uses i when loop uses j + lhs, err := crypto.Exp(p[j], psf.PublicKey.N, psf.PublicKey.N) + if err != nil { + return err + } + if lhs.Cmp(xj) != 0 { + return fmt.Errorf("not equal at %d", j) + } + } + + return nil +} + +// generateChallenges computes `l` deterministic numbers as +// challenges for PsfProof which proves that the Paillier modulus is square free +// [spec] fig.15 GenerateChallenges +func generateChallenges(params *elliptic.CurveParams, N *big.Int, pi uint32, y *curves.EcPoint) ([]*big.Int, error) { + if params == nil || + y == nil || + pi == 0 { + return nil, internal.ErrNilArguments + } + + // 1. Set b = |N| // bit length of N + b := N.BitLen() + + // a modulus that is too small turns this function into an infinite loop + // need at least a byte to guarantee termination + if b < 8 { + return nil, internal.ErrNilArguments + } + + // 2. h = output bit-length of fiat-shamir hash + // See util.fiatShamir which uses sha256 + // So the output bit-length is 256 bits + const h int = 256 + + // 3. Compute s = ⌈b/h⌉ // number of hash outputs required to obtain b bits + // i.e. the number of times we have to call fs-shamir to get the same bits as + // `b`. Compute ceil as ceilVal = (a+b-1) / b + s := int64((b + h - 1) / h) + + // 4. j = 0 + j := int64(0) + + // 5. m = 0 + m := big.NewInt(0) + + x := make([]*big.Int, PsfProofLength) + + Pi := new(big.Int).SetUint64(uint64(pi)) + // 6. while j ≤ l + for j < PsfProofLength { + + bij := big.NewInt(j) + var ej []byte + + // 7. for k = [1,...,s] + for k := int64(1); k <= s; k++ { + bik := big.NewInt(k) + + // 8. Compute e_jk = FS-HASH(g, q, y, p_i, j, k, m) + res, err := crypto.FiatShamir(params.Gx, params.Gy, params.N, y.X, y.Y, Pi, bij, bik, m) + if err != nil { + return nil, err + } + // 9. Set x_j = eJ1 || ... || eJs + // Pseudocode says to concatenate outside this loop + // however, we just concatenate the bytes now instead of storing as temporary + // variables + ej = append(ej, res...) + } + // 10. Truncate ej to b bits + xj := new(big.Int).SetBytes(ej[:b/8]) + + // 11. if x_j < Z_N* i.e. 0 < x_j and x_j < N + if xj.Cmp(crypto.Zero) == 1 && xj.Cmp(N) == -1 { + x[j] = xj + + // 12 j = j + 1 + j++ + // 13 m = 0 + m = big.NewInt(0) + // 14 else + } else { + // 15. Set m = m + 1 + m.Add(m, crypto.One) + } + } + return x, nil +} diff --git a/pkg/crypto/paillier/psf_test.go b/pkg/crypto/paillier/psf_test.go new file mode 100755 index 000000000..f2f062d95 --- /dev/null +++ b/pkg/crypto/paillier/psf_test.go @@ -0,0 +1,303 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package paillier + +import ( + "crypto/elliptic" + "encoding/json" + "math/big" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" + + crypto "github.com/onsonr/sonr/pkg/crypto/core" + curves2 "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var testPrimes = []*big.Int{ + internal.B10("186141419611617071752010179586510154515933389116254425631491755419216243670159714804545944298892950871169229878325987039840135057969555324774918895952900547869933648175107076399993833724447909579697857041081987997463765989497319509683575289675966710007879762972723174353568113668226442698275449371212397561567"), + internal.B10("94210786053667323206442523040419729883258172350738703980637961803118626748668924192069593010365236618255120977661397310932923345291377692570649198560048403943687994859423283474169530971418656709749020402756179383990602363122039939937953514870699284906666247063852187255623958659551404494107714695311474384687"), + internal.B10("130291226847076770981564372061529572170236135412763130013877155698259035960569046218348763182598589633420963942796327547969527085797839549642610021986391589746295634536750785366034581957858065740296991986002552598751827526181747791647357767502200771965093659353354985289411489453223546075843993686648576029043"), + internal.B10("172938910323633442195852028319756134734590277522945546987913328782597284762767185925315797321999389252040294991952361905020940252121762387957669654615602135429944435719699091344247805645764550860505536884031064967454028383404046221898300153428182409080298694828920944094158777327533157774919783417586902830043"), + internal.B10("135841191929788643010555393808775051922265083622266098277752143441294911675705272940799534437169053045878247274810449617960047255023823301284034559807472662111224710158898548617194658983006262996831617082584649612602010680423107108651221824216065228161009680618243402116924511141821829055830713600437589058643"), + internal.B10("179677777376220950493907657233669314916823596507009854134559513388779535023958212632715646194917807302098015450071151245496651913873851032302340489007561121851068326577148680474495447007833318066335149850926605897908761267606415610900931306044455332084757793630487163583451178807470499389106913845684353833379"), + internal.B10("62649985409697862206708027961094957171873130708493280862148817115812710388878279240372941307490519941098268192630359164091992515623574326498710952492586770923230983753287493884398990474917756375654842939939940915963324175552421981212594421823752854754541693709434365609636589761589816398869727328798680335583"), + internal.B10("196576931859098680370388202020086631604584490828609819764890020064880575503817891126703473215983239396058738287255240835101797315137072822716923594188151190460588551553676484461393180135097616711975997391550414447010491794087888246885960280296709672609456539741162207414899687167396008233995214434586323322859"), + internal.B10("271336420864746369701165973306090650688066226258594853124089876839120277465060891854507381090238664515950686049792387028144049076707224579184820539700879884119579186284072404459682082855184644444282438298561112002507411996589407330801765394106772460665497195944412067027079123717579308322520985921886949051399"), + internal.B10("147653127360336844448178027222853805809444645720500374788954343695331927468524513989671450440433430392339037667457657655958027740671071573403925974795764987870476118984896439440386146680643457835633462311776946902713168513155240275028008685964121441954481847113848701823211862974120297600518927026940189810103"), + internal.B10("61539010433774119199101441060312213379096965116494840834113311373246794436251480454630309900106802555812462300777026043563820643373439814989443964169335227347638731691284339678436222951965582264570176875078394338903074717434072995072121221264531723385013005031614327462206339323414428493321384497439106152163"), + internal.B10("311771090987243597109711542316907830756641693311804000593662622484722315782429237915515708860530841821213561483232298821623675096481796856960171671330638042763441430256097782130268494276848432981045602236986861083392706904041234926428759947857376161689191720483868111001987710383245853931937989224732484206639"), + internal.B10("348545239501897032367950520763624245702184225360238826931782856428685149253861325854706825698843098817604431561258712026020688621010635185480321876001016614912927680387840531641703966894322797491484955817022624047355473480912508041252361257911175397626575812830091471419378132244146077774966527307225203863239"), + internal.B10("167562983031509383478485987630533113343120902430985961468758712448125734458812918541051012669749885569679178971612428577288632429606851871845164719448590160530844833425628143996971699662729056519326776907622035340086832629206691942750594912221135787534670122007438859975313187460872690748138136170080913902203"), + internal.B10("151715609132228776595716500435665208768897792993205818803431003524953811539898459230192282642811956896879836518212758893685104146944932088195466999437630114129887975508715417094019351746027667352287673763064246395392591213231796089814648654152625331299642171758052545451706130433176935280325874961374276589763"), + internal.B10("281712498774102170277967098381151873986368736986748325672760355775943894718315925237789122870763991635031524237638254080973752419302437870447849091185409669906909828874532209010547976564209374430136988588219470076527433259993640332285914706329187116209118972038509278879237122949265824264856530096167843589043"), + internal.B10("86882427063713590116032012033991745733440719961931885774819345297872782432110706546175706398857226544896860987721577779470479838062106788873559026307646871133570915480684987993282364698928926188640576189281202695899665555602891606955025957497645420156315890379148794822782242384167644977894987285630058930123"), + internal.B10("83303406464212917441403726886711948278716398972782717472384580707071541544369912289531948826578557956123897261910116726555850408667234850301141318443154703778225305104540324875867615851047711871915209458107086347063530255813116254895432804373554367035028329996279513893337862177371103671113527972705508417219"), + internal.B10("290829612093510969863838578444630131194824970528125429399090307997156531200557462531776190769158191441614466855963164356672434851525764502180873524299787560160992955274777477308009367164212073773611071813219472273292916120276721541591451163160398750751633065097434700462944540404208636130411713202759646572187"), + internal.B10("48881643615473281990659967689574873112454227417010573158578046287415357392674453353386274403945930212163960526780980360358370255117866064326375672959460785974850231208253282115124348836379470403659096433419030132737534978624170609788431758477453270578400762995584298785082853409573009591146163658067217132999"), + internal.B10("47818664065019136841944639898604168570191742429107462510943153778085167306149797958497736138014922106778177497683417470713996340979203175236987691632152128071256018368891463388744514315997309312144264057334961479235114340091423812710466596081259537323405527816634204224641066174554915788023121121924554823463"), + internal.B10("229695065817346126758526483359337260282925372883465036895664320607569899180246065431164369223444026964554195802821338287119074827091354255558249504915527499047398698041873875019622138440848556549357174461846992529556315682586788137744896985847052668283284231628825924370859640129811142861116994552829398428647"), + internal.B10("100501115016957347491693508757253443864758446032047524096020585354104983606736759639044367167134409576092528219013168507381959241052976704837620234061351712684500077849808223040972825725745511581504906610633548112115513604053190610668096089811015493012026572475283305559529666099836493252485826156659750294903"), + internal.B10("164941338210872461448879529698900150056451305424623398039343691654768566536491493438826728710972441042226712374570117138883019423322602098706113298908005378303473844839971995715847918643285222217768344335264383514921181158565529236124115589719970140511822410990649549555047928093673140752570788415674868532299"), + internal.B10("277037199251333188171108034082127252450960810846571117481542098050121457972964006392527344163695411986229107011168411232117984760439307440561490229321182283823299859836750264962218540927582605520434969388646847458788766216835350519741512353041653865564337457599778511921159510170311560556844284028160928114623"), + internal.B10("194450633495795999995837828580097111229016136925345956148788562473415774074431957758705067019578300241653926511426134047652491974620284426575921711048247821582093564387999309993254763749991516361193554847964638949731507356038181346481870018202492098453036116472375750355687853028597643560794156133662678349939"), + internal.B10("351287943170075259292767465687447861777186026969543801283411356809391771346213158326614410370157474105344692424346410925411240089238093158848815209147605381454294661108047095253146499393310219242924552687094316959878415907497273176683394122976929775532753961555304244867490393116346360677109958055297215711587"), + internal.B10("329970582937843908299463472795994928703202360293919677760100619380642134736439176597341134222679061949935544692834943628667398294307004076774417457697130314341974849843695836050603685013468031012892094273233016929045028941716224648802422408386216033754532303003405690778077639489173685122357063674177077611499"), + internal.B10("67751546105580063387575764356375682499165422473383503143930633584920975946879807021875353514236996076344028719391905234977223693643926924731304657199486141030504275775023186923364159168130612275534168246529309247449138607249407760246378829338068736888203134857601657561860157938495777271164458736576560502603"), + internal.B10("276043923868350639738966705196129285523536747369492013710841410915407411458158268634302674024358477700030814139419613881758439643092328709376796555454484423864587139181985503560495790018232370315219082876142282958894264284344738294415199758590186234114829175455336589153989920707778566032047921277945163061363"), + internal.B10("62028909880050184794454820320289487394141550306616974968340908736543032782344593292214952852576535830823991093496498970213686040280098908204236051130358424961175634703281821899530101130244725435470475135483879784963475148975313832483400747421265545413510460046067002322131902159892876739088034507063542087523"), + internal.B10("321804071508183671133831207712462079740282619152225438240259877528712344129467977098976100894625335474509551113902455258582802291330071887726188174124352664849954838358973904505681968878957681630941310372231688127901147200937955329324769631743029415035218057960201863908173045670622969475867077447909836936523"), + internal.B10("52495647838749571441531580865340679598533348873590977282663145916368795913408897399822291638579504238082829052094508345857857144973446573810004060341650816108578548997792700057865473467391946766537119012441105169305106247003867011741811274367120479722991749924616247396514197345075177297436299446651331187067"), + internal.B10("118753381771703394804894143450628876988609300829627946826004421079000316402854210786451078221445575185505001470635997217855372731401976507648597119694813440063429052266569380936671291883364036649087788968029662592370202444662489071262833666489940296758935970249316300642591963940296755031586580445184253416139"), +} + +func TestGenerateChallengesWorks(t *testing.T) { + curves := []elliptic.Curve{btcec.S256(), elliptic.P256()} + for _, curve := range curves { + // dummy secret based on curve + y, _ := curves2.NewScalarBaseMult(curve, big.NewInt(3)) + + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + // Compute N from test primes + skN := new(big.Int).Mul(testPrimes[i], testPrimes[j]) + x, err := generateChallenges(curve.Params(), skN, uint32(i+1), y) + + require.NoError(t, err) + for _, xj := range x { + require.NotNil(t, xj) + require.Greater(t, xj.Cmp(crypto.Zero), 0) + require.Equal(t, xj.Cmp(skN), -1) + } + } + } + } +} + +// tests whether the hash function can still produce valid challenges +// even when the modulus is smaller than the hash output +func TestGenerateChallengesPrimeN(t *testing.T) { + curves := []elliptic.Curve{btcec.S256(), elliptic.P256()} + n := []*big.Int{ + internal.B10("680564733841876926926749214863536724007"), + internal.B10("1234345830644315716128223123383371693999"), + internal.B10("358070498390900219760227294443948492156530525739357363711230524749453568134007"), + internal.B10("409819537231165473932776844223512813127760876374228481246566335070809195677439"), + internal.B10("336327054820888403283842064345570507895192245801107954728200717775133442039527"), + internal.B10("353526063197730551176241127281213353808518592628930654494044427064787696719527"), + } + + for _, curve := range curves { + // dummy secret based on curve + y, _ := curves2.NewScalarBaseMult(curve, big.NewInt(3)) + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + x, err := generateChallenges(curve.Params(), n[i], uint32(j+1), y) + + require.NoError(t, err) + for _, xj := range x { + require.NotNil(t, xj) + require.Greater(t, xj.Cmp(crypto.Zero), 0) + } + } + } + } +} + +func TestGenerateChallengesNilInputs(t *testing.T) { + y, _ := curves2.NewScalarBaseMult(elliptic.P256(), big.NewInt(1)) + + _, err := generateChallenges(nil, nil, 0, nil) + require.Error(t, err) + _, err = generateChallenges(elliptic.P256().Params(), nil, 0, nil) + require.Error(t, err) + _, err = generateChallenges(elliptic.P256().Params(), big.NewInt(0), 0, nil) + require.Error(t, err) + _, err = generateChallenges(elliptic.P256().Params(), big.NewInt(1), 1, nil) + require.Error(t, err) + _, err = generateChallenges(elliptic.P256().Params(), big.NewInt(1), 1, y) + require.Error(t, err) + _, err = generateChallenges(elliptic.P256().Params(), big.NewInt(1), 1, y) + require.Error(t, err) + _, err = generateChallenges(elliptic.P256().Params(), big.NewInt(255), 1, y) + require.NoError(t, err) +} + +func TestPsfProofParams_Prove(t *testing.T) { + // RSA primes for testing + sk, _ := NewSecretKey( + // 75-digit random primes from Wolfram-Alpha + internal.B10("110045198697022997120409435651962875820936327127306040565577217116705932648687"), + internal.B10("95848033199746534486927143950536999279071340697368502822602282152563330640779")) + smallSk, _ := NewSecretKey(big.NewInt(13), big.NewInt(11)) + + // Some points for testing + k := internal.B10("270988338908697209412444309907441365656383309727758604622908325428179708750") + Qp256, _ := curves2.NewScalarBaseMult(elliptic.P256(), k) + Qs256, _ := curves2.NewScalarBaseMult(btcec.S256(), k) + pi := uint32(4) + + tests := []struct { + name string + in *PsfProofParams + expectedError error + expectedResultLen int + }{ + // Positive tests + { + "positive: p256, small numbers", + &PsfProofParams{elliptic.P256(), smallSk, 1001, Qp256}, + nil, + PsfProofLength, + }, + { + "positive: p256, large numbers", + &PsfProofParams{elliptic.P256(), sk, pi, Qp256}, + nil, + PsfProofLength, + }, + { + "positive: s256, large numbers", + &PsfProofParams{btcec.S256(), sk, pi, Qs256}, + nil, + PsfProofLength, + }, + + // Nil params + { + "negative: ", + &PsfProofParams{ + btcec.S256(), + sk, + pi, + Qs256, + }, + nil, + PsfProofLength, + }, + { + "negative: proof params are nil", + &PsfProofParams{ + nil, + sk, + pi, + Qs256, + }, + internal.ErrNilArguments, + 0, + }, + { + "negative: SecretKey is nil", + &PsfProofParams{ + btcec.S256(), + nil, + pi, + Qs256, + }, + internal.ErrNilArguments, + 0, + }, + { + "negative: y is nil", + &PsfProofParams{ + btcec.S256(), + sk, + 0, + Qs256, + }, + internal.ErrNilArguments, + 0, + }, + { + "negative: Pi is nil", + &PsfProofParams{ + btcec.S256(), + sk, + pi, + nil, + }, + internal.ErrNilArguments, + 0, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // test + result, err := test.in.Prove() + + // Verify the results are as expected + require.Equal(t, test.expectedError, err) + require.Len(t, result, test.expectedResultLen) + }) + } +} + +// Test that Range2Proof can be marshaled and unmarshaled correctly +func TestPsfProof_MarshalJSON(t *testing.T) { + // Generate some proof + sk, _ := NewSecretKey( + internal.B10("110045198697022997120409435651962875820936327127306040565577217116705932648687"), + internal.B10("95848033199746534486927143950536999279071340697368502822602282152563330640779")) + Q, _ := curves2.NewScalarBaseMult(elliptic.P256(), + internal.B10("270988338908697209412444309907441365656383309727758604622908325428179708750")) + params := &PsfProofParams{ + elliptic.P256(), sk, + 1, + Q, + } + proof, err := params.Prove() + require.NoError(t, err) + require.NotNil(t, proof) + + // Marshal + testJSON, err := json.Marshal(proof) + require.NoError(t, err) + require.NotNil(t, testJSON) + + var unmarshaled PsfProof + err = json.Unmarshal(testJSON, &unmarshaled) + require.NoError(t, err) + + // Test for equality + require.Len(t, ([]*big.Int)(unmarshaled), len(([]*big.Int)(proof))) + for i := range proof { + require.Equal(t, proof[i], unmarshaled[i]) + } +} + +// Tests for Verify +// prove/verify round trip works +// modifying any parameter causes verify to fail +func TestPsfProofWorks(t *testing.T) { + // RSA primes for testing + sk, _ := NewSecretKey( + // 75-digit random primes from Wolfram-Alpha + internal.B10("110045198697022997120409435651962875820936327127306040565577217116705932648687"), + internal.B10("95848033199746534486927143950536999279071340697368502822602282152563330640779")) + + // Some points for testing + k := internal.B10("270988338908697209412444309907441365656383309727758604622908325428179708750") + Qp256, _ := curves2.NewScalarBaseMult(elliptic.P256(), k) + pi := uint32(2) + + proveParams := &PsfProofParams{ + Curve: elliptic.P256(), + SecretKey: sk, + Pi: pi, + Y: Qp256, + } + proof, _ := proveParams.Prove() + verifyParams := &PsfVerifyParams{ + Curve: elliptic.P256(), + PublicKey: &sk.PublicKey, + Pi: pi, + Y: Qp256, + } + require.NoError(t, proof.Verify(verifyParams)) +} diff --git a/pkg/crypto/sharing/README.md b/pkg/crypto/sharing/README.md new file mode 100755 index 000000000..03874fdd4 --- /dev/null +++ b/pkg/crypto/sharing/README.md @@ -0,0 +1,16 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## Shamir Secret Sharing Scheme + +The code is an implementation of the following papers. + +- +- ~gasarch/TOPICS/secretsharing/feldmanVSS.pdf +- diff --git a/pkg/crypto/sharing/ed25519_feldman_test.go b/pkg/crypto/sharing/ed25519_feldman_test.go new file mode 100755 index 000000000..ddecf4075 --- /dev/null +++ b/pkg/crypto/sharing/ed25519_feldman_test.go @@ -0,0 +1,132 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sharing + +import ( + crand "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +var testCurve = curves.ED25519() + +func TestEd25519FeldmanSplitInvalidArgs(t *testing.T) { + _, err := NewFeldman(0, 0, testCurve) + require.NotNil(t, err) + _, err = NewFeldman(3, 2, testCurve) + require.NotNil(t, err) + _, err = NewFeldman(1, 10, testCurve) + require.NotNil(t, err) + scheme, err := NewFeldman(2, 3, testCurve) + require.Nil(t, err) + require.NotNil(t, scheme) + _, _, err = scheme.Split(testCurve.NewScalar(), crand.Reader) + require.NotNil(t, err) +} + +func TestEd25519FeldmanCombineNoShares(t *testing.T) { + scheme, err := NewFeldman(2, 3, testCurve) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestEd25519FeldmanCombineDuplicateShare(t *testing.T) { + scheme, err := NewFeldman(2, 3, testCurve) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Id: 1, + Value: testCurve.Scalar.New(3).Bytes(), + }, + { + Id: 1, + Value: testCurve.Scalar.New(3).Bytes(), + }, + }...) + require.NotNil(t, err) +} + +func TestEd25519FeldmanCombineBadIdentifier(t *testing.T) { + scheme, err := NewFeldman(2, 3, testCurve) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Id: 0, + Value: testCurve.Scalar.New(3).Bytes(), + }, + { + Id: 2, + Value: testCurve.Scalar.New(3).Bytes(), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Id: 4, + Value: testCurve.Scalar.New(3).Bytes(), + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) +} + +func TestEd25519FeldmanCombineSingle(t *testing.T) { + scheme, err := NewFeldman(2, 3, testCurve) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := testCurve.Scalar.Hash([]byte("test")) + verifiers, shares, err := scheme.Split(secret, crand.Reader) + require.Nil(t, err) + require.NotNil(t, shares) + for _, s := range shares { + err = verifiers.Verify(s) + require.Nil(t, err) + } + secret2, err := scheme.Combine(shares...) + require.Nil(t, err) + require.Equal(t, secret2, secret) +} + +func TestEd25519FeldmanAllCombinations(t *testing.T) { + scheme, err := NewFeldman(3, 5, testCurve) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := testCurve.Scalar.Hash([]byte("test")) + verifiers, shares, err := scheme.Split(secret, crand.Reader) + for _, s := range shares { + err = verifiers.Verify(s) + require.Nil(t, err) + } + require.Nil(t, err) + require.NotNil(t, shares) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(shares[i], shares[j], shares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + } + } + } +} diff --git a/pkg/crypto/sharing/feldman.go b/pkg/crypto/sharing/feldman.go new file mode 100755 index 000000000..51940e040 --- /dev/null +++ b/pkg/crypto/sharing/feldman.go @@ -0,0 +1,112 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sharing + +import ( + "fmt" + "io" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type FeldmanVerifier struct { + Commitments []curves.Point +} + +func (v FeldmanVerifier) Verify(share *ShamirShare) error { + curve := curves.GetCurveByName(v.Commitments[0].CurveName()) + err := share.Validate(curve) + if err != nil { + return err + } + x := curve.Scalar.New(int(share.Id)) + i := curve.Scalar.One() + rhs := v.Commitments[0] + + for j := 1; j < len(v.Commitments); j++ { + i = i.Mul(x) + rhs = rhs.Add(v.Commitments[j].Mul(i)) + } + sc, _ := curve.Scalar.SetBytes(share.Value) + lhs := v.Commitments[0].Generator().Mul(sc) + + if lhs.Equal(rhs) { + return nil + } else { + return fmt.Errorf("not equal") + } +} + +type Feldman struct { + Threshold, Limit uint32 + Curve *curves.Curve +} + +func NewFeldman(threshold, limit uint32, curve *curves.Curve) (*Feldman, error) { + if limit < threshold { + return nil, fmt.Errorf("limit cannot be less than threshold") + } + if threshold < 2 { + return nil, fmt.Errorf("threshold cannot be less than 2") + } + if limit > 255 { + return nil, fmt.Errorf("cannot exceed 255 shares") + } + if curve == nil { + return nil, fmt.Errorf("invalid curve") + } + return &Feldman{threshold, limit, curve}, nil +} + +func (f Feldman) Split(secret curves.Scalar, reader io.Reader) (*FeldmanVerifier, []*ShamirShare, error) { + if secret.IsZero() { + return nil, nil, fmt.Errorf("invalid secret") + } + shamir := &Shamir{ + threshold: f.Threshold, + limit: f.Limit, + curve: f.Curve, + } + shares, poly := shamir.getPolyAndShares(secret, reader) + verifier := new(FeldmanVerifier) + verifier.Commitments = make([]curves.Point, f.Threshold) + for i := range verifier.Commitments { + verifier.Commitments[i] = f.Curve.ScalarBaseMult(poly.Coefficients[i]) + } + return verifier, shares, nil +} + +func (f Feldman) LagrangeCoeffs(shares map[uint32]*ShamirShare) (map[uint32]curves.Scalar, error) { + shamir := &Shamir{ + threshold: f.Threshold, + limit: f.Limit, + curve: f.Curve, + } + identities := make([]uint32, 0) + for _, xi := range shares { + identities = append(identities, xi.Id) + } + return shamir.LagrangeCoeffs(identities) +} + +func (f Feldman) Combine(shares ...*ShamirShare) (curves.Scalar, error) { + shamir := &Shamir{ + threshold: f.Threshold, + limit: f.Limit, + curve: f.Curve, + } + return shamir.Combine(shares...) +} + +func (f Feldman) CombinePoints(shares ...*ShamirShare) (curves.Point, error) { + shamir := &Shamir{ + threshold: f.Threshold, + limit: f.Limit, + curve: f.Curve, + } + return shamir.CombinePoints(shares...) +} diff --git a/pkg/crypto/sharing/pedersen.go b/pkg/crypto/sharing/pedersen.go new file mode 100755 index 000000000..5e493755c --- /dev/null +++ b/pkg/crypto/sharing/pedersen.go @@ -0,0 +1,152 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sharing + +import ( + "fmt" + "io" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// Pedersen Verifiable Secret Sharing Scheme +type Pedersen struct { + threshold, limit uint32 + curve *curves.Curve + generator curves.Point +} + +type PedersenVerifier struct { + Generator curves.Point + Commitments []curves.Point +} + +func (pv PedersenVerifier) Verify(share, blindShare *ShamirShare) error { + curve := curves.GetCurveByName(pv.Generator.CurveName()) + if err := share.Validate(curve); err != nil { + return err + } + if err := blindShare.Validate(curve); err != nil { + return err + } + + x := curve.Scalar.New(int(share.Id)) + i := curve.Scalar.One() + rhs := pv.Commitments[0] + + for j := 1; j < len(pv.Commitments); j++ { + i = i.Mul(x) + rhs = rhs.Add(pv.Commitments[j].Mul(i)) + } + + sc, _ := curve.Scalar.SetBytes(share.Value) + bsc, _ := curve.Scalar.SetBytes(blindShare.Value) + g := pv.Commitments[0].Generator().Mul(sc) + h := pv.Generator.Mul(bsc) + lhs := g.Add(h) + + if lhs.Equal(rhs) { + return nil + } else { + return fmt.Errorf("not equal") + } +} + +// PedersenResult contains all the data from calling Split +type PedersenResult struct { + Blinding curves.Scalar + BlindingShares, SecretShares []*ShamirShare + FeldmanVerifier *FeldmanVerifier + PedersenVerifier *PedersenVerifier +} + +// NewPedersen creates a new pedersen VSS +func NewPedersen(threshold, limit uint32, generator curves.Point) (*Pedersen, error) { + if limit < threshold { + return nil, fmt.Errorf("limit cannot be less than threshold") + } + if threshold < 2 { + return nil, fmt.Errorf("threshold cannot be less than 2") + } + if limit > 255 { + return nil, fmt.Errorf("cannot exceed 255 shares") + } + curve := curves.GetCurveByName(generator.CurveName()) + if curve == nil { + return nil, fmt.Errorf("invalid curve") + } + if generator == nil { + return nil, fmt.Errorf("invalid generator") + } + if !generator.IsOnCurve() || generator.IsIdentity() { + return nil, fmt.Errorf("invalid generator") + } + return &Pedersen{threshold, limit, curve, generator}, nil +} + +// Split creates the verifiers, blinding and shares +func (pd Pedersen) Split(secret curves.Scalar, reader io.Reader) (*PedersenResult, error) { + // generate a random blinding factor + blinding := pd.curve.Scalar.Random(reader) + + shamir := Shamir{pd.threshold, pd.limit, pd.curve} + // split the secret into shares + shares, poly := shamir.getPolyAndShares(secret, reader) + + // split the blinding into shares + blindingShares, polyBlinding := shamir.getPolyAndShares(blinding, reader) + + // Generate the verifiable commitments to the polynomial for the shares + blindedverifiers := make([]curves.Point, pd.threshold) + verifiers := make([]curves.Point, pd.threshold) + + // ({p0 * G + b0 * H}, ...,{pt * G + bt * H}) + for i, c := range poly.Coefficients { + s := pd.curve.ScalarBaseMult(c) + b := pd.generator.Mul(polyBlinding.Coefficients[i]) + bv := s.Add(b) + blindedverifiers[i] = bv + verifiers[i] = s + } + verifier1 := &FeldmanVerifier{Commitments: verifiers} + verifier2 := &PedersenVerifier{Commitments: blindedverifiers, Generator: pd.generator} + + return &PedersenResult{ + blinding, blindingShares, shares, verifier1, verifier2, + }, nil +} + +func (pd Pedersen) LagrangeCoeffs(shares map[uint32]*ShamirShare) (map[uint32]curves.Scalar, error) { + shamir := &Shamir{ + threshold: pd.threshold, + limit: pd.limit, + curve: pd.curve, + } + identities := make([]uint32, 0) + for _, xi := range shares { + identities = append(identities, xi.Id) + } + return shamir.LagrangeCoeffs(identities) +} + +func (pd Pedersen) Combine(shares ...*ShamirShare) (curves.Scalar, error) { + shamir := &Shamir{ + threshold: pd.threshold, + limit: pd.limit, + curve: pd.curve, + } + return shamir.Combine(shares...) +} + +func (pd Pedersen) CombinePoints(shares ...*ShamirShare) (curves.Point, error) { + shamir := &Shamir{ + threshold: pd.threshold, + limit: pd.limit, + curve: pd.curve, + } + return shamir.CombinePoints(shares...) +} diff --git a/pkg/crypto/sharing/polynomial.go b/pkg/crypto/sharing/polynomial.go new file mode 100755 index 000000000..6e4be22e9 --- /dev/null +++ b/pkg/crypto/sharing/polynomial.go @@ -0,0 +1,35 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sharing + +import ( + "io" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type Polynomial struct { + Coefficients []curves.Scalar +} + +func (p *Polynomial) Init(intercept curves.Scalar, degree uint32, reader io.Reader) *Polynomial { + p.Coefficients = make([]curves.Scalar, degree) + p.Coefficients[0] = intercept.Clone() + for i := 1; i < int(degree); i++ { + p.Coefficients[i] = intercept.Random(reader) + } + return p +} + +func (p Polynomial) Evaluate(x curves.Scalar) curves.Scalar { + degree := len(p.Coefficients) - 1 + out := p.Coefficients[degree].Clone() + for i := degree - 1; i >= 0; i-- { + out = out.Mul(x).Add(p.Coefficients[i]) + } + return out +} diff --git a/pkg/crypto/sharing/polynomial_test.go b/pkg/crypto/sharing/polynomial_test.go new file mode 100755 index 000000000..bea0bd307 --- /dev/null +++ b/pkg/crypto/sharing/polynomial_test.go @@ -0,0 +1,32 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Copyright Coinbase, Inc. All Rights Reserved. +// +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sharing + +import ( + crand "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestNewPoly(t *testing.T) { + curve := curves.BLS12381G1() + secret := curve.NewScalar().Hash([]byte("test")) + + poly := new(Polynomial).Init(secret, 4, crand.Reader) + require.NotNil(t, poly) + + require.Equal(t, poly.Coefficients[0], secret) +} diff --git a/pkg/crypto/sharing/shamir.go b/pkg/crypto/sharing/shamir.go new file mode 100755 index 000000000..fe38b8d0a --- /dev/null +++ b/pkg/crypto/sharing/shamir.go @@ -0,0 +1,206 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package sharing is an implementation of shamir secret sharing and implements the following papers. +// +// - https://dl.acm.org/doi/pdf/10.1145/359168.359176 +// - https://www.cs.umd.edu/~gasarch/TOPICS/secretsharing/feldmanVSS.pdf +// - https://link.springer.com/content/pdf/10.1007%2F3-540-46766-1_9.pdf +package sharing + +import ( + "encoding/binary" + "fmt" + "io" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type ShamirShare struct { + Id uint32 `json:"identifier"` + Value []byte `json:"value"` +} + +func (ss ShamirShare) Validate(curve *curves.Curve) error { + if ss.Id == 0 { + return fmt.Errorf("invalid identifier") + } + sc, err := curve.Scalar.SetBytes(ss.Value) + if err != nil { + return err + } + if sc.IsZero() { + return fmt.Errorf("invalid share") + } + return nil +} + +func (ss ShamirShare) Bytes() []byte { + var id [4]byte + binary.BigEndian.PutUint32(id[:], ss.Id) + return append(id[:], ss.Value...) +} + +type Shamir struct { + threshold, limit uint32 + curve *curves.Curve +} + +func NewShamir(threshold, limit uint32, curve *curves.Curve) (*Shamir, error) { + if limit < threshold { + return nil, fmt.Errorf("limit cannot be less than threshold") + } + if threshold < 2 { + return nil, fmt.Errorf("threshold cannot be less than 2") + } + if limit > 255 { + return nil, fmt.Errorf("cannot exceed 255 shares") + } + if curve == nil { + return nil, fmt.Errorf("invalid curve") + } + return &Shamir{threshold, limit, curve}, nil +} + +func (s Shamir) Split(secret curves.Scalar, reader io.Reader) ([]*ShamirShare, error) { + if secret.IsZero() { + return nil, fmt.Errorf("invalid secret") + } + shares, _ := s.getPolyAndShares(secret, reader) + return shares, nil +} + +func (s Shamir) getPolyAndShares(secret curves.Scalar, reader io.Reader) ([]*ShamirShare, *Polynomial) { + poly := new(Polynomial).Init(secret, s.threshold, reader) + shares := make([]*ShamirShare, s.limit) + for i := range shares { + x := s.curve.Scalar.New(i + 1) + shares[i] = &ShamirShare{ + Id: uint32(i + 1), + Value: poly.Evaluate(x).Bytes(), + } + } + return shares, poly +} + +func (s Shamir) LagrangeCoeffs(identities []uint32) (map[uint32]curves.Scalar, error) { + xs := make(map[uint32]curves.Scalar, len(identities)) + for _, xi := range identities { + xs[xi] = s.curve.Scalar.New(int(xi)) + } + + result := make(map[uint32]curves.Scalar, len(identities)) + for i, xi := range xs { + num := s.curve.Scalar.One() + den := s.curve.Scalar.One() + for j, xj := range xs { + if i == j { + continue + } + + num = num.Mul(xj) + den = den.Mul(xj.Sub(xi)) + } + if den.IsZero() { + return nil, fmt.Errorf("divide by zero") + } + result[i] = num.Div(den) + } + return result, nil +} + +func (s Shamir) Combine(shares ...*ShamirShare) (curves.Scalar, error) { + if len(shares) < int(s.threshold) { + return nil, fmt.Errorf("invalid number of shares") + } + dups := make(map[uint32]bool, len(shares)) + xs := make([]curves.Scalar, len(shares)) + ys := make([]curves.Scalar, len(shares)) + + for i, share := range shares { + err := share.Validate(s.curve) + if err != nil { + return nil, err + } + if share.Id > s.limit { + return nil, fmt.Errorf("invalid share identifier") + } + if _, in := dups[share.Id]; in { + return nil, fmt.Errorf("duplicate share") + } + dups[share.Id] = true + ys[i], _ = s.curve.Scalar.SetBytes(share.Value) + xs[i] = s.curve.Scalar.New(int(share.Id)) + } + return s.interpolate(xs, ys) +} + +func (s Shamir) CombinePoints(shares ...*ShamirShare) (curves.Point, error) { + if len(shares) < int(s.threshold) { + return nil, fmt.Errorf("invalid number of shares") + } + dups := make(map[uint32]bool, len(shares)) + xs := make([]curves.Scalar, len(shares)) + ys := make([]curves.Point, len(shares)) + + for i, share := range shares { + err := share.Validate(s.curve) + if err != nil { + return nil, err + } + if share.Id > s.limit { + return nil, fmt.Errorf("invalid share identifier") + } + if _, in := dups[share.Id]; in { + return nil, fmt.Errorf("duplicate share") + } + dups[share.Id] = true + sc, _ := s.curve.Scalar.SetBytes(share.Value) + ys[i] = s.curve.ScalarBaseMult(sc) + xs[i] = s.curve.Scalar.New(int(share.Id)) + } + return s.interpolatePoint(xs, ys) +} + +func (s Shamir) interpolate(xs, ys []curves.Scalar) (curves.Scalar, error) { + result := s.curve.Scalar.Zero() + for i, xi := range xs { + num := s.curve.Scalar.One() + den := s.curve.Scalar.One() + for j, xj := range xs { + if i == j { + continue + } + num = num.Mul(xj) + den = den.Mul(xj.Sub(xi)) + } + if den.IsZero() { + return nil, fmt.Errorf("divide by zero") + } + result = result.Add(ys[i].Mul(num.Div(den))) + } + return result, nil +} + +func (s Shamir) interpolatePoint(xs []curves.Scalar, ys []curves.Point) (curves.Point, error) { + result := s.curve.NewIdentityPoint() + for i, xi := range xs { + num := s.curve.Scalar.One() + den := s.curve.Scalar.One() + for j, xj := range xs { + if i == j { + continue + } + num = num.Mul(xj) + den = den.Mul(xj.Sub(xi)) + } + if den.IsZero() { + return nil, fmt.Errorf("divide by zero") + } + result = result.Add(ys[i].Mul(num.Div(den))) + } + return result, nil +} diff --git a/pkg/crypto/sharing/shamir_test.go b/pkg/crypto/sharing/shamir_test.go new file mode 100755 index 000000000..8394b0185 --- /dev/null +++ b/pkg/crypto/sharing/shamir_test.go @@ -0,0 +1,186 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sharing + +import ( + "bytes" + crand "crypto/rand" + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestShamirSplitInvalidArgs(t *testing.T) { + curve := curves.ED25519() + _, err := NewShamir(0, 0, curve) + require.NotNil(t, err) + _, err = NewShamir(3, 2, curve) + require.NotNil(t, err) + _, err = NewShamir(1, 10, curve) + require.NotNil(t, err) + scheme, err := NewShamir(2, 3, curve) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Split(curve.NewScalar(), crand.Reader) + require.NotNil(t, err) +} + +func TestShamirCombineNoShares(t *testing.T) { + curve := curves.ED25519() + scheme, err := NewShamir(2, 3, curve) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestShamirCombineDuplicateShare(t *testing.T) { + curve := curves.ED25519() + scheme, err := NewShamir(2, 3, curve) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Id: 1, + Value: curve.NewScalar().New(3).Bytes(), + }, + { + Id: 1, + Value: curve.NewScalar().New(3).Bytes(), + }, + }...) + require.NotNil(t, err) +} + +func TestShamirCombineBadIdentifier(t *testing.T) { + curve := curves.ED25519() + scheme, err := NewShamir(2, 3, curve) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Id: 0, + Value: curve.NewScalar().New(3).Bytes(), + }, + { + Id: 2, + Value: curve.NewScalar().New(3).Bytes(), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Id: 4, + Value: curve.NewScalar().New(3).Bytes(), + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) +} + +func TestShamirCombineSingle(t *testing.T) { + curve := curves.ED25519() + scheme, err := NewShamir(2, 3, curve) + require.Nil(t, err) + require.NotNil(t, scheme) + + shares, err := scheme.Split(curve.NewScalar().Hash([]byte("test")), crand.Reader) + require.Nil(t, err) + require.NotNil(t, shares) + secret, err := scheme.Combine(shares...) + require.Nil(t, err) + require.Equal(t, secret, curve.NewScalar().Hash([]byte("test"))) +} + +// Test ComputeL function to compute Lagrange coefficients. +func TestShamirComputeL(t *testing.T) { + curve := curves.ED25519() + scheme, err := NewShamir(2, 2, curve) + require.Nil(t, err) + require.NotNil(t, scheme) + secret := curve.Scalar.Hash([]byte("test")) + shares, err := scheme.Split(secret, crand.Reader) + require.Nil(t, err) + require.NotNil(t, shares) + identities := make([]uint32, 0) + for _, xi := range shares { + identities = append(identities, xi.Id) + } + lCoeffs, err := scheme.LagrangeCoeffs(identities) + require.Nil(t, err) + require.NotNil(t, lCoeffs) + + // Checking we can reconstruct the same secret using Lagrange coefficients. + result := curve.NewScalar() + for _, r := range shares { + rc, _ := curve.Scalar.SetBytes(r.Value) + result = result.Add(rc.Mul(lCoeffs[r.Id])) + } + require.Equal(t, result.Bytes(), secret.Bytes()) +} + +func TestShamirAllCombinations(t *testing.T) { + curve := curves.ED25519() + scheme, err := NewShamir(3, 5, curve) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := curve.Scalar.Hash([]byte("test")) + shares, err := scheme.Split(secret, crand.Reader) + require.Nil(t, err) + require.NotNil(t, shares) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(shares[i], shares[j], shares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + } + } + } +} + +// Ensures that ShamirShare's un/marshal successfully. +func TestMarshalJsonRoundTrip(t *testing.T) { + curve := curves.ED25519() + shares := []ShamirShare{ + {0, curve.Scalar.New(300).Bytes()}, + {2, curve.Scalar.New(300000).Bytes()}, + {20, curve.Scalar.New(12812798).Bytes()}, + {31, curve.Scalar.New(17).Bytes()}, + {57, curve.Scalar.New(5066680).Bytes()}, + {128, curve.Scalar.New(3005).Bytes()}, + {19, curve.Scalar.New(317).Bytes()}, + {7, curve.Scalar.New(323).Bytes()}, + {222, curve.NewScalar().New(-1).Bytes()}, + } + // Run all the tests! + for _, in := range shares { + input, err := json.Marshal(in) + require.NoError(t, err) + require.NotNil(t, input) + + // Unmarshal and test + out := &ShamirShare{} + // out.Value = curve.NewScalar() + err = json.Unmarshal(input, &out) + require.NoError(t, err) + require.Equal(t, in.Id, out.Id) + require.Equal(t, bytes.Compare(in.Value, out.Value), 0) + } +} diff --git a/pkg/crypto/sharing/v1/bls12381g1_feldman_test.go b/pkg/crypto/sharing/v1/bls12381g1_feldman_test.go new file mode 100755 index 000000000..ddf020946 --- /dev/null +++ b/pkg/crypto/sharing/v1/bls12381g1_feldman_test.go @@ -0,0 +1,141 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +var ( + modulus, _ = new(big.Int).SetString( + "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + 16, + ) + field = curves.NewField(modulus) +) + +func TestBls12381G1FeldmanSplitInvalidArgs(t *testing.T) { + _, err := NewFeldman(0, 0, Bls12381G1()) + require.NotNil(t, err) + _, err = NewFeldman(3, 2, Bls12381G1()) + require.NotNil(t, err) + _, err = NewFeldman(1, 10, Bls12381G1()) + require.NotNil(t, err) + scheme, err := NewFeldman(2, 3, Bls12381G1()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, _, err = scheme.Split([]byte{}) + require.NotNil(t, err) + _, _, err = scheme.Split([]byte{0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65}) + require.NotNil(t, err) +} + +func TestBls12381G1FeldmanCombineNoShares(t *testing.T) { + scheme, err := NewFeldman(2, 3, Bls12381G1()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestBls12381G1FeldmanCombineDuplicateShare(t *testing.T) { + scheme, err := NewFeldman(2, 3, Bls12381G1()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + }...) + require.NotNil(t, err) +} + +func TestBls12381G1FeldmanCombineBadIdentifier(t *testing.T) { + scheme, err := NewFeldman(2, 3, Bls12381G1()) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Identifier: 0, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Identifier: 4, + Value: field.NewElement(big.NewInt(3)), + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) +} + +func TestBls12381G1FeldmanCombineSingle(t *testing.T) { + scheme, err := NewFeldman(2, 3, Bls12381G1()) + require.Nil(t, err) + require.NotNil(t, scheme) + + verifiers, shares, err := scheme.Split([]byte("test")) + require.Nil(t, err) + require.NotNil(t, shares) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + secret, err := scheme.Combine(shares...) + require.Nil(t, err) + require.Equal(t, secret, []byte("test")) +} + +func TestBls12381G1FeldmanAllCombinations(t *testing.T) { + scheme, err := NewFeldman(3, 5, Bls12381G1()) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := []byte("test") + verifiers, shares, err := scheme.Split(secret) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + require.Nil(t, err) + require.NotNil(t, shares) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(shares[i], shares[j], shares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + } + } + } +} diff --git a/pkg/crypto/sharing/v1/bls12381g1curve.go b/pkg/crypto/sharing/v1/bls12381g1curve.go new file mode 100755 index 000000000..f961c4258 --- /dev/null +++ b/pkg/crypto/sharing/v1/bls12381g1curve.go @@ -0,0 +1,109 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "crypto/elliptic" + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + bls12381g1Initonce sync.Once + bls12381g1 Bls12381G1Curve +) + +type Bls12381G1Curve struct { + *elliptic.CurveParams +} + +func bls12381g1InitAll() { + bls12381g1.CurveParams = new(elliptic.CurveParams) + bls12381g1.P, _ = new(big.Int).SetString("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16) + bls12381g1.N = bls12381.Bls12381FqNew().Params.BiModulus + bls12381g1.B, _ = new(big.Int).SetString("0bbc3efc5008a26a0e1c8c3fad0059c051ac582950405194dd595f13570725ce8c22631a7918fd8ebaac93d50ce72271", 16) + bls12381g1.Gx, _ = new(big.Int).SetString("120177419e0bfb75edce6ecc21dbf440f0ae6acdf3d0e747154f95c7143ba1c17817fc679976fff55cb38790fd530c16", 16) + bls12381g1.Gy, _ = new(big.Int).SetString("0bbc3efc5008a26a0e1c8c3fad0059c051ac582950405194dd595f13570725ce8c22631a7918fd8ebaac93d50ce72271", 16) + bls12381g1.BitSize = 381 + bls12381g1.Name = "Bls12381G1" +} + +func Bls12381G1() *Bls12381G1Curve { + bls12381g1Initonce.Do(bls12381g1InitAll) + return &bls12381g1 +} + +func (curve *Bls12381G1Curve) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +func (curve *Bls12381G1Curve) IsOnCurve(x, y *big.Int) bool { + _, err := new(bls12381.G1).SetBigInt(x, y) + return err == nil +} + +func (curve *Bls12381G1Curve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + p1, err1 := new(bls12381.G1).SetBigInt(x1, y1) + p2, err2 := new(bls12381.G1).SetBigInt(x2, y2) + + if err1 != nil || err2 != nil { + return nil, nil + } + return p1.Add(p1, p2).BigInt() +} + +func (curve *Bls12381G1Curve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + p, err := new(bls12381.G1).SetBigInt(x1, y1) + if err != nil { + return nil, nil + } + return p.Double(p).BigInt() +} + +func (curve *Bls12381G1Curve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + p, err := new(bls12381.G1).SetBigInt(Bx, By) + if err != nil { + return nil, nil + } + var bb [native.FieldBytes]byte + copy(bb[:], k) + s, err := bls12381.Bls12381FqNew().SetBytes(&bb) + if err != nil { + return nil, nil + } + return p.Mul(p, s).BigInt() +} + +func (curve *Bls12381G1Curve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + p := new(bls12381.G1).Generator() + var bb [native.FieldBytes]byte + copy(bb[:], internal.ReverseScalarBytes(k)) + s, err := bls12381.Bls12381FqNew().SetBytes(&bb) + if err != nil { + return nil, nil + } + return p.Mul(p, s).BigInt() +} + +// Hash an arbitrary byte sequence to a G1 point according to the hash-to-curve standard +func (curve *Bls12381G1Curve) Hash(msg []byte) (*big.Int, *big.Int) { + return new(bls12381.G1).Hash(native.EllipticPointHasherSha256(), msg, []byte("BLS12381G1_XMD:SHA-256_SSWU_RO_")).BigInt() +} + +// CompressedBytesFromBigInts takes x and y coordinates and converts them to the BLS compressed point form +func (curve *Bls12381G1Curve) CompressedBytesFromBigInts(x, y *big.Int) ([]byte, error) { + p, err := new(bls12381.G1).SetBigInt(x, y) + if err != nil { + return nil, err + } + out := p.ToCompressed() + return out[:], nil +} diff --git a/pkg/crypto/sharing/v1/bls12381g2_feldman_test.go b/pkg/crypto/sharing/v1/bls12381g2_feldman_test.go new file mode 100755 index 000000000..edef8dac3 --- /dev/null +++ b/pkg/crypto/sharing/v1/bls12381g2_feldman_test.go @@ -0,0 +1,131 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBls12381G2FeldmanSplitInvalidArgs(t *testing.T) { + _, err := NewFeldman(0, 0, Bls12381G2()) + require.NotNil(t, err) + _, err = NewFeldman(3, 2, Bls12381G2()) + require.NotNil(t, err) + _, err = NewFeldman(1, 10, Bls12381G2()) + require.NotNil(t, err) + scheme, err := NewFeldman(2, 3, Bls12381G2()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, _, err = scheme.Split([]byte{}) + require.NotNil(t, err) + _, _, err = scheme.Split([]byte{0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65}) + require.NotNil(t, err) +} + +func TestBls12381G2FeldmanCombineNoShares(t *testing.T) { + scheme, err := NewFeldman(2, 3, Bls12381G2()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestBls12381G2FeldmanCombineDuplicateShare(t *testing.T) { + scheme, err := NewFeldman(2, 3, Bls12381G2()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + }...) + require.NotNil(t, err) +} + +func TestBls12381G2FeldmanCombineBadIdentifier(t *testing.T) { + scheme, err := NewFeldman(2, 3, Bls12381G2()) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Identifier: 0, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Identifier: 4, + Value: field.NewElement(big.NewInt(3)), + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) +} + +func TestBls12381G2FeldmanCombineSingle(t *testing.T) { + scheme, err := NewFeldman(2, 3, Bls12381G2()) + require.Nil(t, err) + require.NotNil(t, scheme) + + verifiers, shares, err := scheme.Split([]byte("test")) + require.Nil(t, err) + require.NotNil(t, shares) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + secret, err := scheme.Combine(shares...) + require.Nil(t, err) + require.Equal(t, secret, []byte("test")) +} + +func TestBls12381G2FeldmanAllCombinations(t *testing.T) { + scheme, err := NewFeldman(3, 5, Bls12381G2()) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := []byte("test") + verifiers, shares, err := scheme.Split(secret) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + require.Nil(t, err) + require.NotNil(t, shares) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(shares[i], shares[j], shares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + } + } + } +} diff --git a/pkg/crypto/sharing/v1/bls12381g2curve.go b/pkg/crypto/sharing/v1/bls12381g2curve.go new file mode 100755 index 000000000..0360bb03b --- /dev/null +++ b/pkg/crypto/sharing/v1/bls12381g2curve.go @@ -0,0 +1,108 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "crypto/elliptic" + "math/big" + "sync" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" +) + +var ( + bls12381g2Initonce sync.Once + bls12381g2 Bls12381G2Curve +) + +type Bls12381G2Curve struct { + *elliptic.CurveParams +} + +func bls12381g2InitAll() { + bls12381g2.CurveParams = new(elliptic.CurveParams) + bls12381g2.P, _ = new(big.Int).SetString("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16) + bls12381g2.N = bls12381.Bls12381FqNew().Params.BiModulus + bls12381g2.B, _ = new(big.Int).SetString("0bbc3efc5008a26a0e1c8c3fad0059c051ac582950405194dd595f13570725ce8c22631a7918fd8ebaac93d50ce72271", 16) + bls12381g2.Gx, _ = new(big.Int).SetString("120177419e0bfb75edce6ecc21dbf440f0ae6acdf3d0e747154f95c7143ba1c17817fc679976fff55cb38790fd530c16", 16) + bls12381g2.Gy, _ = new(big.Int).SetString("0bbc3efc5008a26a0e1c8c3fad0059c051ac582950405194dd595f13570725ce8c22631a7918fd8ebaac93d50ce72271", 16) + bls12381g2.BitSize = 381 + bls12381g2.Name = "Bls12381G1" +} + +func Bls12381G2() *Bls12381G1Curve { + bls12381g2Initonce.Do(bls12381g2InitAll) + return &bls12381g1 +} + +func (curve *Bls12381G2Curve) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +func (curve *Bls12381G2Curve) IsOnCurve(x, y *big.Int) bool { + _, err := new(bls12381.G2).SetBigInt(x, y) + return err == nil +} + +func (curve *Bls12381G2Curve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + p1, err1 := new(bls12381.G2).SetBigInt(x1, y1) + p2, err2 := new(bls12381.G2).SetBigInt(x2, y2) + + if err1 != nil || err2 != nil { + return nil, nil + } + return p1.Add(p1, p2).BigInt() +} + +func (curve *Bls12381G2Curve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + p, err := new(bls12381.G2).SetBigInt(x1, y1) + if err != nil { + return nil, nil + } + return p.Double(p).BigInt() +} + +func (curve *Bls12381G2Curve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + p, err := new(bls12381.G2).SetBigInt(Bx, By) + if err != nil { + return nil, nil + } + var bb [native.FieldBytes]byte + copy(bb[:], k) + s, err := bls12381.Bls12381FqNew().SetBytes(&bb) + if err != nil { + return nil, nil + } + return p.Mul(p, s).BigInt() +} + +func (curve *Bls12381G2Curve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + p := new(bls12381.G2).Generator() + var bb [native.FieldBytes]byte + copy(bb[:], k) + s, err := bls12381.Bls12381FqNew().SetBytes(&bb) + if err != nil { + return nil, nil + } + return p.Mul(p, s).BigInt() +} + +// Hash an arbitrary byte sequence to a G1 point according to the hash-to-curve standard +func (curve *Bls12381G2Curve) Hash(msg []byte) (*big.Int, *big.Int) { + return new(bls12381.G1).Hash(native.EllipticPointHasherSha256(), msg, []byte("BLS12381G2_XMD:SHA-256_SSWU_RO_")).BigInt() +} + +// CompressedBytesFromBigInts takes x and y coordinates and converts them to the BLS compressed point form +func (curve *Bls12381G2Curve) CompressedBytesFromBigInts(x, y *big.Int) ([]byte, error) { + p, err := new(bls12381.G2).SetBigInt(x, y) + if err != nil { + return nil, err + } + out := p.ToCompressed() + return out[:], nil +} diff --git a/pkg/crypto/sharing/v1/common.go b/pkg/crypto/sharing/v1/common.go new file mode 100755 index 000000000..c5ef0171b --- /dev/null +++ b/pkg/crypto/sharing/v1/common.go @@ -0,0 +1,14 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + kryptology "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// ShareVerifier is used to verify secret shares from Feldman or Pedersen VSS +type ShareVerifier = kryptology.EcPoint diff --git a/pkg/crypto/sharing/v1/ed25519_feldman_test.go b/pkg/crypto/sharing/v1/ed25519_feldman_test.go new file mode 100755 index 000000000..1c3e21133 --- /dev/null +++ b/pkg/crypto/sharing/v1/ed25519_feldman_test.go @@ -0,0 +1,131 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEd25519FeldmanSplitInvalidArgs(t *testing.T) { + _, err := NewFeldman(0, 0, Ed25519()) + require.NotNil(t, err) + _, err = NewFeldman(3, 2, Ed25519()) + require.NotNil(t, err) + _, err = NewFeldman(1, 10, Ed25519()) + require.NotNil(t, err) + scheme, err := NewFeldman(2, 3, Ed25519()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, _, err = scheme.Split([]byte{}) + require.NotNil(t, err) + _, _, err = scheme.Split([]byte{0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65}) + require.NotNil(t, err) +} + +func TestEd25519FeldmanCombineNoShares(t *testing.T) { + scheme, err := NewFeldman(2, 3, Ed25519()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestEd25519FeldmanCombineDuplicateShare(t *testing.T) { + scheme, err := NewFeldman(2, 3, Ed25519()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + }...) + require.NotNil(t, err) +} + +func TestEd25519FeldmanCombineBadIdentifier(t *testing.T) { + scheme, err := NewFeldman(2, 3, Ed25519()) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Identifier: 0, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Identifier: 4, + Value: field.NewElement(big.NewInt(3)), + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) +} + +func TestEd25519FeldmanCombineSingle(t *testing.T) { + scheme, err := NewFeldman(2, 3, Ed25519()) + require.Nil(t, err) + require.NotNil(t, scheme) + + verifiers, shares, err := scheme.Split([]byte("test")) + require.Nil(t, err) + require.NotNil(t, shares) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + secret, err := scheme.Combine(shares...) + require.Nil(t, err) + require.Equal(t, secret, []byte("test")) +} + +func TestEd25519FeldmanAllCombinations(t *testing.T) { + scheme, err := NewFeldman(3, 5, Ed25519()) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := []byte("test") + verifiers, shares, err := scheme.Split(secret) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + require.Nil(t, err) + require.NotNil(t, shares) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(shares[i], shares[j], shares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + } + } + } +} diff --git a/pkg/crypto/sharing/v1/ed25519_pedersen_test.go b/pkg/crypto/sharing/v1/ed25519_pedersen_test.go new file mode 100755 index 000000000..3ac363851 --- /dev/null +++ b/pkg/crypto/sharing/v1/ed25519_pedersen_test.go @@ -0,0 +1,154 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "crypto/sha512" + "math/big" + "testing" + + "filippo.io/edwards25519" + "github.com/stretchr/testify/require" + + core "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + ed25519BasePoint = &core.EcPoint{Curve: Ed25519(), X: Ed25519().Gx, Y: Ed25519().Gy} + testPointEd25519, _ = core.NewScalarBaseMult(Ed25519(), big.NewInt(2222)) +) + +func TestEd25519PedersenSplitInvalidArgs(t *testing.T) { + _, err := NewPedersen(0, 0, nil) + require.NotNil(t, err) + _, err = NewPedersen(3, 2, nil) + require.NotNil(t, err) + _, err = NewPedersen(1, 10, nil) + require.NotNil(t, err) + _, err = NewPedersen(2, 3, nil) + require.NotNil(t, err) + scheme, err := NewPedersen(2, 3, ed25519BasePoint) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Split([]byte{}) + require.NotNil(t, err) + // test that split doesn't work on secrets bigger than the modulus + _, err = scheme.Split([]byte{0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65}) + require.NotNil(t, err) +} + +func TestEd25519PedersenCombineNoShares(t *testing.T) { + scheme, err := NewPedersen(2, 3, ed25519BasePoint) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestEd25519PedersenCombineDuplicateShare(t *testing.T) { + scheme, err := NewPedersen(2, 3, ed25519BasePoint) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + }...) + require.NotNil(t, err) +} + +func TestEd25519PedersenCombineBadIdentifier(t *testing.T) { + scheme, err := NewPedersen(2, 3, ed25519BasePoint) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Identifier: 0, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Identifier: 4, + Value: field.NewElement(big.NewInt(3)), + } + _, err = scheme.Combine(shares...) + require.Error(t, err) +} + +func TestEd25519PedersenCombineSingle(t *testing.T) { + scheme, err := NewPedersen(2, 3, testPointEd25519) + require.Nil(t, err) + require.NotNil(t, scheme) + + hBytes := sha512.Sum512([]byte("test")) + var arr [32]byte + copy(arr[:], hBytes[:]) + sc, err := edwards25519.NewScalar().SetBytesWithClamping(arr[:]) + require.Nil(t, err) + result, err := scheme.Split(internal.ReverseScalarBytes(sc.Bytes())) + require.Nil(t, err) + require.NotNil(t, result) + for i, s := range result.SecretShares { + ok, err := scheme.Verify(s, result.BlindingShares[i], result.BlindedVerifiers) + require.Nil(t, err) + require.True(t, ok) + } + secret, err := scheme.Combine(result.SecretShares...) + require.Nil(t, err) + require.Equal(t, internal.ReverseScalarBytes(secret), sc.Bytes()) +} + +func TestEd25519PedersenAllCombinations(t *testing.T) { + scheme, err := NewPedersen(3, 5, testPointEd25519) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := []byte("test") + result, err := scheme.Split(secret) + for i, s := range result.SecretShares { + ok, err := scheme.Verify(s, result.BlindingShares[i], result.BlindedVerifiers) + require.Nil(t, err) + require.True(t, ok) + } + require.Nil(t, err) + require.NotNil(t, result) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(result.SecretShares[i], result.SecretShares[j], result.SecretShares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + + bSecret, err := scheme.Combine(result.BlindingShares[i], result.BlindingShares[j], result.BlindingShares[k]) + require.Nil(t, err) + require.NotNil(t, bSecret) + require.Equal(t, bSecret, result.Blinding.Bytes()) + } + } + } +} diff --git a/pkg/crypto/sharing/v1/ed25519curve.go b/pkg/crypto/sharing/v1/ed25519curve.go new file mode 100755 index 000000000..e94e1e623 --- /dev/null +++ b/pkg/crypto/sharing/v1/ed25519curve.go @@ -0,0 +1,143 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "crypto/elliptic" + "math/big" + "sync" + + ed "filippo.io/edwards25519" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +var ( + ed25519Initonce sync.Once + ed25519 Ed25519Curve +) + +type Ed25519Curve struct { + *elliptic.CurveParams +} + +func ed25519InitAll() { + // taken from https://datatracker.ietf.org/doc/html/rfc8032 + ed25519.CurveParams = new(elliptic.CurveParams) + ed25519.P, _ = new(big.Int).SetString("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", 16) + ed25519.N, _ = new(big.Int).SetString("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", 16) + ed25519.Gx = new(big.Int) + ed25519.Gy = new(big.Int).SetBytes(ed.NewGeneratorPoint().Bytes()) + ed25519.BitSize = 255 + ed25519.Name = "ed25519" +} + +func Ed25519() *Ed25519Curve { + ed25519Initonce.Do(ed25519InitAll) + return &ed25519 +} + +func (curve *Ed25519Curve) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +func (curve *Ed25519Curve) IsOnCurve(x, y *big.Int) bool { + // ignore the x value since Ed25519 is canonical 32 bytes of y according to RFC 8032 + // Set bytes returns an error if not a valid point + _, err := internal.BigInt2Ed25519Point(y) + return err == nil +} + +func (curve *Ed25519Curve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + var p1, p2 *ed.Point + var err error + if y1.Cmp(big.NewInt(0)) == 0 { + p1 = ed.NewIdentityPoint() + } else { + p1, err = internal.BigInt2Ed25519Point(y1) + } + if err != nil { + panic(err) + } + if y2.Cmp(big.NewInt(0)) == 0 { + p2 = ed.NewIdentityPoint() + } else { + p2, err = internal.BigInt2Ed25519Point(y2) + } + if err != nil { + panic(err) + } + p1.Add(p1, p2) + return new(big.Int), new(big.Int).SetBytes(p1.Bytes()) +} + +func (curve *Ed25519Curve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + p, err := internal.BigInt2Ed25519Point(y1) + if err != nil { + panic(err) + } + p1, _ := internal.BigInt2Ed25519Point(y1) + p.Add(p, p1) + return new(big.Int), new(big.Int).SetBytes(p.Bytes()) +} + +func (curve *Ed25519Curve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { + p, err := internal.BigInt2Ed25519Point(By) + if err != nil { + panic(err) + } + s, err := internal.BigInt2Ed25519Scalar(new(big.Int).SetBytes(k)) + if err != nil { + var t [64]byte + copy(t[:], internal.ReverseScalarBytes(k)) + s, err = ed.NewScalar().SetUniformBytes(t[:]) + if err != nil { + panic(err) + } + } + p.ScalarMult(s, p) + return new(big.Int), new(big.Int).SetBytes(p.Bytes()) +} + +func (curve *Ed25519Curve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + s, err := internal.BigInt2Ed25519Scalar(new(big.Int).SetBytes(k)) + if err != nil { + var t [64]byte + copy(t[:], internal.ReverseScalarBytes(k)) + s, err = ed.NewScalar().SetUniformBytes(t[:]) + if err != nil { + panic(err) + } + } + p := ed.NewIdentityPoint().ScalarBaseMult(s) + return new(big.Int), new(big.Int).SetBytes(p.Bytes()) +} + +func (curve *Ed25519Curve) Neg(Bx, By *big.Int) (*big.Int, *big.Int) { + var p1 *ed.Point + var err error + if By.Cmp(big.NewInt(0)) == 0 { + p1 = ed.NewIdentityPoint() + } else { + p1, err = internal.BigInt2Ed25519Point(By) + if err != nil { + panic(err) + } + } + p1.Negate(p1) + return new(big.Int), new(big.Int).SetBytes(p1.Bytes()) +} + +func (curve *Ed25519Curve) Hash(msg []byte) (*big.Int, *big.Int) { + data := new(curves.PointEd25519).Hash(msg).ToAffineCompressed() + pt, err := ed.NewIdentityPoint().SetBytes(data) + if err != nil { + panic(err) + } + return new(big.Int), new(big.Int).SetBytes(internal.ReverseScalarBytes(pt.Bytes())) +} diff --git a/pkg/crypto/sharing/v1/ed25519curve_test.go b/pkg/crypto/sharing/v1/ed25519curve_test.go new file mode 100755 index 000000000..cf60fc278 --- /dev/null +++ b/pkg/crypto/sharing/v1/ed25519curve_test.go @@ -0,0 +1,26 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEd25519ScalarMult(t *testing.T) { + // These values were caught during testing where this combination + // yields leading zeros in which big.Int chops. + // This test makes sure that this case is correctly handled + y := new(big.Int).SetBytes([]byte{37, 228, 49, 105, 78, 97, 108, 221, 63, 25, 125, 212, 108, 189, 247, 169, 52, 86, 150, 97, 93, 199, 212, 254, 122, 98, 189, 7, 97, 14, 78, 12}) + x := new(big.Int).SetInt64(4) + curve := Ed25519() + require.True(t, curve.IsOnCurve(nil, y)) + _, newY := curve.ScalarMult(nil, y, x.Bytes()) + require.True(t, curve.IsOnCurve(nil, newY)) +} diff --git a/pkg/crypto/sharing/v1/feldman.go b/pkg/crypto/sharing/v1/feldman.go new file mode 100755 index 000000000..9ffde8d91 --- /dev/null +++ b/pkg/crypto/sharing/v1/feldman.go @@ -0,0 +1,107 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "crypto/elliptic" + "encoding/binary" + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// Feldman Verifiable Secret Sharing Scheme +type Feldman struct { + threshold, limit uint32 + curve elliptic.Curve +} + +// FeldmanResult contains all the data from calling Split +type FeldmanResult struct { + SecretShares []*ShamirShare + Verifiers []*ShareVerifier +} + +func NewFeldman(threshold, limit uint32, curve elliptic.Curve) (*Feldman, error) { + if limit < threshold { + return nil, fmt.Errorf("limit cannot be less than threshold") + } + if threshold < 2 { + return nil, fmt.Errorf("threshold must be at least 2") + } + return &Feldman{ + threshold, limit, curve, + }, nil +} + +func (f Feldman) Split(secret []byte) ([]*ShareVerifier, []*ShamirShare, error) { + field := curves.NewField(f.curve.Params().N) + shamir := Shamir{f.threshold, f.limit, field} + shares, poly, err := shamir.GetSharesAndPolynomial(secret) + if err != nil { + return nil, nil, err + } + // Generate the verifiable commitments to the polynomial for the shares + verifiers := make([]*ShareVerifier, len(poly.Coefficients)) + for i, c := range poly.Coefficients { + v, err := curves.NewScalarBaseMult(f.curve, c.Value) + if err != nil { + return nil, nil, err + } + verifiers[i] = v + } + return verifiers, shares, nil +} + +func (f Feldman) Combine(shares ...*ShamirShare) ([]byte, error) { + field := curves.NewField(f.curve.Params().N) + shamir := Shamir{f.threshold, f.limit, field} + return shamir.Combine(shares...) +} + +// Verify checks a share for validity +func (f Feldman) Verify(share *ShamirShare, verifiers []*ShareVerifier) (bool, error) { + if len(verifiers) < int(f.threshold) { + return false, fmt.Errorf("not enough verifiers to check") + } + field := curves.NewField(f.curve.Params().N) + + xBytes := make([]byte, 4) + binary.BigEndian.PutUint32(xBytes, share.Identifier) + x := field.ElementFromBytes(xBytes) + + i := share.Value.Modulus.One() + + // c_0 + rhs := verifiers[0] + + // Compute the sum of products + // c_0 * c_1^i * c_2^{i^2} * c_3^{i^3} ... c_t^{i_t} + for j := 1; j < len(verifiers); j++ { + // i *= x + i = i.Mul(x) + + c, err := verifiers[j].ScalarMult(i.Value) + if err != nil { + return false, err + } + + // ... * c_j^{i^j} + rhs, err = rhs.Add(c) + if err != nil { + return false, err + } + } + + lhs, err := curves.NewScalarBaseMult(f.curve, share.Value.Value) + if err != nil { + return false, err + } + + // Check if lhs == rhs + return lhs.Equals(rhs), nil +} diff --git a/pkg/crypto/sharing/v1/k256_feldman_test.go b/pkg/crypto/sharing/v1/k256_feldman_test.go new file mode 100755 index 000000000..959603dca --- /dev/null +++ b/pkg/crypto/sharing/v1/k256_feldman_test.go @@ -0,0 +1,132 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "math/big" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" +) + +func TestK256FeldmanSplitInvalidArgs(t *testing.T) { + _, err := NewFeldman(0, 0, btcec.S256()) + require.NotNil(t, err) + _, err = NewFeldman(3, 2, btcec.S256()) + require.NotNil(t, err) + _, err = NewFeldman(1, 10, btcec.S256()) + require.NotNil(t, err) + scheme, err := NewFeldman(2, 3, btcec.S256()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, _, err = scheme.Split([]byte{}) + require.NotNil(t, err) + _, _, err = scheme.Split([]byte{0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65}) + require.NotNil(t, err) +} + +func TestK256FeldmanCombineNoShares(t *testing.T) { + scheme, err := NewFeldman(2, 3, btcec.S256()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestK256FeldmanCombineDuplicateShare(t *testing.T) { + scheme, err := NewFeldman(2, 3, btcec.S256()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + }...) + require.NotNil(t, err) +} + +func TestK256FeldmanCombineBadIdentifier(t *testing.T) { + scheme, err := NewFeldman(2, 3, btcec.S256()) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Identifier: 0, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Identifier: 4, + Value: field.NewElement(big.NewInt(3)), + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) +} + +func TestK256FeldmanCombineSingle(t *testing.T) { + scheme, err := NewFeldman(2, 3, btcec.S256()) + require.Nil(t, err) + require.NotNil(t, scheme) + + verifiers, shares, err := scheme.Split([]byte("test")) + require.Nil(t, err) + require.NotNil(t, shares) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + secret, err := scheme.Combine(shares...) + require.Nil(t, err) + require.Equal(t, secret, []byte("test")) +} + +func TestK256FeldmanAllCombinations(t *testing.T) { + scheme, err := NewFeldman(3, 5, btcec.S256()) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := []byte("test") + verifiers, shares, err := scheme.Split(secret) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + require.Nil(t, err) + require.NotNil(t, shares) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(shares[i], shares[j], shares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + } + } + } +} diff --git a/pkg/crypto/sharing/v1/k256_pedersen_test.go b/pkg/crypto/sharing/v1/k256_pedersen_test.go new file mode 100755 index 000000000..6b07d3bed --- /dev/null +++ b/pkg/crypto/sharing/v1/k256_pedersen_test.go @@ -0,0 +1,155 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "math/big" + "testing" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" + + core "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +var ( + k256BasePoint = &core.EcPoint{Curve: btcec.S256(), X: btcec.S256().Gx, Y: btcec.S256().Gy} + testPointK256, _ = core.NewScalarBaseMult(btcec.S256(), big.NewInt(2222)) +) + +func TestK256PedersenSplitInvalidArgs(t *testing.T) { + _, err := NewPedersen(0, 0, nil) + require.NotNil(t, err) + _, err = NewPedersen(3, 2, nil) + require.NotNil(t, err) + _, err = NewPedersen(1, 10, nil) + require.NotNil(t, err) + _, err = NewPedersen(2, 3, nil) + require.NotNil(t, err) + scheme, err := NewPedersen(2, 3, k256BasePoint) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Split([]byte{}) + require.NotNil(t, err) + // test that split doesn't work on secrets bigger than the modulus + _, err = scheme.Split([]byte{0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65}) + require.NotNil(t, err) +} + +func TestK256PedersenCombineNoShares(t *testing.T) { + scheme, err := NewPedersen(2, 3, k256BasePoint) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestK256PedersenCombineDuplicateShare(t *testing.T) { + scheme, err := NewPedersen(2, 3, k256BasePoint) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + }...) + require.NotNil(t, err) +} + +func TestK256PedersenCombineBadIdentifier(t *testing.T) { + scheme, err := NewPedersen(2, 3, k256BasePoint) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Identifier: 0, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Identifier: 4, + Value: field.NewElement(big.NewInt(3)), + } + _, err = scheme.Combine(shares...) + require.Error(t, err) +} + +func TestK256GeneratorFromHashedBytes(t *testing.T) { + x, y, err := K256GeneratorFromHashedBytes([]byte("Fair is foul, and foul is fair: Hover through the fog and filthy air.")) + require.NoError(t, err) + require.NotNil(t, x) + require.NotNil(t, y) + require.True(t, btcec.S256().IsOnCurve(x, y)) +} + +func TestK256PedersenCombineSingle(t *testing.T) { + scheme, err := NewPedersen(2, 3, testPointK256) + require.Nil(t, err) + require.NotNil(t, scheme) + + result, err := scheme.Split([]byte("test")) + require.Nil(t, err) + require.NotNil(t, result) + for i, s := range result.SecretShares { + ok, err := scheme.Verify(s, result.BlindingShares[i], result.BlindedVerifiers) + require.Nil(t, err) + require.True(t, ok) + } + secret, err := scheme.Combine(result.SecretShares...) + require.Nil(t, err) + require.Equal(t, secret, []byte("test")) +} + +func TestK256PedersenAllCombinations(t *testing.T) { + scheme, err := NewPedersen(3, 5, testPointK256) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := []byte("test") + result, err := scheme.Split(secret) + for i, s := range result.SecretShares { + ok, err := scheme.Verify(s, result.BlindingShares[i], result.BlindedVerifiers) + require.Nil(t, err) + require.True(t, ok) + } + require.Nil(t, err) + require.NotNil(t, result) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(result.SecretShares[i], result.SecretShares[j], result.SecretShares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + + bSecret, err := scheme.Combine(result.BlindingShares[i], result.BlindingShares[j], result.BlindingShares[k]) + require.Nil(t, err) + require.NotNil(t, bSecret) + require.Equal(t, bSecret, result.Blinding.Bytes()) + } + } + } +} diff --git a/pkg/crypto/sharing/v1/p256_feldman_test.go b/pkg/crypto/sharing/v1/p256_feldman_test.go new file mode 100755 index 000000000..7e4525f19 --- /dev/null +++ b/pkg/crypto/sharing/v1/p256_feldman_test.go @@ -0,0 +1,132 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "crypto/elliptic" + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestP256FeldmanSplitInvalidArgs(t *testing.T) { + _, err := NewFeldman(0, 0, elliptic.P256()) + require.NotNil(t, err) + _, err = NewFeldman(3, 2, elliptic.P256()) + require.NotNil(t, err) + _, err = NewFeldman(1, 10, elliptic.P256()) + require.NotNil(t, err) + scheme, err := NewFeldman(2, 3, elliptic.P256()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, _, err = scheme.Split([]byte{}) + require.NotNil(t, err) + _, _, err = scheme.Split([]byte{0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65}) + require.NotNil(t, err) +} + +func TestP256FeldmanCombineNoShares(t *testing.T) { + scheme, err := NewFeldman(2, 3, elliptic.P256()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestP256FeldmanCombineDuplicateShare(t *testing.T) { + scheme, err := NewFeldman(2, 3, elliptic.P256()) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + }...) + require.NotNil(t, err) +} + +func TestP256FeldmanCombineBadIdentifier(t *testing.T) { + scheme, err := NewFeldman(2, 3, elliptic.P256()) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Identifier: 0, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Identifier: 4, + Value: field.NewElement(big.NewInt(3)), + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) +} + +func TestP256FeldmanCombineSingle(t *testing.T) { + scheme, err := NewFeldman(2, 3, elliptic.P256()) + require.Nil(t, err) + require.NotNil(t, scheme) + + verifiers, shares, err := scheme.Split([]byte("test")) + require.Nil(t, err) + require.NotNil(t, shares) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + secret, err := scheme.Combine(shares...) + require.Nil(t, err) + require.Equal(t, secret, []byte("test")) +} + +func TestP256FeldmanAllCombinations(t *testing.T) { + scheme, err := NewFeldman(3, 5, elliptic.P256()) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := []byte("test") + verifiers, shares, err := scheme.Split(secret) + for _, s := range shares { + ok, err := scheme.Verify(s, verifiers) + require.Nil(t, err) + require.True(t, ok) + } + require.Nil(t, err) + require.NotNil(t, shares) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(shares[i], shares[j], shares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + } + } + } +} diff --git a/pkg/crypto/sharing/v1/pedersen.go b/pkg/crypto/sharing/v1/pedersen.go new file mode 100755 index 000000000..6c83f82a7 --- /dev/null +++ b/pkg/crypto/sharing/v1/pedersen.go @@ -0,0 +1,174 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + crand "crypto/rand" + "encoding/binary" + "fmt" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// Pedersen Verifiable Secret Sharing Scheme +type Pedersen struct { + threshold, limit uint32 + generator *curves.EcPoint +} + +// PedersenResult contains all the data from calling Split +type PedersenResult struct { + Blinding *big.Int + BlindingShares, SecretShares []*ShamirShare + BlindedVerifiers []*ShareVerifier + Verifiers []*ShareVerifier +} + +// NewPedersen creates a new pedersen VSS +func NewPedersen(threshold, limit uint32, generator *curves.EcPoint) (*Pedersen, error) { + if limit < threshold { + return nil, fmt.Errorf("limit cannot be less than threshold") + } + if threshold < 2 { + return nil, fmt.Errorf("threshold must be at least 2") + } + + if generator == nil { + return nil, internal.ErrNilArguments + } + if generator.IsIdentity() { + return nil, fmt.Errorf("generator point cannot be at infinity") + } + if !generator.IsOnCurve() { + return nil, fmt.Errorf("generator point must be on the curve") + } + + return &Pedersen{ + threshold, limit, generator, + }, nil +} + +// Split creates the verifiers, blinding and shares +func (pd Pedersen) Split(secret []byte) (*PedersenResult, error) { + // generate a random blinding factor + blinding, err := crand.Int(crand.Reader, pd.generator.Curve.Params().N) + if err != nil { + return nil, err + } + + field := curves.NewField(pd.generator.Curve.Params().N) + shamir := Shamir{pd.threshold, pd.limit, field} + // split the secret into shares + shares, polySecret, err := shamir.GetSharesAndPolynomial(secret) + if err != nil { + return nil, err + } + + // split the blinding into shares + blindingShares, polyBlinding, err := shamir.GetSharesAndPolynomial(blinding.Bytes()) + if err != nil { + return nil, err + } + + // Generate the verifiable commitments to the polynomial for the shares + blindedverifiers := make([]*ShareVerifier, pd.threshold) + verifiers := make([]*ShareVerifier, pd.threshold) + + // ({p0 * G + b0 * H}, ...,{pt * G + bt * H}) + for i, c := range polySecret.Coefficients { + s, err := curves.NewScalarBaseMult(pd.generator.Curve, c.Value) + if err != nil { + return nil, err + } + b, err := pd.generator.ScalarMult(polyBlinding.Coefficients[i].Value) + if err != nil { + return nil, err + } + + bv, err := s.Add(b) + if err != nil { + return nil, err + } + + blindedverifiers[i] = bv + verifiers[i] = s + } + return &PedersenResult{ + blinding, blindingShares, shares, blindedverifiers, verifiers, + }, nil +} + +// Combine recreates the original secret from the shares +func (pd Pedersen) Combine(shares ...*ShamirShare) ([]byte, error) { + field := curves.NewField(pd.generator.Curve.Params().N) + shamir := Shamir{pd.threshold, pd.limit, field} + return shamir.Combine(shares...) +} + +// Verify checks a share for validity +func (pd Pedersen) Verify(share *ShamirShare, blinding *ShamirShare, blindedverifiers []*ShareVerifier) (bool, error) { + if len(blindedverifiers) < int(pd.threshold) { + return false, fmt.Errorf("not enough blindedverifiers to check") + } + field := curves.NewField(pd.generator.Curve.Params().N) + + xBytes := make([]byte, 4) + binary.BigEndian.PutUint32(xBytes, share.Identifier) + x := field.ElementFromBytes(xBytes) + + i := share.Value.Modulus.One() + + // c_0 + rhs := blindedverifiers[0] + + // Compute the sum of products + // c_0 * c_1^i * c_2^{i^2} * c_3^{i^3} ... c_t^{i_t} + for j := 1; j < len(blindedverifiers); j++ { + // i *= x + i = i.Mul(x) + + c, err := blindedverifiers[j].ScalarMult(i.Value) + if err != nil { + return false, err + } + + // ... * c_j^{i^j} + rhs, err = rhs.Add(c) + if err != nil { + return false, err + } + } + + lhs, err := curves.NewScalarBaseMult(pd.generator.Curve, share.Value.Value) + if err != nil { + return false, err + } + tmp, err := pd.generator.ScalarMult(blinding.Value.Value) + if err != nil { + return false, err + } + lhs, err = lhs.Add(tmp) + if err != nil { + return false, err + } + + // Check if lhs == rhs + return lhs.Equals(rhs), nil +} + +// K256GeneratorFromHashedBytes computes a generator whose discrete log is unknown +// from a bytes sequence +func K256GeneratorFromHashedBytes(bytes []byte) (x, y *big.Int, err error) { + pt := new(curves.PointK256).Hash(bytes) + p, _ := pt.(*curves.PointK256) + x = p.X().BigInt() + y = p.Y().BigInt() + err = nil + return +} diff --git a/pkg/crypto/sharing/v1/polynomial.go b/pkg/crypto/sharing/v1/polynomial.go new file mode 100755 index 000000000..6c8fc9d70 --- /dev/null +++ b/pkg/crypto/sharing/v1/polynomial.go @@ -0,0 +1,49 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type polynomial struct { + Coefficients []*curves.Element +} + +// newPoly creates a random polynomial of the given degree but with the provided intercept value +func newPoly(intercept *curves.Element, degree uint32) (polynomial, error) { + p := polynomial{ + Coefficients: make([]*curves.Element, degree), + } + + // Intercept is the value to be split + p.Coefficients[0] = intercept + + // random coefficients + for i := uint32(1); i < degree; i++ { + c, err := intercept.Field().RandomElement(nil) + if err != nil { + return p, err + } + p.Coefficients[i] = c + } + + return p, nil +} + +// evaluate returns the value of the polynomial for the given x +func (p polynomial) evaluate(x *curves.Element) *curves.Element { + // Compute the polynomial value using Horner's Method + + degree := len(p.Coefficients) - 1 + result := p.Coefficients[degree].Clone() + for i := degree - 1; i >= 0; i-- { + result = result.Mul(x).Add(p.Coefficients[i]) + } + + return result +} diff --git a/pkg/crypto/sharing/v1/polynomial_test.go b/pkg/crypto/sharing/v1/polynomial_test.go new file mode 100755 index 000000000..f94dc76ed --- /dev/null +++ b/pkg/crypto/sharing/v1/polynomial_test.go @@ -0,0 +1,29 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Copyright Coinbase, Inc. All Rights Reserved. +// +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewPoly(t *testing.T) { + secret := field.ElementFromBytes([]byte("test")) + + poly, err := newPoly(secret, 4) + require.Nil(t, err) + require.NotNil(t, poly) + + require.Equal(t, poly.Coefficients[0], secret) +} diff --git a/pkg/crypto/sharing/v1/shamir.go b/pkg/crypto/sharing/v1/shamir.go new file mode 100755 index 000000000..441d47abc --- /dev/null +++ b/pkg/crypto/sharing/v1/shamir.go @@ -0,0 +1,212 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "encoding/binary" + "fmt" + "math/big" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// ShamirShare is the data from splitting a secret +type ShamirShare struct { + // x-coordinate + Identifier uint32 `json:"identifier"` + // y-coordinate + Value *curves.Element `json:"value"` +} + +// NewShamirShare creates a ShamirShare given the Identifier, value, and Field for the value +func NewShamirShare(x uint32, y []byte, f *curves.Field) *ShamirShare { + return &ShamirShare{ + Identifier: x, + Value: f.ElementFromBytes(y), + } +} + +// Bytes returns the representation of the share in bytes with the identifier as the first +// 4 bytes +func (s ShamirShare) Bytes() []byte { + a := make([]byte, 4) + binary.BigEndian.PutUint32(a, s.Identifier) + a = append(a, s.Value.Bytes()...) + return a +} + +// Add returns the sum of two Shamir shares +func (s ShamirShare) Add(other *ShamirShare) *ShamirShare { + if s.Identifier != other.Identifier { + panic("identifiers must match for valid addition") + } + newSecret := s.Value.Add(other.Value) + return NewShamirShare(s.Identifier, newSecret.Bytes(), s.Value.Field()) +} + +// Shamir is the Shamir secret sharing scheme +type Shamir struct { + threshold, limit uint32 + field *curves.Field +} + +// NewShamir creates a Shamir secret sharing scheme +func NewShamir(threshold, limit int, field *curves.Field) (*Shamir, error) { + if limit < threshold { + return nil, fmt.Errorf("limit cannot be less than threshold") + } + if threshold < 2 { + return nil, fmt.Errorf("threshold must be at least 2") + } + return &Shamir{ + uint32(threshold), uint32(limit), field, + }, nil +} + +// Split takes a secret and splits it into multiple shares that requires +// threshold to reconstruct +func (s *Shamir) Split(secret []byte) ([]*ShamirShare, error) { + shares, _, err := s.GetSharesAndPolynomial(secret) + return shares, err +} + +// Combine takes any number of shares and tries to combine them into the original secret +func (s *Shamir) Combine(shares ...*ShamirShare) ([]byte, error) { + if len(shares) < int(s.threshold) { + return nil, fmt.Errorf("not enough shares to combine") + } + + dups := make(map[uint32]bool) + xCoordinates := make([]*curves.Element, s.threshold) + yCoordinates := make([]*curves.Element, s.threshold) + + for i := 0; i < int(s.threshold); i++ { + r := shares[i] + if r.Identifier > s.limit || r.Identifier < 1 { + return nil, fmt.Errorf("invalid share identifier") + } + if _, ok := dups[r.Identifier]; ok { + return nil, fmt.Errorf("duplicate shares cannot be used") + } + + xBytes := make([]byte, 4) + binary.BigEndian.PutUint32(xBytes, r.Identifier) + xCoordinates[i] = s.field.ElementFromBytes(xBytes) + yCoordinates[i] = r.Value + } + + secret, err := s.Interpolate(xCoordinates, yCoordinates) + if err != nil { + return nil, err + } + return secret.Bytes(), nil +} + +// getSharesAndPolynomial returns the shares for the specified secret and the polynomial +// used to create the shares +func (s *Shamir) GetSharesAndPolynomial(secret []byte) ([]*ShamirShare, *polynomial, error) { + if len(secret) == 0 { + return nil, nil, fmt.Errorf("cannot split an empty secret") + } + intSecret := new(big.Int).SetBytes(secret) + if !s.field.IsValid(intSecret) { + return nil, nil, fmt.Errorf("secret is too large") + } + + elemSecret := s.field.NewElement(intSecret) + poly, err := newPoly(elemSecret, s.threshold) + if err != nil { + return nil, nil, fmt.Errorf("failed to generate polynomial: %w", err) + } + + shares := make([]*ShamirShare, s.limit) + for i := uint32(0); i < s.limit; i++ { + x := s.field.NewElement(big.NewInt(int64(i + 1))) + y := poly.evaluate(x) + shares[i] = &ShamirShare{ + Identifier: i + 1, + Value: y, + } + } + return shares, &poly, nil +} + +// interpolate calculates the lagrange interpolation +func (s *Shamir) Interpolate(xCoordinates, yCoordinates []*curves.Element) (*curves.Element, error) { + if len(xCoordinates) < int(s.threshold) || + len(yCoordinates) < int(s.threshold) { + return nil, fmt.Errorf("not enough points") + } + + zero := xCoordinates[0].Field().Zero() + result := yCoordinates[0].Field().Zero() + + for i := 0; i < int(s.threshold); i++ { + basis := xCoordinates[0].Field().One() + for j := 0; j < int(s.threshold); j++ { + if i == j { + continue + } + + // x_m - x_j + denom := xCoordinates[j].Sub(xCoordinates[i]) + if denom.IsEqual(zero) { + return nil, fmt.Errorf("invalid x coordinates") + } + // x_m / x_m - x_j + basis = basis.Mul(xCoordinates[j].Div(denom)) + } + + result = result.Add(yCoordinates[i].Mul(basis)) + } + + return result, nil +} + +// ComputeL is a function that computes all Lagrange coefficients. +// This function is particularly needed in FROST tSchnorr signature. +func (s Shamir) ComputeL(shares ...*ShamirShare) ([]*curves.Element, error) { + if len(shares) < int(s.threshold) { + return nil, fmt.Errorf("Not enough shares to compute Lagrange coefficients") + } + dups := make(map[uint32]bool) + xCoordinates := make([]*curves.Element, s.threshold) + for i := 0; i < int(s.threshold); i++ { + r := shares[i] + if r.Identifier > s.limit || r.Identifier < 1 { + return nil, fmt.Errorf("ComputeL: invalid share identifier") + } + if _, ok := dups[r.Identifier]; ok { + return nil, fmt.Errorf("ComputeL: duplicate shares cannot be used") + } + + xBytes := make([]byte, 4) + binary.BigEndian.PutUint32(xBytes, r.Identifier) + xCoordinates[i] = s.field.ElementFromBytes(xBytes) + } + + zero := xCoordinates[0].Field().Zero() + result := make([]*curves.Element, s.threshold) + + for i := 0; i < int(s.threshold); i++ { + basis := xCoordinates[0].Field().One() + for j := 0; j < int(s.threshold); j++ { + if i == j { + continue + } + // x_m - x_j + denom := xCoordinates[j].Sub(xCoordinates[i]) + if denom.IsEqual(zero) { + return nil, fmt.Errorf("invalid x coordinates") + } + // x_m / x_m - x_j + basis = basis.Mul(xCoordinates[j].Div(denom)) + } + result[i] = basis + } + return result, nil +} diff --git a/pkg/crypto/sharing/v1/shamir_test.go b/pkg/crypto/sharing/v1/shamir_test.go new file mode 100755 index 000000000..0e3073210 --- /dev/null +++ b/pkg/crypto/sharing/v1/shamir_test.go @@ -0,0 +1,205 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package v1 + +import ( + "encoding/json" + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestShamirSplitInvalidArgs(t *testing.T) { + _, err := NewShamir(0, 0, field) + require.NotNil(t, err) + _, err = NewShamir(3, 2, field) + require.NotNil(t, err) + _, err = NewShamir(1, 10, field) + require.NotNil(t, err) + scheme, err := NewShamir(2, 3, field) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Split([]byte{}) + require.NotNil(t, err) + _, err = scheme.Split([]byte{0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65}) + require.NotNil(t, err) +} + +func TestShamirCombineNoShares(t *testing.T) { + scheme, err := NewShamir(2, 3, field) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine() + require.NotNil(t, err) +} + +func TestShamirCombineDuplicateShare(t *testing.T) { + scheme, err := NewShamir(2, 3, field) + require.Nil(t, err) + require.NotNil(t, scheme) + _, err = scheme.Combine([]*ShamirShare{ + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 1, + Value: field.NewElement(big.NewInt(3)), + }, + }...) + require.NotNil(t, err) +} + +func TestShamirCombineBadIdentifier(t *testing.T) { + scheme, err := NewShamir(2, 3, field) + require.Nil(t, err) + require.NotNil(t, scheme) + shares := []*ShamirShare{ + { + Identifier: 0, + Value: field.NewElement(big.NewInt(3)), + }, + { + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + }, + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) + shares[0] = &ShamirShare{ + Identifier: 4, + Value: field.NewElement(big.NewInt(3)), + } + _, err = scheme.Combine(shares...) + require.NotNil(t, err) +} + +func TestShamirCombineSingle(t *testing.T) { + scheme, err := NewShamir(2, 3, field) + require.Nil(t, err) + require.NotNil(t, scheme) + + shares, err := scheme.Split([]byte("test")) + require.Nil(t, err) + require.NotNil(t, shares) + secret, err := scheme.Combine(shares...) + require.Nil(t, err) + require.Equal(t, secret, []byte("test")) +} + +// Test ComputeL function to compute Lagrange coefficients. +func TestShamirComputeL(t *testing.T) { + scheme, err := NewShamir(2, 2, field) + require.Nil(t, err) + require.NotNil(t, scheme) + secret := []byte("test") + shares, err := scheme.Split(secret) + require.Nil(t, err) + require.NotNil(t, shares) + lCoeffs, err := scheme.ComputeL(shares[0], shares[1]) + require.Nil(t, err) + require.NotNil(t, lCoeffs) + + // Checking we can reconstruct the same secret using Lagrange coefficients. + inputShares := [2]*ShamirShare{shares[0], shares[1]} + yCoordinates := make([]*curves.Element, 2) + for i := 0; i < 2; i++ { + r := inputShares[i] + yCoordinates[i] = r.Value + } + result := yCoordinates[0].Field().Zero() + for i := 0; i < 2; i++ { + result = result.Add(yCoordinates[i].Mul(lCoeffs[i])) + } + require.Equal(t, result.Bytes(), secret) +} + +func TestShamirAllCombinations(t *testing.T) { + scheme, err := NewShamir(3, 5, field) + require.Nil(t, err) + require.NotNil(t, scheme) + + secret := []byte("test") + shares, err := scheme.Split(secret) + require.Nil(t, err) + require.NotNil(t, shares) + // There are 5*4*3 possible combinations + for i := 0; i < 5; i++ { + for j := 0; j < 5; j++ { + if i == j { + continue + } + for k := 0; k < 5; k++ { + if i == k || j == k { + continue + } + + rSecret, err := scheme.Combine(shares[i], shares[j], shares[k]) + require.Nil(t, err) + require.NotNil(t, rSecret) + require.Equal(t, rSecret, secret) + } + } + } +} + +// Ensures that ShamirShare's un/marshal successfully. +func TestMarshalJsonRoundTrip(t *testing.T) { + oneBelowModulus := new(big.Int).Sub(modulus, big.NewInt(1)) + shares := []ShamirShare{ + {0, field.NewElement(big.NewInt(300))}, + {2, field.NewElement(big.NewInt(300000))}, + {20, field.NewElement(big.NewInt(12812798))}, + {31, field.NewElement(big.NewInt(17))}, + {57, field.NewElement(big.NewInt(5066680))}, + {128, field.NewElement(big.NewInt(3005))}, + {19, field.NewElement(big.NewInt(317))}, + {7, field.NewElement(big.NewInt(323))}, + {222, field.NewElement(oneBelowModulus)}, + } + // Run all the tests! + for _, in := range shares { + bytes, err := json.Marshal(in) + require.NoError(t, err) + require.NotNil(t, bytes) + + // Unmarshal and test + out := &ShamirShare{} + err = json.Unmarshal(bytes, &out) + require.NoError(t, err) + require.Equal(t, in.Identifier, out.Identifier) + require.Equal(t, in.Value.Value.Bytes(), out.Value.Value.Bytes()) + } +} + +func TestSharesAdd(t *testing.T) { + finiteField := curves.NewField(big.NewInt(7)) + one := NewShamirShare(0, []byte{0x01}, finiteField) + two := NewShamirShare(0, []byte{0x02}, finiteField) + + // basic addition + sum := one.Add(two) + require.Equal(t, uint32(0), sum.Identifier) + require.Equal(t, []byte{0x03}, sum.Value.Bytes()) + + // addition is performed within the globalField + sum = two.Add(NewShamirShare(0, []byte{0x06}, finiteField)) + require.Equal(t, uint32(0), sum.Identifier) + require.Equal(t, []byte{0x01}, sum.Value.Bytes()) +} + +func TestSharesAdd_errors(t *testing.T) { + finiteField := curves.NewField(big.NewInt(7)) + one := NewShamirShare(0, []byte{0x01}, finiteField) + two := NewShamirShare(1, []byte{0x02}, finiteField) + require.PanicsWithValue(t, "identifiers must match for valid addition", func() { + one.Add(two) + }) +} diff --git a/pkg/crypto/signatures/bbs/blind_signature.go b/pkg/crypto/signatures/bbs/blind_signature.go new file mode 100755 index 000000000..41fdcc1fd --- /dev/null +++ b/pkg/crypto/signatures/bbs/blind_signature.go @@ -0,0 +1,79 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + "errors" + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/signatures/common" +) + +// BlindSignature is a BBS+ blind signature +// structurally identical to `Signature` but +// is used to help avoid misuse and confusion. +// +// 1 or more message have been hidden by the +// potential signature holder so the signer +// only knows a subset of the messages to be signed +type BlindSignature struct { + a curves.PairingPoint + e, s curves.Scalar +} + +// Init creates an empty signature to a specific curve +// which should be followed by UnmarshalBinary +func (sig *BlindSignature) Init(curve *curves.PairingCurve) *BlindSignature { + sig.a = curve.NewG1IdentityPoint() + sig.e = curve.NewScalar() + sig.s = curve.NewScalar() + return sig +} + +func (sig BlindSignature) MarshalBinary() ([]byte, error) { + out := append(sig.a.ToAffineCompressed(), sig.e.Bytes()...) + out = append(out, sig.s.Bytes()...) + return out, nil +} + +func (sig *BlindSignature) UnmarshalBinary(data []byte) error { + pointLength := len(sig.a.ToAffineCompressed()) + scalarLength := len(sig.s.Bytes()) + expectedLength := pointLength + scalarLength*2 + if len(data) != expectedLength { + return fmt.Errorf("invalid byte sequence") + } + a, err := sig.a.FromAffineCompressed(data[:pointLength]) + if err != nil { + return err + } + e, err := sig.e.SetBytes(data[pointLength:(pointLength + scalarLength)]) + if err != nil { + return err + } + s, err := sig.s.SetBytes(data[(pointLength + scalarLength):]) + if err != nil { + return err + } + var ok bool + sig.a, ok = a.(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + sig.e = e + sig.s = s + return nil +} + +func (sig BlindSignature) ToUnblinded(blinder common.SignatureBlinding) *Signature { + return &Signature{ + a: sig.a, + e: sig.e, + s: sig.s.Add(blinder), + } +} diff --git a/pkg/crypto/signatures/bbs/blind_signature_context.go b/pkg/crypto/signatures/bbs/blind_signature_context.go new file mode 100755 index 000000000..b1107142b --- /dev/null +++ b/pkg/crypto/signatures/bbs/blind_signature_context.go @@ -0,0 +1,255 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + "fmt" + "io" + "sort" + + "github.com/gtank/merlin" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" + "github.com/onsonr/sonr/pkg/crypto/signatures/common" +) + +// BlindSignatureContext contains the data used for computing +// a blind signature and verifying proof of hidden messages from +// a future signature holder. A potential holder commits to messages +// that the signer will not know during the signing process +// rendering them hidden, but requires the holder to +// prove knowledge of those messages so a malicious party +// doesn't add just random data from anywhere. +type BlindSignatureContext struct { + // The blinded signature commitment + commitment common.Commitment + // The challenge hash for the Fiat-Shamir heuristic + challenge curves.Scalar + // The proofs of hidden messages. + proofs []curves.Scalar +} + +// NewBlindSignatureContext creates the data needed to +// send to a signer to complete a blinded signature +// `msgs` is an index to message map where the index +// corresponds to the index in `generators` +// msgs are hidden from the signer but can also be empty +// if no messages are hidden but a blind signature is still desired +// because the signer should have no knowledge of the signature +func NewBlindSignatureContext(curve *curves.PairingCurve, msgs map[int]curves.Scalar, generators *MessageGenerators, nonce common.Nonce, reader io.Reader) (*BlindSignatureContext, common.SignatureBlinding, error) { + if curve == nil || generators == nil || nonce == nil || reader == nil { + return nil, nil, internal.ErrNilArguments + } + points := make([]curves.Point, 0) + secrets := make([]curves.Scalar, 0) + + committing := common.NewProofCommittedBuilder(&curves.Curve{ + Scalar: curve.Scalar, + Point: curve.Scalar.Point().(curves.PairingPoint).OtherGroup(), + Name: curve.Name, + }) + + // C = h0^blinding_factor*h_i^m_i..... + for i, m := range msgs { + if i > generators.length || i < 0 { + return nil, nil, fmt.Errorf("invalid index") + } + secrets = append(secrets, m) + pt := generators.Get(i + 1) + points = append(points, pt) + err := committing.CommitRandom(pt, reader) + if err != nil { + return nil, nil, err + } + } + blinding, ok := curve.Scalar.Random(reader).(common.SignatureBlinding) + if !ok { + return nil, nil, fmt.Errorf("unable to create signature blinding") + } + secrets = append(secrets, blinding) + + h0 := generators.Get(0) + points = append(points, h0) + err := committing.CommitRandom(h0, reader) + if err != nil { + return nil, nil, err + } + + // Create a random commitment, compute challenges and response. + // The proof of knowledge consists of a commitment and responses + // Holder and signer engage in a proof of knowledge for `commitment` + commitment := curve.Scalar.Point().(curves.PairingPoint).OtherGroup().SumOfProducts(points, secrets) + transcript := merlin.NewTranscript("new blind signature") + transcript.AppendMessage([]byte("random commitment"), committing.GetChallengeContribution()) + transcript.AppendMessage([]byte("blind commitment"), commitment.ToAffineCompressed()) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm := transcript.ExtractBytes([]byte("blind signature context challenge"), 64) + challenge, err := curve.Scalar.SetBytesWide(okm) + if err != nil { + return nil, nil, err + } + proofs, err := committing.GenerateProof(challenge, secrets) + if err != nil { + return nil, nil, err + } + return &BlindSignatureContext{ + commitment: commitment, + challenge: challenge, + proofs: proofs, + }, blinding, nil +} + +func (bsc *BlindSignatureContext) Init(curve *curves.PairingCurve) *BlindSignatureContext { + bsc.challenge = curve.NewScalar() + bsc.commitment = curve.Scalar.Point().(curves.PairingPoint).OtherGroup() + bsc.proofs = make([]curves.Scalar, 0) + return bsc +} + +// MarshalBinary store the generators as a sequence of bytes +// where each point is compressed. +// Needs (N + 1) * ScalarSize + PointSize +func (bsc BlindSignatureContext) MarshalBinary() ([]byte, error) { + buffer := append(bsc.commitment.ToAffineCompressed(), bsc.challenge.Bytes()...) + for _, p := range bsc.proofs { + buffer = append(buffer, p.Bytes()...) + } + return buffer, nil +} + +func (bsc *BlindSignatureContext) UnmarshalBinary(in []byte) error { + scSize := len(bsc.challenge.Bytes()) + ptSize := len(bsc.commitment.ToAffineCompressed()) + if len(in) < scSize*2+ptSize { + return fmt.Errorf("insufficient number of bytes") + } + + if (len(in)-ptSize)%scSize != 0 { + return fmt.Errorf("invalid byte sequence") + } + commitment, err := bsc.commitment.FromAffineCompressed(in[:ptSize]) + if err != nil { + return err + } + challenge, err := bsc.challenge.SetBytes(in[ptSize:(ptSize + scSize)]) + if err != nil { + return err + } + + nProofs := ((len(in) - ptSize) / scSize) - 1 + proofs := make([]curves.Scalar, nProofs) + for i := 0; i < nProofs; i++ { + proofs[i], err = bsc.challenge.SetBytes(in[(ptSize + (i+1)*scSize):(ptSize + (i+2)*scSize)]) + if err != nil { + return err + } + } + bsc.commitment = commitment + bsc.challenge = challenge + bsc.proofs = proofs + return nil +} + +// Verify validates a proof of hidden messages +func (bsc BlindSignatureContext) Verify(knownMsgs []int, generators *MessageGenerators, nonce common.Nonce) error { + known := make(map[int]bool, len(knownMsgs)) + for _, i := range knownMsgs { + if i > generators.length { + return fmt.Errorf("invalid message index") + } + known[i] = true + } + + points := make([]curves.Point, 0) + for i := 0; i < generators.length; i++ { + if _, contains := known[i]; !contains { + points = append(points, generators.Get(i+1)) + } + } + points = append(points, generators.Get(0), bsc.commitment) + scalars := append(bsc.proofs, bsc.challenge.Neg()) + + commitment := points[0].SumOfProducts(points, scalars) + transcript := merlin.NewTranscript("new blind signature") + transcript.AppendMessage([]byte("random commitment"), commitment.ToAffineCompressed()) + transcript.AppendMessage([]byte("blind commitment"), bsc.commitment.ToAffineCompressed()) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm := transcript.ExtractBytes([]byte("blind signature context challenge"), 64) + challenge, err := bsc.challenge.SetBytesWide(okm) + if err != nil { + return err + } + + if challenge.Cmp(bsc.challenge) != 0 { + return fmt.Errorf("invalid proof") + } + return nil +} + +// ToBlindSignature converts a blind signature where +// msgs are known to the signer +// `msgs` is an index to message map where the index +// corresponds to the index in `generators` +func (bsc BlindSignatureContext) ToBlindSignature(msgs map[int]curves.Scalar, sk *SecretKey, generators *MessageGenerators, nonce common.Nonce) (*BlindSignature, error) { + if sk == nil || generators == nil || nonce == nil { + return nil, internal.ErrNilArguments + } + if sk.value.IsZero() { + return nil, fmt.Errorf("invalid secret key") + } + tv1 := make([]int, 0, len(msgs)) + for i := range msgs { + if i > generators.length { + return nil, fmt.Errorf("not enough message generators") + } + tv1 = append(tv1, i) + } + sort.Ints(tv1) + signingMsgs := make([]curves.Scalar, len(msgs)) + for i, index := range tv1 { + signingMsgs[i] = msgs[index] + } + err := bsc.Verify(tv1, generators, nonce) + if err != nil { + return nil, err + } + + drbg := sha3.NewShake256() + _, _ = drbg.Write(sk.value.Bytes()) + addDeterministicNonceData(generators, signingMsgs, drbg) + // Should yield non-zero values for `e` and `s`, very small likelihood of being zero + e := getNonZeroScalar(sk.value, drbg) + s := getNonZeroScalar(sk.value, drbg) + + exp, err := e.Add(sk.value).Invert() + if err != nil { + return nil, err + } + // B = g1+h_0^s+h_1^m_1... + points := make([]curves.Point, len(msgs)+3) + scalars := make([]curves.Scalar, len(msgs)+3) + points[0] = bsc.commitment + points[1] = bsc.commitment.Generator() + points[2] = generators.Get(0) + scalars[0] = sk.value.One() + scalars[1] = sk.value.One() + scalars[2] = s + i := 3 + for idx, m := range msgs { + points[i] = generators.Get(idx + 1) + scalars[i] = m + i++ + } + b := bsc.commitment.SumOfProducts(points, scalars) + return &BlindSignature{ + a: b.Mul(exp).(curves.PairingPoint), + e: e, + s: s, + }, nil +} diff --git a/pkg/crypto/signatures/bbs/blind_signature_context_test.go b/pkg/crypto/signatures/bbs/blind_signature_context_test.go new file mode 100755 index 000000000..25f1b18cd --- /dev/null +++ b/pkg/crypto/signatures/bbs/blind_signature_context_test.go @@ -0,0 +1,98 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + crand "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestBlindSignatureContext(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + require.NotNil(t, pk) + require.NotNil(t, sk) + + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + nonce := curve.Scalar.Random(crand.Reader) + msgs := make(map[int]curves.Scalar, 1) + msgs[0] = curve.Scalar.Hash([]byte("identifier")) + + ctx, blinding, err := NewBlindSignatureContext(curve, msgs, generators, nonce, crand.Reader) + require.NoError(t, err) + require.NotNil(t, blinding) + require.False(t, blinding.IsZero()) + require.NotNil(t, ctx) + require.False(t, ctx.commitment.IsIdentity()) + require.False(t, ctx.challenge.IsZero()) + for _, p := range ctx.proofs { + require.False(t, p.IsZero()) + } + + delete(msgs, 0) + msgs[1] = curve.Scalar.Hash([]byte("firstname")) + msgs[2] = curve.Scalar.Hash([]byte("lastname")) + msgs[3] = curve.Scalar.Hash([]byte("age")) + blindSig, err := ctx.ToBlindSignature(msgs, sk, generators, nonce) + require.NoError(t, err) + require.NotNil(t, blindSig) + require.False(t, blindSig.a.IsIdentity()) + require.False(t, blindSig.e.IsZero()) + require.False(t, blindSig.s.IsZero()) + sig := blindSig.ToUnblinded(blinding) + msgs[0] = curve.Scalar.Hash([]byte("identifier")) + var sigMsgs [4]curves.Scalar + for i := 0; i < 4; i++ { + sigMsgs[i] = msgs[i] + } + err = pk.Verify(sig, generators, sigMsgs[:]) + require.NoError(t, err) +} + +func TestBlindSignatureContextMarshalBinary(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + require.NotNil(t, pk) + require.NotNil(t, sk) + + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + nonce := curve.Scalar.Random(crand.Reader) + msgs := make(map[int]curves.Scalar, 1) + msgs[0] = curve.Scalar.Hash([]byte("identifier")) + + ctx, blinding, err := NewBlindSignatureContext(curve, msgs, generators, nonce, crand.Reader) + require.NoError(t, err) + require.NotNil(t, blinding) + require.False(t, blinding.IsZero()) + require.NotNil(t, ctx) + require.False(t, ctx.commitment.IsIdentity()) + require.False(t, ctx.challenge.IsZero()) + for _, p := range ctx.proofs { + require.False(t, p.IsZero()) + } + + data, err := ctx.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, data) + ctx2 := new(BlindSignatureContext).Init(curve) + err = ctx2.UnmarshalBinary(data) + require.NoError(t, err) + require.Equal(t, ctx.challenge.Cmp(ctx2.challenge), 0) + require.True(t, ctx.commitment.Equal(ctx2.commitment)) + require.Equal(t, len(ctx.proofs), len(ctx2.proofs)) + for i, p := range ctx.proofs { + require.Equal(t, p.Cmp(ctx2.proofs[i]), 0) + } +} diff --git a/pkg/crypto/signatures/bbs/message_generators.go b/pkg/crypto/signatures/bbs/message_generators.go new file mode 100755 index 000000000..f3bcd31e3 --- /dev/null +++ b/pkg/crypto/signatures/bbs/message_generators.go @@ -0,0 +1,77 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + "errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// MessageGenerators are used to sign a vector of commitments for +// a BBS+ signature. These must be the same generators used by +// sign, verify, prove, and open +// +// These are generated in a deterministic manner. By using +// MessageGenerators in this way, the generators do not need to be +// stored alongside the public key and the same key can be used to sign +// an arbitrary number of messages +// Generators are created by computing +// H_i = H_G1(W || I2OSP(0, 4) || I2OSP(0, 1) || I2OSP(length, 4)) +// where I2OSP means Integer to Octet Stream Primitive and +// I2OSP represents an integer in a statically sized byte array. +// `W` is the BBS+ public key. +// Internally we store the 201 byte state since the only value that changes +// is the index +type MessageGenerators struct { + // Blinding factor generator, stored, so we know what points to return in `Get` + h0 curves.PairingPoint + length int + state [201]byte +} + +// Init set the message generators to the default state +func (msgg *MessageGenerators) Init(w *PublicKey, length int) (*MessageGenerators, error) { + if length < 0 { + return nil, errors.New("length should be nonnegative") + } + msgg.length = length + for i := range msgg.state { + msgg.state[i] = 0 + } + copy(msgg.state[:192], w.value.ToAffineUncompressed()) + msgg.state[197] = byte(length >> 24) + msgg.state[198] = byte(length >> 16) + msgg.state[199] = byte(length >> 8) + msgg.state[200] = byte(length) + var ok bool + msgg.h0, ok = w.value.OtherGroup().Hash(msgg.state[:]).(curves.PairingPoint) + if !ok { + return nil, errors.New("incorrect type conversion") + } + + return msgg, nil +} + +func (msgg MessageGenerators) Get(i int) curves.PairingPoint { + if i <= 0 { + return msgg.h0 + } + if i > msgg.length { + return nil + } + state := msgg.state + state[193] = byte(i >> 24) + state[194] = byte(i >> 16) + state[195] = byte(i >> 8) + state[196] = byte(i) + point, ok := msgg.h0.Hash(msgg.state[:]).(curves.PairingPoint) + if !ok { + return nil + } + return point +} diff --git a/pkg/crypto/signatures/bbs/pok_signature.go b/pkg/crypto/signatures/bbs/pok_signature.go new file mode 100755 index 000000000..aba608c01 --- /dev/null +++ b/pkg/crypto/signatures/bbs/pok_signature.go @@ -0,0 +1,159 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + "fmt" + "io" + + "github.com/gtank/merlin" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/signatures/common" +) + +// PokSignature a.k.a. Proof of Knowledge of a Signature +// is used by the prover to convince a verifier +// that they possess a valid signature and +// can selectively disclose a set of signed messages +type PokSignature struct { + // These values correspond to values with the same name + // as section 4.5 in + aPrime, aBar, d curves.PairingPoint + // proof1 for proving signature + // proof2 for selective disclosure + proof1, proof2 *common.ProofCommittedBuilder + // secrets1 for proving signature + // secrets2 for proving relation + // g1 * h1^m1 * h2^m2.... for all disclosed messages + // m_i == d^r3 * h_0^{-s_prime} * h1^-m1 * h2^-m2.... for all undisclosed messages m_i + secrets1, secrets2 []curves.Scalar +} + +// NewPokSignature creates the initial proof data before a Fiat-Shamir calculation +func NewPokSignature(sig *Signature, + generators *MessageGenerators, + msgs []common.ProofMessage, + reader io.Reader, +) (*PokSignature, error) { + if len(msgs) != generators.length { + return nil, fmt.Errorf("mismatch messages and generators") + } + + r1 := getNonZeroScalar(sig.s, reader) + r2 := getNonZeroScalar(sig.s, reader) + r3, err := r1.Invert() + if err != nil { + return nil, err + } + + sigMsgs := make([]curves.Scalar, len(msgs)) + for i, m := range msgs { + sigMsgs[i] = m.GetMessage() + } + + b := computeB(sig.s, sigMsgs, generators) + + aPrime, ok := sig.a.Mul(r1).(curves.PairingPoint) + if !ok { + return nil, fmt.Errorf("invalid point") + } + aBar, ok := b.Mul(r1).Sub(aPrime.Mul(sig.e)).(curves.PairingPoint) + if !ok { + return nil, fmt.Errorf("invalid point") + } + // d = b * r1 + h0 * r2 + d, ok := aPrime.SumOfProducts([]curves.Point{b, generators.h0}, []curves.Scalar{r1, r2}).(curves.PairingPoint) + if !ok { + return nil, fmt.Errorf("invalid point") + } + + // s' = s + r2r3 + sPrime := sig.s.Add(r2.Mul(r3)) + + // For proving relation aBar - d = aPrime * -e + h0 * r2 + curve := curves.Curve{ + Scalar: sig.s.Zero(), + Point: sig.a.Identity(), + } + proof1 := common.NewProofCommittedBuilder(&curve) + // For aPrime * -e + err = proof1.CommitRandom(aPrime, reader) + if err != nil { + return nil, err + } + err = proof1.CommitRandom(generators.h0, reader) + if err != nil { + return nil, err + } + secrets1 := []curves.Scalar{sig.e, r2} + + // For selective disclosure + proof2 := common.NewProofCommittedBuilder(&curve) + // For d * -r3 + err = proof2.CommitRandom(d.Neg(), reader) + if err != nil { + return nil, err + } + // For h0 * s' + err = proof2.CommitRandom(generators.h0, reader) + if err != nil { + return nil, err + } + secrets2 := make([]curves.Scalar, 0, len(msgs)+2) + secrets2 = append(secrets2, r3) + secrets2 = append(secrets2, sPrime) + + for i, m := range msgs { + if m.IsHidden() { + err = proof2.Commit(generators.Get(i+1), m.GetBlinding(reader)) + if err != nil { + return nil, err + } + secrets2 = append(secrets2, m.GetMessage()) + } + } + + return &PokSignature{ + aPrime, + aBar, + d, + proof1, + proof2, + secrets1, + secrets2, + }, nil +} + +// GetChallengeContribution returns the bytes that should be added to +// a sigma protocol transcript for generating the challenge +func (pok *PokSignature) GetChallengeContribution(transcript *merlin.Transcript) { + transcript.AppendMessage([]byte("A'"), pok.aPrime.ToAffineCompressed()) + transcript.AppendMessage([]byte("Abar"), pok.aBar.ToAffineCompressed()) + transcript.AppendMessage([]byte("D"), pok.d.ToAffineCompressed()) + transcript.AppendMessage([]byte("Proof1"), pok.proof1.GetChallengeContribution()) + transcript.AppendMessage([]byte("Proof2"), pok.proof2.GetChallengeContribution()) +} + +// GenerateProof converts the blinding factors and secrets into Schnorr proofs +func (pok *PokSignature) GenerateProof(challenge curves.Scalar) (*PokSignatureProof, error) { + proof1, err := pok.proof1.GenerateProof(challenge, pok.secrets1) + if err != nil { + return nil, err + } + proof2, err := pok.proof2.GenerateProof(challenge, pok.secrets2) + if err != nil { + return nil, err + } + return &PokSignatureProof{ + aPrime: pok.aPrime, + aBar: pok.aBar, + d: pok.d, + proof1: proof1, + proof2: proof2, + }, nil +} diff --git a/pkg/crypto/signatures/bbs/pok_signature_proof.go b/pkg/crypto/signatures/bbs/pok_signature_proof.go new file mode 100755 index 000000000..318bd09d4 --- /dev/null +++ b/pkg/crypto/signatures/bbs/pok_signature_proof.go @@ -0,0 +1,213 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + "errors" + "fmt" + + "github.com/gtank/merlin" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/signatures/common" +) + +// PokSignatureProof is the actual proof sent from a prover +// to a verifier that contains a proof of knowledge of a signature +// and the selective disclosure proof +type PokSignatureProof struct { + aPrime, aBar, d curves.PairingPoint + proof1, proof2 []curves.Scalar +} + +// Init creates an empty proof to a specific curve +// which should be followed by UnmarshalBinary +func (pok *PokSignatureProof) Init(curve *curves.PairingCurve) *PokSignatureProof { + pok.aPrime = curve.Scalar.Point().(curves.PairingPoint).OtherGroup() + pok.aBar = pok.aPrime + pok.d = pok.aPrime + pok.proof1 = []curves.Scalar{ + curve.Scalar.Zero(), + curve.Scalar.Zero(), + } + pok.proof2 = make([]curves.Scalar, 0) + return pok +} + +func (pok *PokSignatureProof) MarshalBinary() ([]byte, error) { + data := append(pok.aPrime.ToAffineCompressed(), pok.aBar.ToAffineCompressed()...) + data = append(data, pok.d.ToAffineCompressed()...) + for _, p := range pok.proof1 { + data = append(data, p.Bytes()...) + } + for _, p := range pok.proof2 { + data = append(data, p.Bytes()...) + } + return data, nil +} + +func (pok *PokSignatureProof) UnmarshalBinary(in []byte) error { + scSize := len(pok.proof1[0].Bytes()) + ptSize := len(pok.aPrime.ToAffineCompressed()) + minSize := scSize*4 + ptSize*3 + inSize := len(in) + if inSize < minSize { + return fmt.Errorf("invalid byte sequence") + } + if (inSize-ptSize)%scSize != 0 { + return fmt.Errorf("invalid byte sequence") + } + secretCnt := ((inSize - ptSize*3) / scSize) - 2 + offset := 0 + end := ptSize + + aPrime, err := pok.aPrime.FromAffineCompressed(in[offset:end]) + if err != nil { + return err + } + offset = end + end += ptSize + aBar, err := pok.aBar.FromAffineCompressed(in[offset:end]) + if err != nil { + return err + } + offset = end + end += ptSize + d, err := pok.d.FromAffineCompressed(in[offset:end]) + if err != nil { + return err + } + offset = end + end += scSize + proof1i0, err := pok.proof1[0].SetBytes(in[offset:end]) + if err != nil { + return err + } + offset = end + end += scSize + proof1i1, err := pok.proof1[1].SetBytes(in[offset:end]) + if err != nil { + return err + } + proof2 := make([]curves.Scalar, secretCnt) + for i := 0; i < secretCnt; i++ { + offset = end + end += scSize + proof2[i], err = pok.proof1[0].SetBytes(in[offset:end]) + if err != nil { + return err + } + } + + var ok bool + pok.aPrime, ok = aPrime.(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + pok.aBar, ok = aBar.(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + pok.d, ok = d.(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + pok.proof1[0] = proof1i0 + pok.proof1[1] = proof1i1 + pok.proof2 = proof2 + return nil +} + +// GetChallengeContribution converts the committed values to bytes +// for the Fiat-Shamir challenge +func (pok PokSignatureProof) GetChallengeContribution( + generators *MessageGenerators, + revealedMessages map[int]curves.Scalar, + challenge common.Challenge, + transcript *merlin.Transcript, +) { + transcript.AppendMessage([]byte("A'"), pok.aPrime.ToAffineCompressed()) + transcript.AppendMessage([]byte("Abar"), pok.aBar.ToAffineCompressed()) + transcript.AppendMessage([]byte("D"), pok.d.ToAffineCompressed()) + + proof1Points := []curves.Point{pok.aBar.Sub(pok.d), pok.aPrime, generators.h0} + proof1Scalars := []curves.Scalar{challenge, pok.proof1[0], pok.proof1[1]} + commitmentProof1 := pok.aPrime.SumOfProducts(proof1Points, proof1Scalars) + transcript.AppendMessage([]byte("Proof1"), commitmentProof1.ToAffineCompressed()) + + rPoints := make([]curves.Point, 1, len(revealedMessages)+1) + rScalars := make([]curves.Scalar, 1, len(revealedMessages)+1) + + rPoints[0] = pok.aPrime.Generator() + rScalars[0] = pok.proof1[0].One() + + for idx, msg := range revealedMessages { + rPoints = append(rPoints, generators.Get(idx+1)) + rScalars = append(rScalars, msg) + } + + r := pok.aPrime.SumOfProducts(rPoints, rScalars) + + pts := 3 + generators.length - len(revealedMessages) + proof2Points := make([]curves.Point, 3, pts) + proof2Scalars := make([]curves.Scalar, 3, pts) + + // R * c + proof2Points[0] = r + proof2Scalars[0] = challenge + + // D * -r3Hat + proof2Points[1] = pok.d.Neg() + proof2Scalars[1] = pok.proof2[0] + + // H0 * s'Hat + proof2Points[2] = generators.h0 + proof2Scalars[2] = pok.proof2[1] + + j := 2 + for i := 0; i < generators.length; i++ { + if _, contains := revealedMessages[i]; contains { + continue + } + proof2Points = append(proof2Points, generators.Get(i+1)) + proof2Scalars = append(proof2Scalars, pok.proof2[j]) + j++ + } + commitmentProof2 := r.SumOfProducts(proof2Points, proof2Scalars) + + transcript.AppendMessage([]byte("Proof2"), commitmentProof2.ToAffineCompressed()) +} + +// VerifySigPok only validates the signature proof, +// the selective disclosure proof is checked by +// verifying +// pok.challenge == computedChallenge +func (pok PokSignatureProof) VerifySigPok(pk *PublicKey) bool { + return !pk.value.IsIdentity() && + !pok.aPrime.IsIdentity() && + !pok.aBar.IsIdentity() && + pok.aPrime.MultiPairing(pok.aPrime, pk.value, pok.aBar, pk.value.Generator().Neg().(curves.PairingPoint)).IsOne() +} + +// Verify checks a signature proof of knowledge and selective disclosure proof +func (pok PokSignatureProof) Verify( + revealedMsgs map[int]curves.Scalar, + pk *PublicKey, + generators *MessageGenerators, + nonce common.Nonce, + challenge common.Challenge, + transcript *merlin.Transcript, +) bool { + pok.GetChallengeContribution(generators, revealedMsgs, challenge, transcript) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm := transcript.ExtractBytes([]byte("signature proof of knowledge"), 64) + vChallenge, err := pok.proof1[0].SetBytesWide(okm) + if err != nil { + return false + } + return pok.VerifySigPok(pk) && challenge.Cmp(vChallenge) == 0 +} diff --git a/pkg/crypto/signatures/bbs/pok_signature_proof_test.go b/pkg/crypto/signatures/bbs/pok_signature_proof_test.go new file mode 100755 index 000000000..a84fc1a8e --- /dev/null +++ b/pkg/crypto/signatures/bbs/pok_signature_proof_test.go @@ -0,0 +1,317 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + crand "crypto/rand" + "testing" + + "github.com/gtank/merlin" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/signatures/common" +) + +func TestPokSignatureProofSomeMessagesRevealed(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + require.NotNil(t, sk) + require.NotNil(t, pk) + require.False(t, sk.value.IsZero()) + require.False(t, pk.value.IsIdentity()) + _, ok := pk.value.(*curves.PointBls12381G2) + require.True(t, ok) + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + msgs := []curves.Scalar{ + curve.Scalar.New(2), + curve.Scalar.New(3), + curve.Scalar.New(4), + curve.Scalar.New(5), + } + + sig, err := sk.Sign(generators, msgs) + require.NoError(t, err) + require.NotNil(t, sig) + require.False(t, sig.a.IsIdentity()) + require.False(t, sig.e.IsZero()) + require.False(t, sig.s.IsZero()) + + proofMsgs := []common.ProofMessage{ + &common.ProofSpecificMessage{ + Message: msgs[0], + }, + &common.ProofSpecificMessage{ + Message: msgs[1], + }, + &common.RevealedMessage{ + Message: msgs[2], + }, + &common.RevealedMessage{ + Message: msgs[3], + }, + } + + pok, err := NewPokSignature(sig, generators, proofMsgs, crand.Reader) + require.NoError(t, err) + require.NotNil(t, pok) + nonce := curve.Scalar.Random(crand.Reader) + transcript := merlin.NewTranscript("TestPokSignatureProofWorks") + pok.GetChallengeContribution(transcript) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm := transcript.ExtractBytes([]byte("signature proof of knowledge"), 64) + challenge, err := curve.Scalar.SetBytesWide(okm) + require.NoError(t, err) + + pokSig, err := pok.GenerateProof(challenge) + require.NoError(t, err) + require.NotNil(t, pokSig) + require.True(t, pokSig.VerifySigPok(pk)) + + revealedMsgs := map[int]curves.Scalar{ + 2: msgs[2], + 3: msgs[3], + } + // Manual verify to show how when used in conjunction with other ZKPs + transcript = merlin.NewTranscript("TestPokSignatureProofWorks") + pokSig.GetChallengeContribution(generators, revealedMsgs, challenge, transcript) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm = transcript.ExtractBytes([]byte("signature proof of knowledge"), 64) + vChallenge, err := curve.Scalar.SetBytesWide(okm) + require.NoError(t, err) + require.Equal(t, challenge.Cmp(vChallenge), 0) + + // Use the all-inclusive method + transcript = merlin.NewTranscript("TestPokSignatureProofWorks") + require.True(t, pokSig.Verify(revealedMsgs, pk, generators, nonce, challenge, transcript)) +} + +func TestPokSignatureProofAllMessagesRevealed(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + require.NotNil(t, sk) + require.NotNil(t, pk) + require.False(t, sk.value.IsZero()) + require.False(t, pk.value.IsIdentity()) + _, ok := pk.value.(*curves.PointBls12381G2) + require.True(t, ok) + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + msgs := []curves.Scalar{ + curve.Scalar.New(2), + curve.Scalar.New(3), + curve.Scalar.New(4), + curve.Scalar.New(5), + } + + sig, err := sk.Sign(generators, msgs) + require.NoError(t, err) + require.NotNil(t, sig) + require.False(t, sig.a.IsIdentity()) + require.False(t, sig.e.IsZero()) + require.False(t, sig.s.IsZero()) + + proofMsgs := []common.ProofMessage{ + &common.RevealedMessage{ + Message: msgs[0], + }, + &common.RevealedMessage{ + Message: msgs[1], + }, + &common.RevealedMessage{ + Message: msgs[2], + }, + &common.RevealedMessage{ + Message: msgs[3], + }, + } + + pok, err := NewPokSignature(sig, generators, proofMsgs, crand.Reader) + require.NoError(t, err) + require.NotNil(t, pok) + nonce := curve.Scalar.Random(crand.Reader) + transcript := merlin.NewTranscript("TestPokSignatureProofWorks") + pok.GetChallengeContribution(transcript) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm := transcript.ExtractBytes([]byte("signature proof of knowledge"), 64) + challenge, err := curve.Scalar.SetBytesWide(okm) + require.NoError(t, err) + + pokSig, err := pok.GenerateProof(challenge) + require.NoError(t, err) + require.NotNil(t, pokSig) + require.True(t, pokSig.VerifySigPok(pk)) + + revealedMsgs := map[int]curves.Scalar{ + 0: msgs[0], + 1: msgs[1], + 2: msgs[2], + 3: msgs[3], + } + // Manual verify to show how when used in conjunction with other ZKPs + transcript = merlin.NewTranscript("TestPokSignatureProofWorks") + pokSig.GetChallengeContribution(generators, revealedMsgs, challenge, transcript) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm = transcript.ExtractBytes([]byte("signature proof of knowledge"), 64) + vChallenge, err := curve.Scalar.SetBytesWide(okm) + require.NoError(t, err) + require.Equal(t, challenge.Cmp(vChallenge), 0) + + // Use the all-inclusive method + transcript = merlin.NewTranscript("TestPokSignatureProofWorks") + require.True(t, pokSig.Verify(revealedMsgs, pk, generators, nonce, challenge, transcript)) +} + +func TestPokSignatureProofAllMessagesHidden(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + require.NotNil(t, sk) + require.NotNil(t, pk) + require.False(t, sk.value.IsZero()) + require.False(t, pk.value.IsIdentity()) + _, ok := pk.value.(*curves.PointBls12381G2) + require.True(t, ok) + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + msgs := []curves.Scalar{ + curve.Scalar.New(2), + curve.Scalar.New(3), + curve.Scalar.New(4), + curve.Scalar.New(5), + } + + sig, err := sk.Sign(generators, msgs) + require.NoError(t, err) + require.NotNil(t, sig) + require.False(t, sig.a.IsIdentity()) + require.False(t, sig.e.IsZero()) + require.False(t, sig.s.IsZero()) + + proofMsgs := []common.ProofMessage{ + &common.ProofSpecificMessage{ + Message: msgs[0], + }, + &common.ProofSpecificMessage{ + Message: msgs[1], + }, + &common.ProofSpecificMessage{ + Message: msgs[2], + }, + &common.ProofSpecificMessage{ + Message: msgs[3], + }, + } + + pok, err := NewPokSignature(sig, generators, proofMsgs, crand.Reader) + require.NoError(t, err) + require.NotNil(t, pok) + nonce := curve.Scalar.Random(crand.Reader) + transcript := merlin.NewTranscript("TestPokSignatureProofWorks") + pok.GetChallengeContribution(transcript) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm := transcript.ExtractBytes([]byte("signature proof of knowledge"), 64) + challenge, err := curve.Scalar.SetBytesWide(okm) + require.NoError(t, err) + + pokSig, err := pok.GenerateProof(challenge) + require.NoError(t, err) + require.NotNil(t, pokSig) + require.True(t, pokSig.VerifySigPok(pk)) + + revealedMsgs := map[int]curves.Scalar{} + + // Manual verify to show how when used in conjunction with other ZKPs + transcript = merlin.NewTranscript("TestPokSignatureProofWorks") + pokSig.GetChallengeContribution(generators, revealedMsgs, challenge, transcript) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + okm = transcript.ExtractBytes([]byte("signature proof of knowledge"), 64) + vChallenge, err := curve.Scalar.SetBytesWide(okm) + require.NoError(t, err) + require.Equal(t, challenge.Cmp(vChallenge), 0) + + // Use the all-inclusive method + transcript = merlin.NewTranscript("TestPokSignatureProofWorks") + require.True(t, pokSig.Verify(revealedMsgs, pk, generators, nonce, challenge, transcript)) +} + +func TestPokSignatureProofMarshalBinary(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + require.NotNil(t, sk) + require.NotNil(t, pk) + require.False(t, sk.value.IsZero()) + require.False(t, pk.value.IsIdentity()) + _, ok := pk.value.(*curves.PointBls12381G2) + require.True(t, ok) + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + msgs := []curves.Scalar{ + curve.Scalar.New(2), + curve.Scalar.New(3), + curve.Scalar.New(4), + curve.Scalar.New(5), + } + + sig, err := sk.Sign(generators, msgs) + require.NoError(t, err) + require.NotNil(t, sig) + require.False(t, sig.a.IsIdentity()) + require.False(t, sig.e.IsZero()) + require.False(t, sig.s.IsZero()) + + proofMsgs := []common.ProofMessage{ + &common.ProofSpecificMessage{ + Message: msgs[0], + }, + &common.ProofSpecificMessage{ + Message: msgs[1], + }, + &common.RevealedMessage{ + Message: msgs[2], + }, + &common.RevealedMessage{ + Message: msgs[3], + }, + } + + pok, err := NewPokSignature(sig, generators, proofMsgs, crand.Reader) + require.NoError(t, err) + require.NotNil(t, pok) + nonce := curve.Scalar.Random(crand.Reader) + transcript := merlin.NewTranscript("TestPokSignatureProofMarshalBinary") + pok.GetChallengeContribution(transcript) + transcript.AppendMessage([]byte("nonce"), nonce.Bytes()) + challenge, err := curve.Scalar.SetBytesWide(transcript.ExtractBytes([]byte("signature proof of knowledge"), 64)) + require.NoError(t, err) + + pokSig, err := pok.GenerateProof(challenge) + require.NoError(t, err) + require.NotNil(t, pokSig) + + data, err := pokSig.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, data) + pokSig2 := new(PokSignatureProof).Init(curve) + err = pokSig2.UnmarshalBinary(data) + require.NoError(t, err) + require.True(t, pokSig.aPrime.Equal(pokSig2.aPrime)) + require.True(t, pokSig.aBar.Equal(pokSig2.aBar)) + require.True(t, pokSig.d.Equal(pokSig2.d)) + require.Equal(t, len(pokSig.proof1), len(pokSig2.proof1)) + require.Equal(t, len(pokSig.proof2), len(pokSig2.proof2)) + for i, p := range pokSig.proof1 { + require.Equal(t, p.Cmp(pokSig2.proof1[i]), 0) + } + for i, p := range pokSig.proof2 { + require.Equal(t, p.Cmp(pokSig2.proof2[i]), 0) + } +} diff --git a/pkg/crypto/signatures/bbs/public_key.go b/pkg/crypto/signatures/bbs/public_key.go new file mode 100755 index 000000000..ff61a30b7 --- /dev/null +++ b/pkg/crypto/signatures/bbs/public_key.go @@ -0,0 +1,73 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + "errors" + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// PublicKey is a BBS+ verification key +type PublicKey struct { + value curves.PairingPoint +} + +func (pk *PublicKey) Init(curve *curves.PairingCurve) *PublicKey { + pk.value = curve.NewG2IdentityPoint() + return pk +} + +func (pk PublicKey) MarshalBinary() ([]byte, error) { + return pk.value.ToAffineCompressed(), nil +} + +func (pk *PublicKey) UnmarshalBinary(in []byte) error { + value, err := pk.value.FromAffineCompressed(in) + if err != nil { + return err + } + var ok bool + pk.value, ok = value.(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + return nil +} + +// Verify checks a signature where all messages are known to the verifier +func (pk PublicKey) Verify(signature *Signature, generators *MessageGenerators, msgs []curves.Scalar) error { + if generators.length < len(msgs) { + return fmt.Errorf("not enough message generators") + } + if len(msgs) < 1 { + return fmt.Errorf("invalid messages") + } + // Identity Point will always return true which is not what we want + if pk.value.IsIdentity() { + return fmt.Errorf("invalid public key") + } + if signature.a.IsIdentity() { + return fmt.Errorf("invalid signature") + } + a, ok := pk.value.Generator().Mul(signature.e).Add(pk.value).(curves.PairingPoint) + if !ok { + return fmt.Errorf("not a valid point") + } + b, ok := computeB(signature.s, msgs, generators).Neg().(curves.PairingPoint) + if !ok { + return fmt.Errorf("not a valid point") + } + + res := a.MultiPairing(signature.a, a, b, pk.value.Generator().(curves.PairingPoint)) + if !res.IsOne() { + return fmt.Errorf("invalid result") + } + + return nil +} diff --git a/pkg/crypto/signatures/bbs/secret_key.go b/pkg/crypto/signatures/bbs/secret_key.go new file mode 100755 index 000000000..a46ec7503 --- /dev/null +++ b/pkg/crypto/signatures/bbs/secret_key.go @@ -0,0 +1,177 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + crand "crypto/rand" + "crypto/sha256" + "errors" + "fmt" + "io" + + "golang.org/x/crypto/hkdf" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// SecretKey is a BBS+ signing key +type SecretKey struct { + value curves.PairingScalar +} + +func NewSecretKey(curve *curves.PairingCurve) (*SecretKey, error) { + // The salt used with generating secret keys + // See section 2.3 from https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04 + const hkdfKeyGenSalt = "BLS-SIG-KEYGEN-SALT-" + const Size = 33 + var ikm [Size]byte + cnt, err := crand.Read(ikm[:32]) + if err != nil { + return nil, err + } + if cnt != Size-1 { + return nil, fmt.Errorf("unable to read sufficient random data") + } + + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04#section-2.3 + h := sha256.New() + n, err := h.Write([]byte(hkdfKeyGenSalt)) + if err != nil { + return nil, err + } + if n != len(hkdfKeyGenSalt) { + return nil, fmt.Errorf("incorrect salt bytes written to be hashed") + } + salt := h.Sum(nil) + + // Leaves key_info parameter as the default empty string + // and just adds parameter I2OSP(L, 2) + kdf := hkdf.New(sha256.New, ikm[:], salt, []byte{0, 48}) + var okm [64]byte + read, err := kdf.Read(okm[:48]) + if err != nil { + return nil, err + } + if read != 48 { + return nil, fmt.Errorf("failed to create secret key") + } + v, err := curve.Scalar.SetBytesWide(okm[:]) + if err != nil { + return nil, err + } + value, ok := v.(curves.PairingScalar) + if !ok { + return nil, fmt.Errorf("invalid scalar") + } + return &SecretKey{ + value: value.SetPoint(curve.PointG2), + }, nil +} + +func NewKeys(curve *curves.PairingCurve) (*PublicKey, *SecretKey, error) { + sk, err := NewSecretKey(curve) + if err != nil { + return nil, nil, err + } + return sk.PublicKey(), sk, nil +} + +func (sk *SecretKey) Init(curve *curves.PairingCurve) *SecretKey { + sk.value = curve.NewScalar() + return sk +} + +func (sk SecretKey) MarshalBinary() ([]byte, error) { + return sk.value.Bytes(), nil +} + +func (sk *SecretKey) UnmarshalBinary(in []byte) error { + value, err := sk.value.SetBytes(in) + if err != nil { + return err + } + var ok bool + sk.value, ok = value.(curves.PairingScalar) + if !ok { + return errors.New("incorrect type conversion") + } + return nil +} + +// Sign generates a new signature where all messages are known to the signer +func (sk *SecretKey) Sign(generators *MessageGenerators, msgs []curves.Scalar) (*Signature, error) { + if generators.length < len(msgs) { + return nil, fmt.Errorf("not enough message generators") + } + if len(msgs) < 1 { + return nil, fmt.Errorf("invalid messages") + } + if sk.value.IsZero() { + return nil, fmt.Errorf("invalid secret key") + } + + drbg := sha3.NewShake256() + _, _ = drbg.Write(sk.value.Bytes()) + addDeterministicNonceData(generators, msgs, drbg) + // Should yield non-zero values for `e` and `s`, very small likelihood of being zero + e := getNonZeroScalar(sk.value, drbg) + s := getNonZeroScalar(sk.value, drbg) + b := computeB(s, msgs, generators) + exp, err := e.Add(sk.value).Invert() + if err != nil { + return nil, err + } + return &Signature{ + a: b.Mul(exp).(curves.PairingPoint), + e: e, + s: s, + }, nil +} + +// PublicKey returns the corresponding public key +func (sk *SecretKey) PublicKey() *PublicKey { + return &PublicKey{ + value: sk.value.Point().Generator().Mul(sk.value).(curves.PairingPoint), + } +} + +// computes g1 + s * h0 + msgs[0] * h[0] + msgs[1] * h[1] ... +func computeB(s curves.Scalar, msgs []curves.Scalar, generators *MessageGenerators) curves.PairingPoint { + nMsgs := len(msgs) + points := make([]curves.Point, nMsgs+2) + points[1] = generators.Get(0) + points[0] = points[1].Generator() + + scalars := make([]curves.Scalar, nMsgs+2) + scalars[0] = msgs[0].One() + scalars[1] = s + for i, m := range msgs { + points[i+2] = generators.Get(i + 1) + scalars[i+2] = m + } + pt := points[0].SumOfProducts(points, scalars) + return pt.(curves.PairingPoint) +} + +func addDeterministicNonceData(generators *MessageGenerators, msgs []curves.Scalar, drbg io.Writer) { + for i := 0; i <= generators.length; i++ { + _, _ = drbg.Write(generators.Get(i).ToAffineUncompressed()) + } + for _, m := range msgs { + _, _ = drbg.Write(m.Bytes()) + } +} + +func getNonZeroScalar(sc curves.Scalar, reader io.Reader) curves.Scalar { + // Should yield non-zero values for `e` and `s`, very small likelihood of being zero + e := sc.Random(reader) + for e.IsZero() { + e = sc.Random(reader) + } + return e +} diff --git a/pkg/crypto/signatures/bbs/signature.go b/pkg/crypto/signatures/bbs/signature.go new file mode 100755 index 000000000..4bfc1e9d0 --- /dev/null +++ b/pkg/crypto/signatures/bbs/signature.go @@ -0,0 +1,67 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package bbs is an implementation of BBS+ signature of https://eprint.iacr.org/2016/663.pdf +package bbs + +import ( + "errors" + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// Signature is a BBS+ signature +// as described in 4.3 in +// +type Signature struct { + a curves.PairingPoint + e, s curves.Scalar +} + +// Init creates an empty signature to a specific curve +// which should be followed by UnmarshalBinary or Create +func (sig *Signature) Init(curve *curves.PairingCurve) *Signature { + sig.a = curve.NewG1IdentityPoint() + sig.e = curve.NewScalar() + sig.s = curve.NewScalar() + return sig +} + +func (sig Signature) MarshalBinary() ([]byte, error) { + out := append(sig.a.ToAffineCompressed(), sig.e.Bytes()...) + out = append(out, sig.s.Bytes()...) + return out, nil +} + +func (sig *Signature) UnmarshalBinary(data []byte) error { + pointLength := len(sig.a.ToAffineCompressed()) + scalarLength := len(sig.s.Bytes()) + expectedLength := pointLength + scalarLength*2 + if len(data) != expectedLength { + return fmt.Errorf("invalid byte sequence") + } + a, err := sig.a.FromAffineCompressed(data[:pointLength]) + if err != nil { + return err + } + e, err := sig.e.SetBytes(data[pointLength:(pointLength + scalarLength)]) + if err != nil { + return err + } + s, err := sig.s.SetBytes(data[(pointLength + scalarLength):]) + if err != nil { + return err + } + var ok bool + sig.a, ok = a.(curves.PairingPoint) + if !ok { + return errors.New("incorrect type conversion") + } + sig.e = e + sig.s = s + return nil +} diff --git a/pkg/crypto/signatures/bbs/signature_test.go b/pkg/crypto/signatures/bbs/signature_test.go new file mode 100755 index 000000000..42fc3e1b4 --- /dev/null +++ b/pkg/crypto/signatures/bbs/signature_test.go @@ -0,0 +1,81 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bbs + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestSignatureWorks(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + msgs := []curves.Scalar{ + curve.Scalar.New(3), + curve.Scalar.New(4), + curve.Scalar.New(5), + curve.Scalar.New(6), + } + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + + sig, err := sk.Sign(generators, msgs) + require.NoError(t, err) + err = pk.Verify(sig, generators, msgs) + require.NoError(t, err) +} + +func TestSignatureIncorrectMessages(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + msgs := []curves.Scalar{ + curve.Scalar.New(3), + curve.Scalar.New(4), + curve.Scalar.New(5), + curve.Scalar.New(6), + } + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + + sig, err := sk.Sign(generators, msgs) + require.NoError(t, err) + msgs[0] = curve.Scalar.New(7) + err = pk.Verify(sig, generators, msgs) + require.Error(t, err) +} + +func TestSignatureMarshalBinary(t *testing.T) { + curve := curves.BLS12381(&curves.PointBls12381G2{}) + msgs := []curves.Scalar{ + curve.Scalar.New(3), + curve.Scalar.New(4), + curve.Scalar.New(5), + curve.Scalar.New(6), + } + pk, sk, err := NewKeys(curve) + require.NoError(t, err) + generators, err := new(MessageGenerators).Init(pk, 4) + require.NoError(t, err) + + sig, err := sk.Sign(generators, msgs) + require.NoError(t, err) + + data, err := sig.MarshalBinary() + require.NoError(t, err) + require.Equal(t, 112, len(data)) + sig2 := new(Signature).Init(curve) + err = sig2.UnmarshalBinary(data) + require.NoError(t, err) + require.True(t, sig.a.Equal(sig2.a)) + require.Equal(t, sig.e.Cmp(sig2.e), 0) + require.Equal(t, sig.s.Cmp(sig2.s), 0) +} diff --git a/pkg/crypto/signatures/bls/README.md b/pkg/crypto/signatures/bls/README.md new file mode 100755 index 000000000..d46edf982 --- /dev/null +++ b/pkg/crypto/signatures/bls/README.md @@ -0,0 +1,114 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## BLS Signatures + +An implementation of the Boneh-Lynn-Shacham (BLS) signatures according to the [standard](https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature/?include_text=1) +on top of the Barreto-Lynn-Scott (BLS) 12-381 curve. The [BLS12-381 curve](https://github.com/zkcrypto/pairing/tree/master/src/bls12_381#serialization) provides roughly +128-bits of security and BLS is a digital signature with aggregation properties. + +We have implemented all three signature schemes described in the [standard](https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature/?include_text=1) +which are designed to handle rogue-key attacks differently. These three are: + +- **Basic** handles rogue key attacks by requiring all signed messages in an aggregate signature be distinct +- **Message Augmentation** handles rogue key attacks by prepending the public key to the message during signing which ensures that all messages are distinct for different public keys. +- **Proof of Possession** handles rogue key attacks by validating public keys in a separate step called a proof of possession. This allows for faster aggregate verification. + +Pairing-friendly curves have two generator-groups 𝔾1, 𝔾2. +Data in 𝔾2 is twice the size of 𝔾1 and operations are slower. +BLS signatures require signatures and public keys to be in opposite groups i.e. signatures in 𝔾1 and public keys in 𝔾2 or +signatures in 𝔾2 and public keys in 𝔾1. This means one of two things: + +- **Short public keys, long signatures**: Signatures are longer and slower to create, verify, and aggregate but public keys are small and fast to aggregate. Used when signing and verification operations not computed as often or for minimizing storage or bandwidth for public keys. +- **Short signatures, long public keys**: Signatures are short and fast to create, verify, and aggregate but public keys are bigger and slower to aggregate. Used when signing and verification operations are computed often or for minimizing storage or bandwidth for signatures. + +This library supports both of these variants for all three signature schemes. The more widely deployed +variant is short public keys, long signatures. We refer to this variant as `UsualBls`. The other variant, +short signatures, long public keys, is named `TinyBls`. +The naming convention follows Sig`SchemeType`[Vt] where **Vt** is short for variant. For example, + +- **Usual Bls Basic -> SigBasic**: Provides all the functions for the Basic signature scheme with signatures in 𝔾2 and public keys in 𝔾1 +- **Tiny Bls Basic -> SigBasicVt**: Provides all the functions for the Basic signature scheme with signatures in 𝔾1 and public keys in 𝔾2 + +One final note, in cryptography, it is considered good practice to use domain separation values to limit attacks to specific contexts. The [standard](https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature/?include_text=1) +recommends specific values for each scheme but this library also supports supplying custom domain separation values. For example, there are two functions for creating +a BLS signing instance: + +- **NewSigBasic()** creates a Basic BLS signature using the recommended domain separation value. +- **NewSigBasicWithDst(dst)** creates a Basic BLS signature using the parameter `dst` as the domain separation value such as in the [Eth2.0 Spec](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/validator.md#attestation-aggregation) + +Also implemented is Threshold BLS as described in section 3.2 of [B03](https://www.cc.gatech.edu/~aboldyre/papers/bold.pdf). + +- ThresholdKeygen(parts, threshold int) -> ([]\*SecretKeyShare, error) +- PartialSign(share *SecretKeyShare, msg []byte) -> *PartialSignature +- CombineSigs(*PartialSignature…) -> *Signature + +### Security Considerations + +#### Validating Secret Keys + +Low entropy secret keys are a problem since this means an attacker can more easily guess the value and now can impersonate the key holder. +Secret keys are derived using trusted random number generators (TRNG). If the TRNG produces bad entropy +the secret key will be weak. Secret keys are checked to be non-zero values. A zero value secret key +not only fails the entropy test but also yields a public key that will validate any signature. + +#### Validating Public Keys + +Public keys are ensured to be valid. A valid public key means +it represents a valid, non-identity elliptic curve point in the correct subgroup. +Public keys that are the identity element mean any signature would pass a call to verify. + +#### Validating Signatures + +Generated signatures are ensured to be valid. A valid signature means +it represents a valid, non-identity elliptic curve point in the correct subgroup. +Signatures that are the identity element mean any signature would pass a call to verify. +Verify checks signatures for non-identity elements in the correct subgroup before checking +for a valid signature. + +#### Mitigating Rogue Key Attacks + +A rogue key attacks can only happen to multisignature or aggregated signature. +A rogue key attack is where at least one party produces a valid but malicious public key such that the multisignature requires less than the threshold to verify a signature. +There are two ways to mitigate rogue key attacks: Guarantee all signed messages are unique or validate each public key before use. This library offers both solutions. + +### Comparison to other BLS Implementations and Integrations + +This library has been tested to be compatible with the following implementations +by randomly generating millions of keys and signatures and importing and verifying +between the two libraries. + +1. Ethereum's [py_ecc](https://github.com/ethereum/py_ecc) +2. PhoreProject [Go BLS](https://github.com/phoreproject/bls) +3. Herumi's [BLS](https://github.com/herumi/bls-eth-go-binary) +4. Algorand's [Rust BLS Sig](https://crates.io/crates/bls_sigs_ref) +5. Miracl's [Rust and Go BLS sig](https://github.com/miracl/core) + +The most common and high risk failures that can occur with library implementations +are low entropy secret keys, malformed public keys, and invalid signature generation. + +Low entropy secret keys are a problem since this means an attacker can more easily guess +the value and now can impersonate the key holder. + +Malformed public keys and signatures result in invalid addresses and no ability to withdraw funds. + +To check for these problems, We tested millions of keys/signatures (vs say thousands or hundreds) to prove that + +1. The odds of producing an invalid key/signature is already theoretically low 2-255 +2. The results of running millions of checks shows that nothing bad happened in 10M attempts + +In other words, keys and signatures generated from these libraries can be consumed by this library +and visa-versa. + +Some of the libraries implementations for hash to curve were either out of date +or not compliant with the [IETF Spec](https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/). +This meant that signatures generated by this library would not validate with others and visa-versa. +However, public keys were found to be compatible in all libraries. + +This library is compliant with the latest version (10 as of this writing). diff --git a/pkg/crypto/signatures/bls/bls_sig/lib.go b/pkg/crypto/signatures/bls/bls_sig/lib.go new file mode 100755 index 000000000..845a2954a --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/lib.go @@ -0,0 +1,208 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package bls_sig is an implementation of the BLS signature defined in https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +package bls_sig + +import ( + "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "fmt" + + "golang.org/x/crypto/hkdf" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" + "github.com/onsonr/sonr/pkg/crypto/internal" + "github.com/onsonr/sonr/pkg/crypto/sharing" +) + +// Secret key in Fr +const SecretKeySize = 32 + +// Secret key share with identifier byte in Fr +const SecretKeyShareSize = 33 + +// The salt used with generating secret keys +// See section 2.3 from https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +const hkdfKeyGenSalt = "BLS-SIG-KEYGEN-SALT-" + +// Represents a value mod r where r is the curve order or +// order of the subgroups in G1 and G2 +type SecretKey struct { + value *native.Field +} + +func allRowsUnique(data [][]byte) bool { + seen := make(map[string]bool) + for _, row := range data { + m := string(row) + if _, ok := seen[m]; ok { + return false + } + seen[m] = true + } + return true +} + +func generateRandBytes(count int) ([]byte, error) { + ikm := make([]byte, count) + cnt, err := rand.Read(ikm) + if err != nil { + return nil, err + } + if cnt != count { + return nil, fmt.Errorf("unable to read sufficient random data") + } + return ikm, nil +} + +// Creates a new BLS secret key +// Input key material (ikm) MUST be at least 32 bytes long, +// but it MAY be longer. +func (sk SecretKey) Generate(ikm []byte) (*SecretKey, error) { + if len(ikm) < 32 { + return nil, fmt.Errorf("ikm is too short. Must be at least 32") + } + + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04#section-2.3 + h := sha256.New() + n, err := h.Write([]byte(hkdfKeyGenSalt)) + if err != nil { + return nil, err + } + if n != len(hkdfKeyGenSalt) { + return nil, fmt.Errorf("incorrect salt bytes written to be hashed") + } + salt := h.Sum(nil) + + ikm = append(ikm, 0) + // Leaves key_info parameter as the default empty string + // and just adds parameter I2OSP(L, 2) + var okm [native.WideFieldBytes]byte + kdf := hkdf.New(sha256.New, ikm, salt, []byte{0, 48}) + read, err := kdf.Read(okm[:48]) + copy(okm[:48], internal.ReverseScalarBytes(okm[:48])) + if err != nil { + return nil, err + } + if read != 48 { + return nil, fmt.Errorf("failed to create private key") + } + v := bls12381.Bls12381FqNew().SetBytesWide(&okm) + return &SecretKey{value: v}, nil +} + +// Serialize a secret key to raw bytes +func (sk SecretKey) MarshalBinary() ([]byte, error) { + bytes := sk.value.Bytes() + return internal.ReverseScalarBytes(bytes[:]), nil +} + +// Deserialize a secret key from raw bytes +// Cannot be zero. Must be 32 bytes and cannot be all zeroes. +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03#section-2.3 +func (sk *SecretKey) UnmarshalBinary(data []byte) error { + if len(data) != SecretKeySize { + return fmt.Errorf("secret key must be %d bytes", SecretKeySize) + } + zeros := make([]byte, len(data)) + if subtle.ConstantTimeCompare(data, zeros) == 1 { + return fmt.Errorf("secret key cannot be zero") + } + var bb [native.FieldBytes]byte + copy(bb[:], internal.ReverseScalarBytes(data)) + value, err := bls12381.Bls12381FqNew().SetBytes(&bb) + if err != nil { + return err + } + sk.value = value + return nil +} + +// SecretKeyShare is shamir share of a private key +type SecretKeyShare struct { + identifier byte + value []byte +} + +// Serialize a secret key share to raw bytes +func (sks SecretKeyShare) MarshalBinary() ([]byte, error) { + var blob [SecretKeyShareSize]byte + l := len(sks.value) + copy(blob[:l], sks.value) + blob[l] = sks.identifier + return blob[:], nil +} + +// Deserialize a secret key share from raw bytes +func (sks *SecretKeyShare) UnmarshalBinary(data []byte) error { + if len(data) != SecretKeyShareSize { + return fmt.Errorf("secret key share must be %d bytes", SecretKeyShareSize) + } + + zeros := make([]byte, len(data)) + if subtle.ConstantTimeCompare(data, zeros) == 1 { + return fmt.Errorf("secret key share cannot be zero") + } + l := len(data) + sks.identifier = data[l-1] + sks.value = make([]byte, SecretKeySize) + copy(sks.value, data[:l]) + return nil +} + +// thresholdizeSecretKey splits a composite secret key such that +// `threshold` partial signatures can be combined to form a composite signature +func thresholdizeSecretKey(secretKey *SecretKey, threshold, total uint) ([]*SecretKeyShare, error) { + // Verify our parameters are acceptable. + if secretKey == nil { + return nil, fmt.Errorf("secret key is nil") + } + if threshold > total { + return nil, fmt.Errorf("threshold cannot be greater than the total") + } + if threshold == 0 { + return nil, fmt.Errorf("threshold cannot be zero") + } + if total <= 1 { + return nil, fmt.Errorf("total must be larger than 1") + } + if total > 255 || threshold > 255 { + return nil, fmt.Errorf("cannot have more than 255 shares") + } + + curve := curves.BLS12381G1() + sss, err := sharing.NewShamir(uint32(threshold), uint32(total), curve) + if err != nil { + return nil, err + } + secret, ok := curve.NewScalar().(*curves.ScalarBls12381) + if !ok { + return nil, fmt.Errorf("invalid curve") + } + secret.Value = secretKey.value + shares, err := sss.Split(secret, rand.Reader) + if err != nil { + return nil, err + } + // Verify we got the expected number of shares + if uint(len(shares)) != total { + return nil, fmt.Errorf("%v != %v shares", len(shares), total) + } + + // Package our shares + secrets := make([]*SecretKeyShare, len(shares)) + for i, s := range shares { + // users expect BigEndian + sks := &SecretKeyShare{identifier: byte(s.Id), value: s.Value} + secrets[i] = sks + } + + return secrets, nil +} diff --git a/pkg/crypto/signatures/bls/bls_sig/lib_test.go b/pkg/crypto/signatures/bls/bls_sig/lib_test.go new file mode 100755 index 000000000..1e19449ef --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/lib_test.go @@ -0,0 +1,284 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "bytes" + "crypto/rand" + "encoding" + "math/big" + "testing" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +func genSecretKey(t *testing.T) *SecretKey { + ikm := make([]byte, 32) + sk, err := new(SecretKey).Generate(ikm) + if err != nil { + t.Errorf("Couldn't generate secret key") + } + return sk +} + +func genRandSecretKey(ikm []byte, t *testing.T) *SecretKey { + sk, err := new(SecretKey).Generate(ikm) + if err != nil { + t.Errorf("Couldn't generate secret key") + } + return sk +} + +func genPublicKeyVt(sk *SecretKey, t *testing.T) *PublicKeyVt { + pk, err := sk.GetPublicKeyVt() + if err != nil { + t.Errorf("Expected GetPublicKeyVt to pass but failed: %v", err) + } + return pk +} + +func genPublicKey(sk *SecretKey, t *testing.T) *PublicKey { + pk, err := sk.GetPublicKey() + if err != nil { + t.Errorf("GetPublicKey failed. Couldn't generate public key: %v", err) + } + return pk +} + +func genSignature(sk *SecretKey, message []byte, t *testing.T) *Signature { + bls := NewSigPop() + + sig, err := bls.Sign(sk, message) + if err != nil { + t.Errorf("createSignature couldn't sign message: %v", err) + } + return sig +} + +func genSignatureVt(sk *SecretKey, message []byte, t *testing.T) *SignatureVt { + bls := NewSigPopVt() + sig, err := bls.Sign(sk, message) + if err != nil { + t.Errorf("createSignatureVt couldn't sign message: %v", err) + } + return sig +} + +func readRand(ikm []byte, t *testing.T) { + n, err := rand.Read(ikm) + if err != nil || n < len(ikm) { + t.Errorf("Not enough data was read or an error occurred") + } +} + +func assertSecretKeyGen(seed, expected []byte, t *testing.T) { + sk, err := new(SecretKey).Generate(seed) + if err != nil { + t.Errorf("Expected Generate to succeed but failed") + } + actual, _ := sk.MarshalBinary() + if len(actual) != len(expected) { + t.Errorf("Length of Generate output is incorrect. Expected 32, found: %v\n", len(actual)) + } + if !bytes.Equal(actual[:], expected) { + t.Errorf("SecretKey was not as expected") + } +} + +func marshalStruct(value encoding.BinaryMarshaler, t *testing.T) []byte { + out, err := value.MarshalBinary() + if err != nil { + t.Errorf("MarshalBinary failed: %v", err) + } + return out +} + +func TestSecretKeyZeroBytes(t *testing.T) { + seed := []byte{} + _, err := new(SecretKey).Generate(seed) + if err == nil { + t.Errorf("Expected Generate to fail but succeeded") + } +} + +func TestMarshalLeadingZeroes(t *testing.T) { + tests := []struct { + name string + in []byte + }{ + {"no leading zeroes", []byte{74, 53, 59, 227, 218, 192, 145, 160, 167, 230, 64, 98, 3, 114, 245, 225, 226, 228, 64, 23, 23, 193, 231, 156, 172, 111, 251, 168, 246, 144, 86, 4}}, + {"one leading zero byte", []byte{0o0, 53, 59, 227, 218, 192, 145, 160, 167, 230, 64, 98, 3, 114, 245, 225, 226, 228, 64, 23, 23, 193, 231, 156, 172, 111, 251, 168, 246, 144, 86, 4}}, + {"two leading zeroes", []byte{0o0, 0o0, 59, 227, 218, 192, 145, 160, 167, 230, 64, 98, 3, 114, 245, 225, 226, 228, 64, 23, 23, 193, 231, 156, 172, 111, 251, 168, 246, 144, 86, 4}}, + } + // Run all the tests! + ss := bls12381.Bls12381FqNew() + for _, test := range tests { + // Marshal + var k big.Int + k.SetBytes(test.in) + ss.SetBigInt(&k) + bytes, err := SecretKey{ss}.MarshalBinary() + if err != nil { + t.Errorf("%v", err) + continue + } + + // Test that marshal produces a values of the exected len + t.Run(test.name, func(t *testing.T) { + if len(bytes) != SecretKeySize { + t.Errorf("expected len=%v got len=%v", SecretKeySize, len(bytes)) + } + }) + + // Test that we can also unmarhsal correctly + t.Run(test.name, func(t *testing.T) { + var actual SecretKey + err := actual.UnmarshalBinary(bytes) + // Test for error + if err != nil { + t.Errorf("%v", err) + return + } + + // Test for correctness + if actual.value.Cmp(ss) != 0 { + t.Errorf("unmarshaled doens't match original value") + } + }) + } +} + +func TestSecretKey32Bytes(t *testing.T) { + seed := make([]byte, 32) + expected := []byte{77, 18, 154, 25, 223, 134, 160, 245, 52, 91, 173, 76, 198, 242, 73, 236, 42, 129, 156, 204, 51, 134, 137, 91, 235, 79, 125, 152, 179, 219, 98, 53} + assertSecretKeyGen(seed, expected, t) +} + +func TestSecretKey128Bytes(t *testing.T) { + seed := make([]byte, 128) + expected := []byte{97, 207, 109, 96, 94, 90, 233, 215, 221, 207, 240, 139, 24, 209, 152, 170, 73, 209, 151, 241, 148, 176, 173, 92, 101, 48, 39, 175, 201, 219, 146, 168} + assertSecretKeyGen(seed, expected, t) +} + +func TestRandomSecretKey(t *testing.T) { + seed := make([]byte, 48) + _, _ = rand.Read(seed) + _, err := new(SecretKey).Generate(seed) + if err != nil { + t.Errorf("Expected Generate to succeed but failed") + } +} + +func TestSecretKeyToBytes(t *testing.T) { + sk := genSecretKey(t) + skBytes := marshalStruct(sk, t) + sk1 := new(SecretKey) + err := sk1.UnmarshalBinary(skBytes) + if err != nil { + t.Errorf("Expected UnmarshalBinary to pass but failed: %v", err) + } + out := sk1.value.Bytes() + for i, b := range internal.ReverseScalarBytes(out[:]) { + if skBytes[i] != b { + t.Errorf("Expected secret keys to be equal but are different at offset %d: %v != %v", i, skBytes[i], b) + } + } + sk2 := new(SecretKey) + err = sk2.UnmarshalBinary(skBytes) + if err != nil { + t.Errorf("Expected FromBytes to succeed but failed.") + } + if !bytes.Equal(marshalStruct(sk2, t), skBytes) { + t.Errorf("Expected secret keys to be equal but are different") + } +} + +// Verifies that the thresholdize creates the expected number +// of shares +func TestThresholdizeSecretKeyCountsCorrect(t *testing.T) { + sk := &SecretKey{value: bls12381.Bls12381FqNew().SetBigInt(big.NewInt(248631463258962596))} + tests := []struct { + key *SecretKey + t, n uint + expectedError bool + }{ + // bad cases + {sk, 1, 1, true}, // n == 1 + {sk, 1, 5, true}, // t == 1 + {nil, 3, 5, true}, // sk nil + {sk, 101, 100, true}, // t> n + {sk, 0, 10, true}, // t == 0 + {sk, 10, 256, true}, // n > 256 + + // good cases + {sk, 10, 10, false}, // t == n + {sk, 2, 10, false}, // boundary case for t + {sk, 9, 10, false}, // boundary case for t + {sk, 10, 255, false}, // boundary case for n + {sk, 254, 255, false}, // boundary case for t,n + {sk, 100, 200, false}, // arbitrary t,n values + {sk, 10, 20, false}, // arbitrary t,n values + {sk, 15, 200, false}, // arbitrary t,n values + {sk, 254, 255, false}, // boundary case + {sk, 255, 255, false}, // boundary case + } + + // Run all the tests! + for i, test := range tests { + shares, err := thresholdizeSecretKey(test.key, test.t, test.n) + + // Check for errors + if test.expectedError && err == nil { + t.Errorf("%d - expected an error but received nil. t=%v, n=%v, sk=%v", i, test.t, test.n, sk) + } + + // Check for errors + if !test.expectedError && err != nil { + t.Errorf("%d - received unexpected error %v. t=%v, n=%v, sk=%v", i, err, test.t, test.n, sk) + } + + // Check the share count == n + if !test.expectedError && test.n != uint(len(shares)) { + t.Errorf("%d - expected len(shares) = %v != %v (n)", i, len(shares), test.n) + } + } +} + +func TestSecretKeyShareUnmarshalBinary(t *testing.T) { + sk := genSecretKey(t) + sks, err := thresholdizeSecretKey(sk, 3, 5) + if err != nil { + t.Errorf("Expected thresholdizeSecretKey to pass but failed.") + } + + for i, sh := range sks { + b1, err := sh.MarshalBinary() + if err != nil { + t.Errorf("%d - expected MarshalBinary to pass but failed. sh=%v", i, sh) + } + + // UnmarshalBinary b1 to new SecretKeyShare + sh1 := new(SecretKeyShare) + err = sh1.UnmarshalBinary(b1) + if err != nil { + t.Errorf("%d - expected UnmarshalBinary to pass but failed. sh=%v", i, sh) + } + + // zero bytes slice with length equal to SecretKeySize + zeros := make([]byte, SecretKeySize) + b2, err := sh1.MarshalBinary() + if err != nil { + t.Errorf("%d - expected MarshalBinary to pass but failed. sh1=%v", i, sh1) + } + + // Check if []bytes from UnmarshalBinary != zeros && Initial bytes(b1) == Final bytes(b2) + if bytes.Equal(zeros, b2) && !bytes.Equal(b1, b2) { + t.Errorf("%d - expected UnmarshalBinary to give non zeros value but failed. sh1=%v, sh=%v", i, sh1, sh) + } + } +} diff --git a/pkg/crypto/signatures/bls/bls_sig/tiny_bls.go b/pkg/crypto/signatures/bls/bls_sig/tiny_bls.go new file mode 100755 index 000000000..13dd058d2 --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/tiny_bls.go @@ -0,0 +1,438 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "fmt" +) + +const ( + // Domain separation tag for basic signatures + // according to section 4.2.1 in + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 + blsSignatureBasicVtDst = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_" + // Domain separation tag for basic signatures + // according to section 4.2.2 in + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 + blsSignatureAugVtDst = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_" + // Domain separation tag for proof of possession signatures + // according to section 4.2.3 in + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 + blsSignaturePopVtDst = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_" + // Domain separation tag for proof of possession proofs + // according to section 4.2.3 in + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 + blsPopProofVtDst = "BLS_POP_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_" +) + +type BlsSchemeVt interface { + Keygen() (*PublicKeyVt, *SecretKey, error) + KeygenWithSeed(ikm []byte) (*PublicKeyVt, *SecretKey, error) + Sign(sk *SecretKey, msg []byte) (*SignatureVt, error) + Verify(pk *PublicKeyVt, msg []byte, sig *SignatureVt) bool + AggregateVerify(pks []*PublicKeyVt, msgs [][]byte, sigs []*SignatureVt) bool +} + +// generateKeysVt creates 32 bytes of random data to be fed to +// generateKeysWithSeedVt +func generateKeysVt() (*PublicKeyVt, *SecretKey, error) { + ikm, err := generateRandBytes(32) + if err != nil { + return nil, nil, err + } + return generateKeysWithSeedVt(ikm) +} + +// generateKeysWithSeedVt generates a BLS key pair given input key material (ikm) +func generateKeysWithSeedVt(ikm []byte) (*PublicKeyVt, *SecretKey, error) { + sk, err := new(SecretKey).Generate(ikm) + if err != nil { + return nil, nil, err + } + pk, err := sk.GetPublicKeyVt() + if err != nil { + return nil, nil, err + } + return pk, sk, nil +} + +// thresholdGenerateKeys will generate random secret key shares and the corresponding public key +func thresholdGenerateKeysVt(threshold, total uint) (*PublicKeyVt, []*SecretKeyShare, error) { + pk, sk, err := generateKeysVt() + if err != nil { + return nil, nil, err + } + shares, err := thresholdizeSecretKey(sk, threshold, total) + if err != nil { + return nil, nil, err + } + return pk, shares, nil +} + +// thresholdGenerateKeysWithSeed will generate random secret key shares and the corresponding public key +// using the corresponding seed `ikm` +func thresholdGenerateKeysWithSeedVt(ikm []byte, threshold, total uint) (*PublicKeyVt, []*SecretKeyShare, error) { + pk, sk, err := generateKeysWithSeedVt(ikm) + if err != nil { + return nil, nil, err + } + shares, err := thresholdizeSecretKey(sk, threshold, total) + if err != nil { + return nil, nil, err + } + return pk, shares, nil +} + +// SigBasicVt is minimal-pubkey-size scheme that doesn't support FastAggregateVerification. +// see: https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03#section-4.2.1 +type SigBasicVt struct { + dst string +} + +// Creates a new BLS basic signature scheme with the standard domain separation tag used for signatures. +func NewSigBasicVt() *SigBasicVt { + return &SigBasicVt{dst: blsSignatureBasicVtDst} +} + +// Creates a new BLS basic signature scheme with a custom domain separation tag used for signatures. +func NewSigBasicVtWithDst(signDst string) *SigBasicVt { + return &SigBasicVt{dst: signDst} +} + +// Creates a new BLS key pair +func (b SigBasicVt) Keygen() (*PublicKeyVt, *SecretKey, error) { + return generateKeysVt() +} + +// Creates a new BLS key pair +// Input key material (ikm) MUST be at least 32 bytes long, +// but it MAY be longer. +func (b SigBasicVt) KeygenWithSeed(ikm []byte) (*PublicKeyVt, *SecretKey, error) { + return generateKeysWithSeedVt(ikm) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigBasicVt) ThresholdKeygen(threshold, total uint) (*PublicKeyVt, []*SecretKeyShare, error) { + return thresholdGenerateKeysVt(threshold, total) +} + +// ThresholdKeygenWithSeed generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures from input key material (ikm) +func (b SigBasicVt) ThresholdKeygenWithSeed(ikm []byte, threshold, total uint) (*PublicKeyVt, []*SecretKeyShare, error) { + return thresholdGenerateKeysWithSeedVt(ikm, threshold, total) +} + +// Computes a signature in G1 from sk, a secret key, and a message +func (b SigBasicVt) Sign(sk *SecretKey, msg []byte) (*SignatureVt, error) { + return sk.createSignatureVt(msg, b.dst) +} + +// Compute a partial signature in G2 that can be combined with other partial signature +func (b SigBasicVt) PartialSign(sks *SecretKeyShare, msg []byte) (*PartialSignatureVt, error) { + return sks.partialSignVt(msg, b.dst) +} + +// CombineSignatures takes partial signatures to yield a completed signature +func (b SigBasicVt) CombineSignatures(sigs ...*PartialSignatureVt) (*SignatureVt, error) { + return combineSigsVt(sigs) +} + +// Checks that a signature is valid for the message under the public key pk +func (b SigBasicVt) Verify(pk *PublicKeyVt, msg []byte, sig *SignatureVt) (bool, error) { + return pk.verifySignatureVt(msg, sig, b.dst) +} + +// The AggregateVerify algorithm checks an aggregated signature over +// several (PK, message, signature) pairs. +// Each message must be different or this will return false. +// See section 3.1.1 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigBasicVt) AggregateVerify(pks []*PublicKeyVt, msgs [][]byte, sigs []*SignatureVt) (bool, error) { + if !allRowsUnique(msgs) { + return false, fmt.Errorf("all messages must be distinct") + } + asig, err := aggregateSignaturesVt(sigs...) + if err != nil { + return false, err + } + return asig.aggregateVerify(pks, msgs, b.dst) +} + +// SigAugVt is minimal-signature-size scheme that doesn't support FastAggregateVerification. +// see: https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03#section-4.2.2 +type SigAugVt struct { + dst string +} + +// Creates a new BLS message augmentation signature scheme with the standard domain separation tag used for signatures. +func NewSigAugVt() *SigAugVt { + return &SigAugVt{dst: blsSignatureAugVtDst} +} + +// Creates a new BLS message augmentation signature scheme with a custom domain separation tag used for signatures. +func NewSigAugVtWithDst(signDst string) *SigAugVt { + return &SigAugVt{dst: signDst} +} + +// Creates a new BLS key pair +func (b SigAugVt) Keygen() (*PublicKeyVt, *SecretKey, error) { + return generateKeysVt() +} + +// Creates a new BLS secret key +// Input key material (ikm) MUST be at least 32 bytes long, +// but it MAY be longer. +func (b SigAugVt) KeygenWithSeed(ikm []byte) (*PublicKeyVt, *SecretKey, error) { + return generateKeysWithSeedVt(ikm) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigAugVt) ThresholdKeygen(threshold, total uint) (*PublicKeyVt, []*SecretKeyShare, error) { + return thresholdGenerateKeysVt(threshold, total) +} + +// ThresholdKeygenWithSeed generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigAugVt) ThresholdKeygenWithSeed(ikm []byte, threshold, total uint) (*PublicKeyVt, []*SecretKeyShare, error) { + return thresholdGenerateKeysWithSeedVt(ikm, threshold, total) +} + +// Computes a signature in G1 from sk, a secret key, and a message +// See section 3.2.1 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-02 +func (b SigAugVt) Sign(sk *SecretKey, msg []byte) (*SignatureVt, error) { + pk, err := sk.GetPublicKeyVt() + if err != nil { + return nil, err + } + bytes, err := pk.MarshalBinary() + if err != nil { + return nil, fmt.Errorf("MarshalBinary failed") + } + bytes = append(bytes, msg...) + return sk.createSignatureVt(bytes, b.dst) +} + +// Compute a partial signature in G2 that can be combined with other partial signature +func (b SigAugVt) PartialSign(sks *SecretKeyShare, pk *PublicKeyVt, msg []byte) (*PartialSignatureVt, error) { + if len(msg) == 0 { + return nil, fmt.Errorf("message cannot be empty or nil") + } + bytes, err := pk.MarshalBinary() + if err != nil { + return nil, fmt.Errorf("MarshalBinary failed") + } + bytes = append(bytes, msg...) + return sks.partialSignVt(bytes, b.dst) +} + +// CombineSignatures takes partial signatures to yield a completed signature +func (b SigAugVt) CombineSignatures(sigs ...*PartialSignatureVt) (*SignatureVt, error) { + return combineSigsVt(sigs) +} + +// Checks that a signature is valid for the message under the public key pk +// See section 3.2.2 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigAugVt) Verify(pk *PublicKeyVt, msg []byte, sig *SignatureVt) (bool, error) { + bytes, err := pk.MarshalBinary() + if err != nil { + return false, err + } + bytes = append(bytes, msg...) + return pk.verifySignatureVt(bytes, sig, b.dst) +} + +// The aggregateVerify algorithm checks an aggregated signature over +// several (PK, message, signature) pairs. +// See section 3.2.3 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigAugVt) AggregateVerify(pks []*PublicKeyVt, msgs [][]byte, sigs []*SignatureVt) (bool, error) { + if len(pks) != len(msgs) { + return false, fmt.Errorf("the number of public keys does not match the number of messages: %v != %v", len(pks), len(msgs)) + } + data := make([][]byte, len(msgs)) + for i, msg := range msgs { + bytes, err := pks[i].MarshalBinary() + if err != nil { + return false, err + } + data[i] = append(bytes, msg...) + } + asig, err := aggregateSignaturesVt(sigs...) + if err != nil { + return false, err + } + return asig.aggregateVerify(pks, data, b.dst) +} + +// SigEth2Vt supports signatures on Eth2. +// Internally is an alias for SigPopVt +type SigEth2Vt = SigPopVt + +// NewSigEth2Vt Creates a new BLS ETH2 signature scheme with the standard domain separation tag used for signatures. +func NewSigEth2Vt() *SigEth2Vt { + return NewSigPopVt() +} + +// SigPopVt is minimal-signature-size scheme that supports FastAggregateVerification +// and requires using proofs of possession to mitigate rogue-key attacks +// see: https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03#section-4.2.3 +type SigPopVt struct { + sigDst string + popDst string +} + +// Creates a new BLS proof of possession signature scheme with the standard domain separation tag used for signatures. +func NewSigPopVt() *SigPopVt { + return &SigPopVt{sigDst: blsSignaturePopVtDst, popDst: blsPopProofVtDst} +} + +// Creates a new BLS message proof of possession signature scheme with a custom domain separation tag used for signatures. +func NewSigPopVtWithDst(signDst, popDst string) (*SigPopVt, error) { + if signDst == popDst { + return nil, fmt.Errorf("domain separation tags cannot be equal") + } + return &SigPopVt{sigDst: signDst, popDst: popDst}, nil +} + +// Creates a new BLS key pair +func (b SigPopVt) Keygen() (*PublicKeyVt, *SecretKey, error) { + return generateKeysVt() +} + +// Creates a new BLS secret key +// Input key material (ikm) MUST be at least 32 bytes long, +// but it MAY be longer. +func (b SigPopVt) KeygenWithSeed(ikm []byte) (*PublicKeyVt, *SecretKey, error) { + return generateKeysWithSeedVt(ikm) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigPopVt) ThresholdKeygen(threshold, total uint) (*PublicKeyVt, []*SecretKeyShare, error) { + return thresholdGenerateKeysVt(threshold, total) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigPopVt) ThresholdKeygenWithSeed(ikm []byte, threshold, total uint) (*PublicKeyVt, []*SecretKeyShare, error) { + return thresholdGenerateKeysWithSeedVt(ikm, threshold, total) +} + +// Computes a signature in G1 from sk, a secret key, and a message +// See section 2.6 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPopVt) Sign(sk *SecretKey, msg []byte) (*SignatureVt, error) { + return sk.createSignatureVt(msg, b.sigDst) +} + +// Compute a partial signature in G2 that can be combined with other partial signature +func (b SigPopVt) PartialSign(sks *SecretKeyShare, msg []byte) (*PartialSignatureVt, error) { + return sks.partialSignVt(msg, b.sigDst) +} + +// CombineSignatures takes partial signatures to yield a completed signature +func (b SigPopVt) CombineSignatures(sigs ...*PartialSignatureVt) (*SignatureVt, error) { + return combineSigsVt(sigs) +} + +// Checks that a signature is valid for the message under the public key pk +// See section 2.7 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPopVt) Verify(pk *PublicKeyVt, msg []byte, sig *SignatureVt) (bool, error) { + return pk.verifySignatureVt(msg, sig, b.sigDst) +} + +// The aggregateVerify algorithm checks an aggregated signature over +// several (PK, message, signature) pairs. +// Each message must be different or this will return false. +// See section 3.1.1 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-02 +func (b SigPopVt) AggregateVerify(pks []*PublicKeyVt, msgs [][]byte, sigs []*SignatureVt) (bool, error) { + if !allRowsUnique(msgs) { + return false, fmt.Errorf("all messages must be distinct") + } + asig, err := aggregateSignaturesVt(sigs...) + if err != nil { + return false, err + } + return asig.aggregateVerify(pks, msgs, b.sigDst) +} + +// Combine many signatures together to form a Multisignature. +// Multisignatures can be created when multiple signers jointly +// generate signatures over the same message. +func (b SigPopVt) AggregateSignatures(sigs ...*SignatureVt) (*MultiSignatureVt, error) { + g1, err := aggregateSignaturesVt(sigs...) + if err != nil { + return nil, err + } + return &MultiSignatureVt{value: g1.value}, nil +} + +// Combine many public keys together to form a Multipublickey. +// Multipublickeys are used to verify multisignatures. +func (b SigPopVt) AggregatePublicKeys(pks ...*PublicKeyVt) (*MultiPublicKeyVt, error) { + g2, err := aggregatePublicKeysVt(pks...) + if err != nil { + return nil, err + } + return &MultiPublicKeyVt{value: g2.value}, nil +} + +// Checks that a multisignature is valid for the message under the multi public key +// Similar to FastAggregateVerify except the keys and signatures have already been +// combined. See section 3.3.4 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-02 +func (b SigPopVt) VerifyMultiSignature(pk *MultiPublicKeyVt, msg []byte, sig *MultiSignatureVt) (bool, error) { + s := &SignatureVt{value: sig.value} + p := &PublicKeyVt{value: pk.value} + return p.verifySignatureVt(msg, s, b.sigDst) +} + +// FastAggregateVerify verifies an aggregated signature over the same message under the given public keys. +// See section 3.3.4 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPopVt) FastAggregateVerify(pks []*PublicKeyVt, msg []byte, asig *SignatureVt) (bool, error) { + apk, err := aggregatePublicKeysVt(pks...) + if err != nil { + return false, err + } + return apk.verifySignatureVt(msg, asig, b.sigDst) +} + +// FastAggregateVerifyConstituent verifies a list of signature over the same message under the given public keys. +// See section 3.3.4 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPopVt) FastAggregateVerifyConstituent(pks []*PublicKeyVt, msg []byte, sigs []*SignatureVt) (bool, error) { + asig, err := aggregateSignaturesVt(sigs...) + if err != nil { + return false, err + } + return b.FastAggregateVerify(pks, msg, asig) +} + +// Create a proof of possession for the corresponding public key. +// A proof of possession must be created for each public key to be used +// in FastAggregateVerify or a Multipublickey to avoid rogue key attacks. +// See section 3.3.2 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPopVt) PopProve(sk *SecretKey) (*ProofOfPossessionVt, error) { + return sk.createProofOfPossessionVt(b.popDst) +} + +// verify a proof of possession for the corresponding public key is valid. +// A proof of possession must be created for each public key to be used +// in FastAggregateVerify or a Multipublickey to avoid rogue key attacks. +// See section 3.3.3 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPopVt) PopVerify(pk *PublicKeyVt, pop1 *ProofOfPossessionVt) (bool, error) { + return pop1.verify(pk, b.popDst) +} diff --git a/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig.go b/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig.go new file mode 100755 index 000000000..d7e4345de --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig.go @@ -0,0 +1,489 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// Implement BLS signatures on the BLS12-381 curve +// according to https://crypto.standford.edu/~dabo/pubs/papers/BLSmultisig.html +// and https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +// this file implements signatures in G1 and public keys in G2. +// Public Keys and Signatures can be aggregated but the consumer +// must use proofs of possession to defend against rogue-key attacks. + +const ( + // Public key size in G2 + PublicKeyVtSize = 96 + // Signature size in G1 + SignatureVtSize = 48 + // Proof of Possession in G1 + ProofOfPossessionVtSize = 48 +) + +// Represents a public key in G2 +type PublicKeyVt struct { + value bls12381.G2 +} + +// Serialize a public key to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (pk *PublicKeyVt) MarshalBinary() ([]byte, error) { + out := pk.value.ToCompressed() + return out[:], nil +} + +// Deserialize a public key from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the public key +// otherwise it will return an error +func (pk *PublicKeyVt) UnmarshalBinary(data []byte) error { + if len(data) != PublicKeyVtSize { + return fmt.Errorf("public key must be %d bytes", PublicKeySize) + } + var blob [PublicKeyVtSize]byte + copy(blob[:], data) + p2, err := new(bls12381.G2).FromCompressed(&blob) + if err != nil { + return err + } + if p2.IsIdentity() == 1 { + return fmt.Errorf("public keys cannot be zero") + } + pk.value = *p2 + return nil +} + +// Represents a BLS signature in G1 +type SignatureVt struct { + value bls12381.G1 +} + +// Serialize a signature to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (sig *SignatureVt) MarshalBinary() ([]byte, error) { + out := sig.value.ToCompressed() + return out[:], nil +} + +func (sig *SignatureVt) verify(pk *PublicKeyVt, message []byte, signDstVt string) (bool, error) { + return pk.verifySignatureVt(message, sig, signDstVt) +} + +// The AggregateVerify algorithm checks an aggregated signature over +// several (PK, message) pairs. +// The Signature is the output of aggregateSignaturesVt +// Each message must be different or this will return false. +// See section 3.1.1 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (sig *SignatureVt) aggregateVerify(pks []*PublicKeyVt, msgs [][]byte, signDstVt string) (bool, error) { + return sig.coreAggregateVerify(pks, msgs, signDstVt) +} + +func (sig *SignatureVt) coreAggregateVerify(pks []*PublicKeyVt, msgs [][]byte, signDstVt string) (bool, error) { + if len(pks) < 1 { + return false, fmt.Errorf("at least one key is required") + } + if len(msgs) < 1 { + return false, fmt.Errorf("at least one message is required") + } + if len(pks) != len(msgs) { + return false, fmt.Errorf("the number of public keys does not match the number of messages: %v != %v", len(pks), len(msgs)) + } + if sig.value.InCorrectSubgroup() == 0 { + return false, fmt.Errorf("signature is not in the correct subgroup") + } + + engine := new(bls12381.Engine) + dst := []byte(signDstVt) + // e(H(m_1), pk_1)*...*e(H(m_N), pk_N) == e(s, g2) + // However, we use only one miller loop + // by doing the equivalent of + // e(H(m_1), pk_1)*...*e(H(m_N), pk_N) * e(s^-1, g2) == 1 + for i, pk := range pks { + if pk == nil { + return false, fmt.Errorf("public key at %d is nil", i) + } + if pk.value.IsIdentity() == 1 || pk.value.InCorrectSubgroup() == 0 { + return false, fmt.Errorf("public key at %d is not in the correct subgroup", i) + } + p1 := new(bls12381.G1).Hash(native.EllipticPointHasherSha256(), msgs[i], dst) + engine.AddPair(p1, &pk.value) + } + engine.AddPairInvG2(&sig.value, new(bls12381.G2).Generator()) + return engine.Check(), nil +} + +// Deserialize a signature from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the Signature +// otherwise it will return an error +func (sig *SignatureVt) UnmarshalBinary(data []byte) error { + if len(data) != SignatureVtSize { + return fmt.Errorf("signature must be %d bytes", SignatureSize) + } + var blob [SignatureVtSize]byte + copy(blob[:], data) + p1, err := new(bls12381.G1).FromCompressed(&blob) + if err != nil { + return err + } + if p1.IsIdentity() == 1 { + return fmt.Errorf("signatures cannot be zero") + } + sig.value = *p1 + return nil +} + +// Get the corresponding public key from a secret key +// Verifies the public key is in the correct subgroup +func (sk *SecretKey) GetPublicKeyVt() (*PublicKeyVt, error) { + result := new(bls12381.G2).Mul(new(bls12381.G2).Generator(), sk.value) + if result.InCorrectSubgroup() == 0 || result.IsIdentity() == 1 { + return nil, fmt.Errorf("point is not in correct subgroup") + } + return &PublicKeyVt{value: *result}, nil +} + +// Compute a signature from a secret key and message +// This signature is deterministic which protects against +// attacks arising from signing with bad randomness like +// the nonce reuse attack on ECDSA. `message` is +// hashed to a point in G1 as described in to +// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/?include_text=1 +// See Section 2.6 in https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +// nil message is not permitted but empty slice is allowed +func (sk *SecretKey) createSignatureVt(message []byte, dstVt string) (*SignatureVt, error) { + if message == nil { + return nil, fmt.Errorf("message cannot be nil") + } + if sk.value.IsZero() == 1 { + return nil, fmt.Errorf("invalid secret key") + } + p1 := new(bls12381.G1).Hash(native.EllipticPointHasherSha256(), message, []byte(dstVt)) + result := new(bls12381.G1).Mul(p1, sk.value) + if result.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("point is not in correct subgroup") + } + return &SignatureVt{value: *result}, nil +} + +// Verify a signature is valid for the message under this public key. +// See Section 2.7 in https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (pk PublicKeyVt) verifySignatureVt(message []byte, signature *SignatureVt, dstVt string) (bool, error) { + if signature == nil || message == nil || pk.value.IsIdentity() == 1 { + return false, fmt.Errorf("signature and message and public key cannot be nil or zero") + } + if signature.value.IsIdentity() == 1 || signature.value.InCorrectSubgroup() == 0 { + return false, fmt.Errorf("signature is not in the correct subgroup") + } + engine := new(bls12381.Engine) + + p1 := new(bls12381.G1).Hash(native.EllipticPointHasherSha256(), message, []byte(dstVt)) + // e(H(m), pk) == e(s, g2) + // However, we can reduce the number of miller loops + // by doing the equivalent of + // e(H(m)^-1, pk) * e(s, g2) == 1 + engine.AddPairInvG1(p1, &pk.value) + engine.AddPair(&signature.value, new(bls12381.G2).Generator()) + return engine.Check(), nil +} + +// Combine public keys into one aggregated key +func aggregatePublicKeysVt(pks ...*PublicKeyVt) (*PublicKeyVt, error) { + if len(pks) < 1 { + return nil, fmt.Errorf("at least one public key is required") + } + result := new(bls12381.G2).Identity() + for i, k := range pks { + if k == nil { + return nil, fmt.Errorf("key at %d is nil, keys cannot be nil", i) + } + if k.value.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("key at %d is not in the correct subgroup", i) + } + result.Add(result, &k.value) + } + return &PublicKeyVt{value: *result}, nil +} + +// Combine signatures into one aggregated signature +func aggregateSignaturesVt(sigs ...*SignatureVt) (*SignatureVt, error) { + if len(sigs) < 1 { + return nil, fmt.Errorf("at least one signature is required") + } + result := new(bls12381.G1).Identity() + for i, s := range sigs { + if s == nil { + return nil, fmt.Errorf("signature at %d is nil, signature cannot be nil", i) + } + if s.value.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("signature at %d is not in the correct subgroup", i) + } + result.Add(result, &s.value) + } + return &SignatureVt{value: *result}, nil +} + +// A proof of possession scheme uses a separate public key validation +// step, called a proof of possession, to defend against rogue key +// attacks. This enables an optimization to aggregate signature +// verification for the case that all signatures are on the same +// message. +type ProofOfPossessionVt struct { + value bls12381.G1 +} + +// Generates a proof-of-possession (PoP) for this secret key. The PoP signature should be verified before +// before accepting any aggregate signatures related to the corresponding pubkey. +func (sk *SecretKey) createProofOfPossessionVt(popDstVt string) (*ProofOfPossessionVt, error) { + pk, err := sk.GetPublicKeyVt() + if err != nil { + return nil, err + } + msg, err := pk.MarshalBinary() + if err != nil { + return nil, err + } + sig, err := sk.createSignatureVt(msg, popDstVt) + if err != nil { + return nil, err + } + return &ProofOfPossessionVt{value: sig.value}, nil +} + +// Serialize a proof of possession to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (pop *ProofOfPossessionVt) MarshalBinary() ([]byte, error) { + out := pop.value.ToCompressed() + return out[:], nil +} + +// Deserialize a proof of possession from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the Signature +// otherwise it will return an error +func (pop *ProofOfPossessionVt) UnmarshalBinary(data []byte) error { + p1 := new(SignatureVt) + err := p1.UnmarshalBinary(data) + if err != nil { + return err + } + pop.value = p1.value + return nil +} + +// Verifies that PoP is valid for this pubkey. In order to prevent rogue key attacks, a PoP must be validated +// for each pubkey in an aggregated signature. +func (pop *ProofOfPossessionVt) verify(pk *PublicKeyVt, popDstVt string) (bool, error) { + if pk == nil { + return false, fmt.Errorf("public key cannot be nil") + } + msg, err := pk.MarshalBinary() + if err != nil { + return false, err + } + return pk.verifySignatureVt(msg, &SignatureVt{value: pop.value}, popDstVt) +} + +// Represents an MultiSignature in G1. A multisignature is used when multiple signatures +// are calculated over the same message vs an aggregate signature where each message signed +// is a unique. +type MultiSignatureVt struct { + value bls12381.G1 +} + +// Serialize a multi-signature to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (sig *MultiSignatureVt) MarshalBinary() ([]byte, error) { + out := sig.value.ToCompressed() + return out[:], nil +} + +// Check a multisignature is valid for a multipublickey and a message +func (sig *MultiSignatureVt) verify(pk *MultiPublicKeyVt, message []byte, signDstVt string) (bool, error) { + if pk == nil { + return false, fmt.Errorf("public key cannot be nil") + } + p := &PublicKeyVt{value: pk.value} + return p.verifySignatureVt(message, &SignatureVt{value: sig.value}, signDstVt) +} + +// Deserialize a signature from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the Signature +// otherwise it will return an error +func (sig *MultiSignatureVt) UnmarshalBinary(data []byte) error { + if len(data) != SignatureVtSize { + return fmt.Errorf("multi signature must be %v bytes", SignatureSize) + } + s1 := new(SignatureVt) + err := s1.UnmarshalBinary(data) + if err != nil { + return err + } + sig.value = s1.value + return nil +} + +// Represents accumulated multiple Public Keys in G2 for verifying a multisignature +type MultiPublicKeyVt struct { + value bls12381.G2 +} + +// Serialize a public key to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (pk *MultiPublicKeyVt) MarshalBinary() ([]byte, error) { + out := pk.value.ToCompressed() + return out[:], nil +} + +// Deserialize a public key from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the public key +// otherwise it will return an error +func (pk *MultiPublicKeyVt) UnmarshalBinary(data []byte) error { + if len(data) != PublicKeyVtSize { + return fmt.Errorf("multi public key must be %v bytes", PublicKeySize) + } + p2 := new(PublicKeyVt) + err := p2.UnmarshalBinary(data) + if err != nil { + return err + } + pk.value = p2.value + return nil +} + +// Check a multisignature is valid for a multipublickey and a message +func (pk *MultiPublicKeyVt) verify(message []byte, sig *MultiSignatureVt, signDstVt string) (bool, error) { + return sig.verify(pk, message, signDstVt) +} + +// PartialSignatureVt represents threshold Gap Diffie-Hellman BLS signature +// that can be combined with other partials to yield a completed BLS signature +// See section 3.2 in +type PartialSignatureVt struct { + identifier byte + signature bls12381.G1 +} + +// partialSignVt creates a partial signature that can be combined with other partial signatures +// to yield a complete signature +func (sks *SecretKeyShare) partialSignVt(message []byte, signDst string) (*PartialSignatureVt, error) { + if len(message) == 0 { + return nil, fmt.Errorf("message cannot be empty or nil") + } + p1 := new(bls12381.G1).Hash(native.EllipticPointHasherSha256(), message, []byte(signDst)) + + var blob [SecretKeySize]byte + copy(blob[:], internal.ReverseScalarBytes(sks.value)) + s, err := bls12381.Bls12381FqNew().SetBytes(&blob) + if err != nil { + return nil, err + } + result := new(bls12381.G1).Mul(p1, s) + if result.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("point is not on correct subgroup") + } + return &PartialSignatureVt{identifier: sks.identifier, signature: *result}, nil +} + +// combineSigsVt gathers partial signatures and yields a complete signature +func combineSigsVt(partials []*PartialSignatureVt) (*SignatureVt, error) { + if len(partials) < 2 { + return nil, fmt.Errorf("must have at least 2 partial signatures") + } + if len(partials) > 255 { + return nil, fmt.Errorf("unsupported to combine more than 255 signatures") + } + + xVars, yVars, err := splitXYVt(partials) + if err != nil { + return nil, err + } + + sTmp := new(bls12381.G1).Identity() + sig := new(bls12381.G1).Identity() + + // Lagrange interpolation + basis := bls12381.Bls12381FqNew() + for i, xi := range xVars { + basis.SetOne() + + for j, xj := range xVars { + if i == j { + continue + } + + num := bls12381.Bls12381FqNew().Neg(xj) // x - x_m + den := bls12381.Bls12381FqNew().Sub(xi, xj) // x_j - x_m + _, wasInverted := den.Invert(den) + // wasInverted == false if den == 0 + if !wasInverted { + return nil, fmt.Errorf("signatures cannot be recombined") + } + basis.Mul(basis, num.Mul(num, den)) + } + sTmp.Mul(yVars[i], basis) + sig.Add(sig, sTmp) + } + if sig.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("signature is not in the correct subgroup") + } + + return &SignatureVt{value: *sig}, nil +} + +// Ensure no duplicates x values and convert x values to field elements +func splitXYVt(partials []*PartialSignatureVt) ([]*native.Field, []*bls12381.G1, error) { + x := make([]*native.Field, len(partials)) + y := make([]*bls12381.G1, len(partials)) + + dup := make(map[byte]bool) + + for i, sp := range partials { + if sp == nil { + return nil, nil, fmt.Errorf("partial signature cannot be nil") + } + if _, exists := dup[sp.identifier]; exists { + return nil, nil, fmt.Errorf("duplicate signature included") + } + if sp.signature.InCorrectSubgroup() == 0 { + return nil, nil, fmt.Errorf("signature is not in the correct subgroup") + } + dup[sp.identifier] = true + x[i] = bls12381.Bls12381FqNew().SetUint64(uint64(sp.identifier)) + y[i] = &sp.signature + } + return x, y, nil +} diff --git a/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_aug_test.go b/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_aug_test.go new file mode 100755 index 000000000..30d939a8e --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_aug_test.go @@ -0,0 +1,381 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "testing" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" +) + +func generateAugSignatureG1(sk *SecretKey, msg []byte, t *testing.T) *SignatureVt { + bls := NewSigAugVt() + sig, err := bls.Sign(sk, msg) + if err != nil { + t.Errorf("Aug Sign failed") + } + return sig +} + +func generateAugAggregateDataG1(t *testing.T) ([]*PublicKeyVt, []*SignatureVt, [][]byte) { + msgs := make([][]byte, numAggregateG1) + pks := make([]*PublicKeyVt, numAggregateG1) + sigs := make([]*SignatureVt, numAggregateG1) + ikm := make([]byte, 32) + bls := NewSigAugVt() + + for i := 0; i < numAggregateG1; i++ { + readRand(ikm, t) + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } + msg := make([]byte, 20) + readRand(msg, t) + sig := generateAugSignatureG1(sk, msg, t) + msgs[i] = msg + sigs[i] = sig + pks[i] = pk + } + return pks, sigs, msgs +} + +func TestAugKeyGenG1Works(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigAugVt() + _, _, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } +} + +func TestAugKeyGenG1Fail(t *testing.T) { + ikm := make([]byte, 10) + readRand(ikm, t) + bls := NewSigAugVt() + _, _, err := bls.KeygenWithSeed(ikm) + if err == nil { + t.Errorf("Aug KeyGen succeeded when it should've failed") + } +} + +func TestAugCustomDstG1(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigAugVtWithDst("BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_TEST") + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug Custom Dst KeyGen failed") + } + + readRand(ikm, t) + sig, err := bls.Sign(sk, ikm) + if err != nil { + t.Errorf("Aug Custom Dst Sign failed") + } + + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Aug Custom Dst Verify failed") + } + + ikm[0] += 1 + if res, _ := bls.Verify(pk, ikm, sig); res { + t.Errorf("Aug Custom Dst Verify succeeded when it should've failed.") + } +} + +func TestAugSigningG1(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigAugVt() + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + readRand(ikm, t) + sig := generateAugSignatureG1(sk, ikm, t) + + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Aug Verify failed") + } + + ikm[0] += 1 + if res, _ := bls.Verify(pk, ikm, sig); res { + t.Errorf("Aug Verify succeeded when it should've failed.") + } +} + +func TestAugAggregateVerifyG1Works(t *testing.T) { + pks, sigs, msgs := generateAugAggregateDataG1(t) + bls := NewSigAugVt() + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Aug AggregateVerify failed") + } +} + +func TestAugAggregateVerifyG1BadPks(t *testing.T) { + bls := NewSigAugVt() + pks, sigs, msgs := generateAugAggregateDataG1(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Aug AggregateVerify failed") + } + + pks[0] = pks[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug AggregateVerify succeeded when it should've failed") + } + + // Try a zero key to make sure it doesn't crash + pkValue := new(bls12381.G2).Identity() + pks[0] = &PublicKeyVt{value: *pkValue} + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug AggregateVerify succeeded with zero byte public key it should've failed") + } + + // Try with base generator + pkValue.Generator() + pks[0] = &PublicKeyVt{value: *pkValue} + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded with the base generator public key it should've failed") + } +} + +func TestAugAggregateVerifyG1BadSigs(t *testing.T) { + bls := NewSigAugVt() + pks, sigs, msgs := generateAugAggregateDataG1(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Aug aggregateVerify failed") + } + + sigs[0] = sigs[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded when it should've failed") + } + + // Try a zero signature to make sure it doesn't crash + sigValue := new(bls12381.G1).Identity() + sigs[0] = &SignatureVt{value: *sigValue} + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded with zero byte signature it should've failed") + } + + // Try with base generator + sigValue.Generator() + sigs[0] = &SignatureVt{value: *sigValue} + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded with the base generator signature it should've failed") + } +} + +func TestAugAggregateVerifyG1BadMsgs(t *testing.T) { + bls := NewSigAugVt() + pks, sigs, msgs := generateAugAggregateDataG1(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Aug aggregateVerify failed") + } + + // Test len(pks) != len(msgs) + if res, _ := bls.AggregateVerify(pks, msgs[0:8], sigs); res { + t.Errorf("Aug aggregateVerify succeeded when it should've failed") + } + + msgs[0] = msgs[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded when it should've failed") + } +} + +func TestAugAggregateVerifyG1DupMsg(t *testing.T) { + bls := NewSigAugVt() + + // Only two messages but repeated + messages := make([][]byte, numAggregateG1) + messages[0] = []byte("Yes") + messages[1] = []byte("No") + for i := 2; i < numAggregateG1; i++ { + messages[i] = messages[i%2] + } + + pks := make([]*PublicKeyVt, numAggregateG1) + sigs := make([]*SignatureVt, numAggregateG1) + + ikm := make([]byte, 32) + for i := 0; i < numAggregateG1; i++ { + readRand(ikm, t) + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + sig := generateAugSignatureG1(sk, messages[i], t) + pks[i] = pk + sigs[i] = sig + } + + if res, _ := bls.AggregateVerify(pks, messages, sigs); !res { + t.Errorf("Aug aggregateVerify failed for duplicate messages") + } +} + +func TestBlsAugG1KeyGen(t *testing.T) { + bls := NewSigAugVt() + _, _, err := bls.Keygen() + if err != nil { + t.Errorf("Keygen failed: %v", err) + } +} + +func TestAugVtThresholdKeygenBadInputs(t *testing.T) { + bls := NewSigAugVt() + _, _, err := bls.ThresholdKeygen(0, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(1, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(3, 2) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } +} + +func TestAugVtThresholdKeygen(t *testing.T) { + bls := NewSigAugVt() + _, sks, err := bls.ThresholdKeygen(3, 5) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + if len(sks) != 5 { + t.Errorf("ThresholdKeygen did not produce enough shares") + } +} + +func TestAugPartialSignVt(t *testing.T) { + ikm := make([]byte, 32) + bls := NewSigAugVt() + pk, sks, err := bls.ThresholdKeygenWithSeed(ikm, 2, 4) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + msg := make([]byte, 10) + sig1, err := bls.PartialSign(sks[0], pk, msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig2, err := bls.PartialSign(sks[1], pk, msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig, err := bls.CombineSignatures(sig1, sig2) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + + if res, _ := bls.Verify(pk, msg, sig); !res { + t.Errorf("Combined signature does not verify") + } + + sig, err = bls.CombineSignatures(sig1) + if err == nil { + t.Errorf("CombineSignatures failed: %v", err) + } + if res, _ := bls.Verify(pk, msg, sig); res { + t.Errorf("Combined signature verify succeeded when it should've failed") + } +} + +// Ensure that mixed partial signatures from distinct origins create invalid composite signatures +func TestAugVtPartialMixupShares(t *testing.T) { + total := uint(5) + ikm := make([]byte, 32) + bls := NewSigAugVt() + pk1, sks1, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + for i := range ikm { + ikm[i] = 1 + } + pk2, sks2, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + + // Generate partial signatures for both sets of keys + msg := make([]byte, 10) + sigs1 := make([]*PartialSignatureVt, total) + sigs2 := make([]*PartialSignatureVt, total) + for i := range sks1 { + sigs1[i], err = bls.PartialSign(sks1[i], pk1, msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + sigs2[i], err = bls.PartialSign(sks2[i], pk2, msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + } + + // Try combining 2 from group 1 and 2 from group 2 + sig, err := bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[2], sigs2[3]) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + // Signature shouldn't validate + if res, _ := bls.Verify(pk1, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + if res, _ := bls.Verify(pk2, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + // Should error out due to duplicate identifiers + _, err = bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[0], sigs2[1]) + if err == nil { + t.Errorf("CombineSignatures expected to fail but succeeded.") + } +} + +func TestEmptyMessageAugPartialSignVt(t *testing.T) { + bls := NewSigAugVt() + pk, sks, err := bls.ThresholdKeygen(5, 6) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + + // Sign an empty message + _, err = bls.PartialSign(sks[0], pk, []byte{}) + if err == nil { + t.Errorf("Expected partial sign to fail on empty message") + } +} + +func TestNilMessageAugPartialSignVt(t *testing.T) { + bls := NewSigAugVt() + pk, sks, err := bls.ThresholdKeygen(5, 6) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + + // Sign nil message + _, err = bls.PartialSign(sks[0], pk, nil) + if err == nil { + t.Errorf("Expected partial signing to fail on nil message") + } +} diff --git a/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_basic_test.go b/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_basic_test.go new file mode 100755 index 000000000..9c8277a6c --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_basic_test.go @@ -0,0 +1,377 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "testing" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" +) + +func generateBasicSignatureG1(sk *SecretKey, msg []byte, t *testing.T) *SignatureVt { + bls := NewSigBasicVt() + sig, err := bls.Sign(sk, msg) + if err != nil { + t.Errorf("Basic Sign failed") + } + return sig +} + +func generateBasicAggregateDataG1(t *testing.T) ([]*PublicKeyVt, []*SignatureVt, [][]byte) { + msgs := make([][]byte, numAggregateG1) + pks := make([]*PublicKeyVt, numAggregateG1) + sigs := make([]*SignatureVt, numAggregateG1) + ikm := make([]byte, 32) + bls := NewSigBasicVt() + + for i := 0; i < numAggregateG1; i++ { + readRand(ikm, t) + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Basic KeyGen failed") + } + msg := make([]byte, 20) + readRand(msg, t) + sig := generateBasicSignatureG1(sk, msg, t) + msgs[i] = msg + sigs[i] = sig + pks[i] = pk + } + return pks, sigs, msgs +} + +func TestBasicKeyGenG1Works(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigBasicVt() + _, _, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Basic KeyGen failed") + } +} + +func TestBasicKeyGenG1Fail(t *testing.T) { + ikm := make([]byte, 10) + readRand(ikm, t) + bls := NewSigBasicVt() + _, _, err := bls.KeygenWithSeed(ikm) + if err == nil { + t.Errorf("Basic KeyGen succeeded when it should've failed") + } +} + +func TestBasicCustomDstG1(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigBasicVtWithDst("BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_TEST") + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Basic Custom Dst KeyGen failed") + } + + readRand(ikm, t) + sig, err := bls.Sign(sk, ikm) + if err != nil { + t.Errorf("Basic Custom Dst Sign failed") + } + + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Basic Custon Dst Verify failed") + } + + ikm[0] += 1 + if res, _ := bls.Verify(pk, ikm, sig); res { + t.Errorf("Basic Custom Dst Verify succeeded when it should've failed.") + } +} + +func TestBasicSigningG1(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigBasicVt() + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Basic KeyGen failed") + } + + readRand(ikm, t) + sig := generateBasicSignatureG1(sk, ikm, t) + + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Basic Verify failed") + } + + ikm[0] += 1 + if res, _ := bls.Verify(pk, ikm, sig); res { + t.Errorf("Basic Verify succeeded when it should've failed.") + } +} + +func TestBasicSigningEmptyMessage(t *testing.T) { + bls := NewSigBasicVt() + _, sk, err := bls.Keygen() + if err != nil { + t.Errorf("Basic KeyGen failed") + } + + // Sign an empty message + _, err = bls.Sign(sk, []byte{}) + if err != nil { + t.Errorf("Expected signing message to succeed: %v", err) + } +} + +func TestBasicSigningNilMessage(t *testing.T) { + bls := NewSigBasicVt() + _, sk, err := bls.Keygen() + if err != nil { + t.Errorf("Basic KeyGen failed") + } + + // Sign nil message + _, err = bls.Sign(sk, nil) + if err == nil { + t.Errorf("Expected signing empty message to fail") + } +} + +func TestBasicAggregateVerifyG1Works(t *testing.T) { + pks, sigs, msgs := generateBasicAggregateDataG1(t) + bls := NewSigBasicVt() + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Basic AggregateVerify failed") + } +} + +func TestBasicAggregateVerifyG1BadPks(t *testing.T) { + bls := NewSigBasicVt() + pks, sigs, msgs := generateBasicAggregateDataG1(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Basic aggregateVerify failed") + } + + pks[0] = pks[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded when it should've failed") + } + + // Try a zero key to make sure it doesn't crash + pkValue := new(bls12381.G2).Identity() + pks[0] = &PublicKeyVt{value: *pkValue} + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded with zero byte public key it should've failed") + } + + // Try with base generator + pkValue.Generator() + pks[0] = &PublicKeyVt{value: *pkValue} + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded with the base generator public key it should've failed") + } +} + +func TestBasicAggregateVerifyG1BadSigs(t *testing.T) { + bls := NewSigBasicVt() + pks, sigs, msgs := generateBasicAggregateDataG1(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Basic aggregateVerify failed") + } + + sigs[0] = sigs[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded when it should've failed") + } + + // Try a zero key to make sure it doesn't crash + g1 := new(bls12381.G1).Identity() + sigValue := g1.Identity() + sigs[0] = &SignatureVt{value: *sigValue} + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded with zero byte signature it should've failed") + } + + // Try with base generator + sigValue = g1.Generator() + sigs[0] = &SignatureVt{value: *sigValue} + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded with the base generator signature it should've failed") + } +} + +func TestBasicAggregateVerifyG1BadMsgs(t *testing.T) { + bls := NewSigBasicVt() + pks, sigs, msgs := generateBasicAggregateDataG1(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Basic aggregateVerify failed") + } + + msgs[0] = msgs[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded when it should've failed") + } +} + +func TestBasicVtThresholdKeygenBadInputs(t *testing.T) { + bls := NewSigBasicVt() + _, _, err := bls.ThresholdKeygen(0, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(0, 1) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(3, 2) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } +} + +func TestBasicVtThresholdKeygen(t *testing.T) { + bls := NewSigBasicVt() + _, sks, err := bls.ThresholdKeygen(3, 5) + if err != nil { + t.Errorf("Keygen failed: %v", err) + } + if len(sks) != 5 { + t.Errorf("ThresholdKeygen did not produce enough shares") + } +} + +func TestBasicPartialSignVt(t *testing.T) { + ikm := make([]byte, 32) + bls := NewSigBasicVt() + pk, sks, err := bls.ThresholdKeygenWithSeed(ikm, 2, 4) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + msg := make([]byte, 10) + sig1, err := bls.PartialSign(sks[0], msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig2, err := bls.PartialSign(sks[1], msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig, err := bls.CombineSignatures(sig1, sig2) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + + if res, _ := bls.Verify(pk, msg, sig); !res { + t.Errorf("Combined signature does not verify") + } + + sig, err = bls.CombineSignatures(sig1) + if err == nil { + t.Errorf("CombineSignatures succeeded when it should've failed") + } + if res, _ := bls.Verify(pk, msg, sig); res { + t.Errorf("Combined signature verify succeeded when it should've failed") + } +} + +// Ensure that mixed partial signatures from distinct origins create invalid composite signatures +func TestBasicVtPartialMixupShares(t *testing.T) { + total := uint(5) + ikm := make([]byte, 32) + bls := NewSigBasicVt() + pk1, sks1, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + for i := range ikm { + ikm[i] = 1 + } + pk2, sks2, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + + // Generate partial signatures for both sets of keys + msg := make([]byte, 10) + sigs1 := make([]*PartialSignatureVt, total) + sigs2 := make([]*PartialSignatureVt, total) + for i := range sks1 { + sigs1[i], err = bls.PartialSign(sks1[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + sigs2[i], err = bls.PartialSign(sks2[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + } + + // Try combining 2 from group 1 and 2 from group 2 + sig, err := bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[2], sigs2[3]) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + // Signature shouldn't validate + if res, _ := bls.Verify(pk1, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + if res, _ := bls.Verify(pk2, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + // Should error out due to duplicate identifiers + _, err = bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[0], sigs2[1]) + if err == nil { + t.Errorf("CombineSignatures expected to fail but succeeded.") + } +} + +func TestIdentityPublicKeyVt(t *testing.T) { + bls := NewSigBasicVt() + _, sk, err := bls.Keygen() + if err != nil { + t.Errorf("Keygen failed: %v", err) + } + msg := []byte{0, 0, 0, 0} + sig, _ := bls.Sign(sk, msg) + pk := PublicKeyVt{value: *new(bls12381.G2).Identity()} + if res, _ := bls.Verify(&pk, msg, sig); res { + t.Errorf("Verify succeeded when the public key is the identity.") + } +} + +func TestThresholdSignTooHighAndLowVt(t *testing.T) { + bls := NewSigBasicVt() + _, sks, err := bls.ThresholdKeygen(3, 5) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + msg := make([]byte, 10) + + ps, err := bls.PartialSign(sks[0], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + + _, err = bls.CombineSignatures(ps) + if err == nil { + t.Errorf("CombinSignatures succeeded when it should've failed") + } + + pss := make([]*PartialSignatureVt, 256) + + _, err = bls.CombineSignatures(pss...) + if err == nil { + t.Errorf("CombinSignatures succeeded when it should've failed") + } +} diff --git a/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_pop_test.go b/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_pop_test.go new file mode 100755 index 000000000..d9ddaa82c --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/tiny_bls_sig_pop_test.go @@ -0,0 +1,845 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "bytes" + "math/big" + "math/rand" + "testing" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" +) + +const numAggregateG1 = 10 + +func TestGetPublicKeyG2(t *testing.T) { + sk := genSecretKey(t) + pk := genPublicKeyVt(sk, t) + actual := marshalStruct(pk, t) + expected := []byte{175, 76, 33, 103, 184, 172, 12, 111, 24, 87, 84, 61, 243, 82, 99, 76, 131, 95, 171, 237, 145, 143, 7, 93, 205, 148, 104, 29, 153, 103, 187, 206, 112, 223, 252, 198, 102, 41, 38, 244, 228, 223, 102, 16, 216, 152, 231, 250, 7, 111, 90, 98, 194, 244, 101, 251, 69, 130, 11, 209, 41, 210, 133, 105, 217, 179, 190, 1, 6, 155, 135, 2, 168, 249, 253, 41, 59, 87, 8, 49, 231, 198, 142, 30, 186, 44, 175, 17, 198, 63, 210, 176, 237, 171, 11, 127} + if !bytes.Equal(actual, expected) { + t.Errorf("Expected GetPublicKeyVt to pass but failed.") + } +} + +func testSignG1(message []byte, t *testing.T) { + sk := genSecretKey(t) + sig := genSignatureVt(sk, message, t) + pk := genPublicKeyVt(sk, t) + + bls := NewSigPopVt() + + if res, _ := bls.Verify(pk, message, sig); !res { + t.Errorf("createSignatureVt failed when it should've passed.") + } +} + +func TestSignG1EmptyNilMessage(t *testing.T) { + sk := genSecretKey(t) + bls := NewSigPopVt() + sig, _ := bls.Sign(sk, nil) + pk := genPublicKeyVt(sk, t) + + if res, _ := bls.Verify(pk, nil, sig); res { + t.Errorf("createSignature succeeded when it should've failed") + } + + message := []byte{} + sig = genSignatureVt(sk, message, t) + + if res, err := bls.Verify(pk, message, sig); !res { + t.Errorf("create and verify failed on empty message: %v", err) + } +} + +func TestSignG1OneByteMessage(t *testing.T) { + message := []byte{1} + testSignG1(message, t) +} + +func TestSignG1LargeMessage(t *testing.T) { + message := make([]byte, 1048576) + testSignG1(message, t) +} + +func TestSignG1RandomMessage(t *testing.T) { + message := make([]byte, 65537) + readRand(message, t) + testSignG1(message, t) +} + +func TestSignG1BadMessage(t *testing.T) { + message := make([]byte, 1024) + sk := genSecretKey(t) + sig := genSignatureVt(sk, message, t) + pk := genPublicKeyVt(sk, t) + message = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0} + + bls := NewSigPopVt() + + if res, _ := bls.Verify(pk, message, sig); res { + t.Errorf("Expected signature to not verify") + } +} + +func TestBadConversionsG1(t *testing.T) { + sk := genSecretKey(t) + message := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0} + sig := genSignatureVt(sk, message, t) + pk := genPublicKeyVt(sk, t) + + bls := NewSigPopVt() + + if res, _ := bls.Verify(pk, message, sig); !res { + t.Errorf("Signature should be valid") + } + if res, _ := sig.verify(pk, message, blsSignaturePopVtDst); !res { + t.Errorf("Signature should be valid") + } + + // Convert public key to signature in G2 + sig2 := new(Signature) + err := sig2.UnmarshalBinary(marshalStruct(pk, t)) + if err != nil { + t.Errorf("Should be able to convert to signature in G2") + } + pk2 := new(PublicKey) + err = pk2.UnmarshalBinary(marshalStruct(sig, t)) + if err != nil { + t.Errorf("Should be able to convert to public key in G1") + } + + res, _ := pk2.verifySignature(message, sig2, blsSignaturePopVtDst) + if res { + t.Errorf("The signature shouldn't verify") + } +} + +func TestAggregatePublicKeysG2(t *testing.T) { + pks := []*PublicKeyVt{} + ikm := make([]byte, 32) + for i := 0; i < 20; i++ { + readRand(ikm, t) + sk := genRandSecretKey(ikm, t) + pk := genPublicKeyVt(sk, t) + pks = append(pks, pk) + } + apk1, err := aggregatePublicKeysVt(pks...) + if err != nil { + t.Errorf("%v", err) + } + rand.Seed(1234567890) + rand.Shuffle(len(pks), func(i, j int) { pks[i], pks[j] = pks[j], pks[i] }) + apk2, err := aggregatePublicKeysVt(pks...) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(marshalStruct(apk1, t), marshalStruct(apk2, t)) { + t.Errorf("Aggregated public keys should be equal") + } + rand.Shuffle(len(pks), func(i, j int) { pks[i], pks[j] = pks[j], pks[i] }) + apk1, err = aggregatePublicKeysVt(pks...) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(marshalStruct(apk1, t), marshalStruct(apk2, t)) { + t.Errorf("Aggregated public keys should be equal") + } +} + +func TestAggregateSignaturesG1(t *testing.T) { + sigs := []*SignatureVt{} + ikm := make([]byte, 32) + for i := 0; i < 20; i++ { + readRand(ikm, t) + sk := genRandSecretKey(ikm, t) + sig := genSignatureVt(sk, ikm, t) + sigs = append(sigs, sig) + } + asig1, err := aggregateSignaturesVt(sigs...) + if err != nil { + t.Errorf("%v", err) + } + rand.Seed(1234567890) + rand.Shuffle(len(sigs), func(i, j int) { sigs[i], sigs[j] = sigs[j], sigs[i] }) + asig2, err := aggregateSignaturesVt(sigs...) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(marshalStruct(asig1, t), marshalStruct(asig2, t)) { + t.Errorf("Aggregated signatures should be equal") + } + rand.Shuffle(len(sigs), func(i, j int) { sigs[i], sigs[j] = sigs[j], sigs[i] }) + asig1, err = aggregateSignaturesVt(sigs...) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(marshalStruct(asig1, t), marshalStruct(asig2, t)) { + t.Errorf("Aggregated signatures should be equal") + } +} + +func initAggregatedTestValuesG1(messages [][]byte, t *testing.T) ([]*PublicKeyVt, []*SignatureVt) { + pks := []*PublicKeyVt{} + sigs := []*SignatureVt{} + ikm := make([]byte, 32) + for i := 0; i < numAggregateG1; i++ { + readRand(ikm, t) + sk := genRandSecretKey(ikm, t) + sig := genSignatureVt(sk, messages[i%len(messages)], t) + sigs = append(sigs, sig) + pk := genPublicKeyVt(sk, t) + pks = append(pks, pk) + } + return pks, sigs +} + +func TestAggregatedFunctionalityG1(t *testing.T) { + message := make([]byte, 20) + messages := make([][]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG1(messages, t) + + bls := NewSigPopVt() + asig, err := bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + apk, err := bls.AggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + if res, _ := bls.VerifyMultiSignature(apk, message, asig); !res { + t.Errorf("Should verify aggregated signatures with same message") + } + if res, _ := asig.verify(apk, message, blsSignaturePopVtDst); !res { + t.Errorf("MultiSignature.verify failed.") + } + if res, _ := apk.verify(message, asig, blsSignaturePopVtDst); !res { + t.Errorf("MultiPublicKey.verify failed.") + } +} + +func TestBadAggregatedFunctionalityG1(t *testing.T) { + message := make([]byte, 20) + messages := make([][]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG1(messages, t) + + bls := NewSigPopVt() + + apk, err := bls.AggregatePublicKeys(pks[2:]...) + if err != nil { + t.Errorf("%v", err) + } + asig, err := bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + + if res, _ := bls.VerifyMultiSignature(apk, message, asig); res { + t.Errorf("Should not verify aggregated signatures with same message when some public keys are missing") + } + + apk, err = bls.AggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + asig, err = bls.AggregateSignatures(sigs[2:]...) + if err != nil { + t.Errorf("%v", err) + } + if res, _ := bls.VerifyMultiSignature(apk, message, asig); res { + t.Errorf("Should not verify aggregated signatures with same message when some signatures are missing") + } + + asig, err = bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + + badmsg := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} + if res, _ := bls.VerifyMultiSignature(apk, badmsg, asig); res { + t.Errorf("Should not verify aggregated signature with bad message") + } +} + +func TestAggregateVerifyG1Pass(t *testing.T) { + messages := make([][]byte, numAggregateG1) + for i := 0; i < numAggregateG1; i++ { + message := make([]byte, 20) + readRand(message, t) + messages[i] = message + } + pks, sigs := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + if res, _ := bls.AggregateVerify(pks, messages, sigs); !res { + t.Errorf("Expected aggregateVerify to pass but failed") + } +} + +func TestAggregateVerifyG1MsgSigCntMismatch(t *testing.T) { + messages := make([][]byte, 8) + for i := 0; i < 8; i++ { + message := make([]byte, 20) + readRand(message, t) + messages[i] = message + } + + pks, sigs := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + if res, _ := bls.AggregateVerify(pks, messages, sigs); res { + t.Errorf("Expected AggregateVerifyG1 to fail with duplicate message but passed") + } +} + +func TestAggregateVerifyG1FailDupMsg(t *testing.T) { + messages := make([][]byte, 10) + for i := 0; i < 9; i++ { + message := make([]byte, 20) + readRand(message, t) + messages[i] = message + } + // Duplicate message + messages[9] = messages[0] + pks, sigs := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + if res, _ := bls.AggregateVerify(pks, messages, sigs); res { + t.Errorf("Expected aggregateVerify to fail with duplicate message but passed") + } +} + +func TestAggregateVerifyG1FailIncorrectMsg(t *testing.T) { + messages := make([][]byte, 10) + for i := 0; i < 9; i++ { + message := make([]byte, 20) + readRand(message, t) + messages[i] = message + } + // Duplicate message + messages[9] = messages[0] + pks, sigs := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + if res, _ := bls.AggregateVerify(pks[2:], messages[2:], sigs); res { + t.Errorf("Expected aggregateVerify to fail with duplicate message but passed") + } +} + +func TestAggregateVerifyG1OneMsg(t *testing.T) { + messages := make([][]byte, 1) + messages[0] = make([]byte, 20) + sk := genSecretKey(t) + sig := genSignatureVt(sk, messages[0], t) + pk := genPublicKeyVt(sk, t) + bls := NewSigPopVt() + // Should be the same as verifySignatureVt + if res, _ := bls.AggregateVerify([]*PublicKeyVt{pk}, messages, []*SignatureVt{sig}); !res { + t.Errorf("Expected AggregateVerifyG1OneMsg to pass but failed") + } +} + +func TestVerifyG1Mutability(t *testing.T) { + // verify should not change any inputs + ikm := make([]byte, 32) + ikm_copy := make([]byte, 32) + readRand(ikm, t) + copy(ikm_copy, ikm) + bls := NewSigPopVt() + pk, sk, err := bls.KeygenWithSeed(ikm) + + if !bytes.Equal(ikm, ikm_copy) { + t.Errorf("SigPopVt.KeygenWithSeed modifies ikm") + } + if err != nil { + t.Errorf("Expected KeygenWithSeed to succeed but failed.") + } + sig, err := bls.Sign(sk, ikm) + if !bytes.Equal(ikm, ikm_copy) { + t.Errorf("SigPopVt.Sign modifies message") + } + if err != nil { + t.Errorf("SigPopVt.KeygenWithSeed to succeed but failed.") + } + sigCopy := marshalStruct(sig, t) + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Expected verify to succeed but failed.") + } + if !bytes.Equal(ikm, ikm_copy) { + t.Errorf("SigPopVt.verify modifies message") + } + if !bytes.Equal(sigCopy, marshalStruct(sig, t)) { + t.Errorf("SigPopVt.verify modifies signature") + } +} + +func TestPublicKeyG2FromBadBytes(t *testing.T) { + pk := make([]byte, 32) + err := new(PublicKeyVt).UnmarshalBinary(pk) + if err == nil { + t.Errorf("Expected PublicKeyG2FromBytes to fail but passed") + } + // All zeros + pk = make([]byte, PublicKeyVtSize) + // See https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization + // 1 << 7 == compressed + // 1 << 6 == infinity or zero + pk[0] = 0xc0 + err = new(PublicKeyVt).UnmarshalBinary(pk) + if err == nil { + t.Errorf("Expected PublicKeyG2FromBytes to fail but passed") + } + sk := genSecretKey(t) + pk1, err := sk.GetPublicKeyVt() + if err != nil { + t.Errorf("Expected GetPublicKeyVt to pass but failed.") + } + out := marshalStruct(pk1, t) + out[3] += 1 + err = new(PublicKeyVt).UnmarshalBinary(pk) + if err == nil { + t.Errorf("Expected PublicKeyG2FromBytes to fail but passed") + } +} + +func TestSignatureG1FromBadBytes(t *testing.T) { + sig := make([]byte, 32) + err := new(SignatureVt).UnmarshalBinary(sig) + if err == nil { + t.Errorf("Expected SignatureG1FromBytes to fail but passed") + } + // All zeros + sig = make([]byte, SignatureVtSize) + // See https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization + // 1 << 7 == compressed + // 1 << 6 == infinity or zero + sig[0] = 0xc0 + err = new(SignatureVt).UnmarshalBinary(sig) + if err == nil { + t.Errorf("Expected SignatureG1FromBytes to fail but passed") + } +} + +func TestBadSecretKeyG1(t *testing.T) { + sk := &SecretKey{value: bls12381.Bls12381FqNew()} + pk, err := sk.GetPublicKeyVt() + if err == nil { + t.Errorf("Expected GetPublicKeyVt to fail with 0 byte secret key but passed: %v", pk) + } + _ = sk.UnmarshalBinary(sk.value.Params.BiModulus.Bytes()) + pk, err = sk.GetPublicKeyVt() + if err == nil { + t.Errorf("Expected GetPublicKeyVt to fail with secret key with Q but passed: %v", pk) + } + + err = sk.UnmarshalBinary([]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) + if err == nil { + t.Errorf("Expected SecretKeyFromBytes to fail with not enough bytes but passed: %v", pk) + } + + err = sk.UnmarshalBinary(make([]byte, 32)) + if err == nil { + t.Errorf("Expected SecretKeyFromBytes to fail but passed: %v", pk) + } +} + +func TestProofOfPossessionG1Works(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigPopVt() + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Key gen failed but should've succeeded") + } + pop, err := bls.PopProve(sk) + if err != nil { + t.Errorf("PopProve failed but should've succeeded") + } + if res, _ := bls.PopVerify(pk, pop); !res { + t.Errorf("PopVerify failed but should've succeeded") + } +} + +func TestProofOfPossessionG1FromBadKey(t *testing.T) { + ikm := make([]byte, 32) + value := new(big.Int) + value.SetBytes(ikm) + sk := SecretKey{value: bls12381.Bls12381FqNew().SetBigInt(value)} + _, err := sk.createProofOfPossessionVt(blsSignaturePopVtDst) + if err == nil { + t.Errorf("createProofOfPossessionVt should've failed but succeeded.") + } +} + +func TestProofOfPossessionG1BytesWorks(t *testing.T) { + sk := genSecretKey(t) + pop, err := sk.createProofOfPossessionVt(blsSignaturePopVtDst) + if err != nil { + t.Errorf("CreateProofOfPossesionG1 failed but shouldn've succeeded.") + } + out := marshalStruct(pop, t) + if len(out) != ProofOfPossessionVtSize { + t.Errorf("ProofOfPossessionBytes incorrect size: expected %v, got %v", ProofOfPossessionVtSize, len(out)) + } + pop2 := new(ProofOfPossessionVt) + err = pop2.UnmarshalBinary(out) + if err != nil { + t.Errorf("ProofOfPossessionVt.UnmarshalBinary failed: %v", err) + } + out2 := marshalStruct(pop2, t) + if !bytes.Equal(out, out2) { + t.Errorf("ProofOfPossessionVt.UnmarshalBinary failed, not equal when deserialized") + } +} + +func TestProofOfPossessionG1BadBytes(t *testing.T) { + zeros := make([]byte, ProofOfPossessionVtSize) + temp := new(ProofOfPossessionVt) + err := temp.UnmarshalBinary(zeros) + if err == nil { + t.Errorf("ProofOfPossessionVt.UnmarshalBinary shouldn've failed but succeeded.") + } +} + +func TestProofOfPossessionG1Fails(t *testing.T) { + sk := genSecretKey(t) + pop, err := sk.createProofOfPossessionVt(blsSignaturePopVtDst) + if err != nil { + t.Errorf("Expected createProofOfPossessionVt to succeed but failed.") + } + + ikm := make([]byte, 32) + readRand(ikm, t) + sk = genRandSecretKey(ikm, t) + bad, err := sk.GetPublicKeyVt() + if err != nil { + t.Errorf("Expected PublicKeyG2FromBytes to succeed but failed: %v", err) + } + if res, _ := pop.verify(bad, blsSignaturePopVtDst); res { + t.Errorf("Expected ProofOfPossession verify to fail but succeeded.") + } +} + +func TestMultiSigG1Bytes(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 20) + messages[0] = message + _, sigs := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + msig, err := bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + msigBytes := marshalStruct(msig, t) + if len(msigBytes) != SignatureVtSize { + t.Errorf("Invalid multi-sig length. Expected %d bytes, found %d", SignatureVtSize, len(msigBytes)) + } + msig2 := new(MultiSignatureVt) + err = msig2.UnmarshalBinary(msigBytes) + if err != nil { + t.Errorf("MultiSignatureG1FromBytes failed with %v", err) + } + msigBytes2 := marshalStruct(msig2, t) + + if !bytes.Equal(msigBytes, msigBytes2) { + t.Errorf("Bytes methods not equal.") + } +} + +func TestMultiSigG1BadBytes(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 20) + messages[0] = message + _, sigs := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + msig, err := bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + msigBytes := marshalStruct(msig, t) + if len(msigBytes) != SignatureVtSize { + t.Errorf("Invalid multi-sig length. Expected %d bytes, found %d", SignatureSize, len(msigBytes)) + } + msigBytes[0] = 0 + temp := new(MultiSignatureVt) + err = temp.UnmarshalBinary(msigBytes) + if err == nil { + t.Errorf("MultiSignatureG1FromBytes should've failed but succeeded") + } + msigBytes = make([]byte, SignatureVtSize) + err = temp.UnmarshalBinary(msigBytes) + if err == nil { + t.Errorf("MultiSignatureG1FromBytes should've failed but succeeded") + } +} + +func TestMultiPubkeyG2Bytes(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 20) + messages[0] = message + pks, _ := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + apk, err := bls.AggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + apkBytes := marshalStruct(apk, t) + if len(apkBytes) != PublicKeyVtSize { + t.Errorf("MultiPublicKeyVt has an incorrect size") + } + apk2 := new(MultiPublicKeyVt) + err = apk2.UnmarshalBinary(apkBytes) + if err != nil { + t.Errorf("MultiPublicKeyVt.UnmarshalBinary failed with %v", err) + } + apk2Bytes := marshalStruct(apk2, t) + if !bytes.Equal(apkBytes, apk2Bytes) { + t.Errorf("Bytes methods not equal.") + } +} + +func TestMultiPubkeyG2BadBytes(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 20) + messages[0] = message + pks, _ := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + apk, err := bls.AggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + apkBytes := marshalStruct(apk, t) + if len(apkBytes) != PublicKeyVtSize { + t.Errorf("MultiPublicKeyVt has an incorrect size") + } + apkBytes[0] = 0 + temp := new(MultiPublicKeyVt) + err = temp.UnmarshalBinary(apkBytes) + if err == nil { + t.Errorf("MultiPublicKeyVt.UnmarshalBinary should've failed but succeeded") + } + apkBytes = make([]byte, PublicKeyVtSize) + err = temp.UnmarshalBinary(apkBytes) + if err == nil { + t.Errorf("MultiPublicKeyVt.UnmarshalBinary should've failed but succeeded") + } +} + +func TestFastAggregateVerifyConstituentG1Works(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + + if res, _ := bls.FastAggregateVerifyConstituent(pks, message, sigs); !res { + t.Errorf("FastAggregateVerify failed.") + } +} + +func TestFastAggregateVerifyG1Works(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG1(messages, t) + asig, _ := aggregateSignaturesVt(sigs...) + bls := NewSigPopVt() + + if res, _ := bls.FastAggregateVerify(pks, message, asig); !res { + t.Errorf("FastAggregateVerify failed.") + } +} + +func TestFastAggregateVerifyG1Fails(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG1(messages, t) + bls := NewSigPopVt() + message[0] = 1 + if res, _ := bls.FastAggregateVerifyConstituent(pks, message, sigs); res { + t.Errorf("FastAggregateVerify verified when it should've failed.") + } +} + +func TestCustomPopDstG1Works(t *testing.T) { + bls, _ := NewSigPopVtWithDst("BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_TEST", + "BLS_POP_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_TEST") + msg := make([]byte, 20) + ikm := make([]byte, 32) + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Couldn't create custom dst keys: %v", err) + } + sig, err := bls.Sign(sk, msg) + if err != nil { + t.Errorf("Couldn't sign with custom dst: %v", err) + } + if res, _ := bls.Verify(pk, msg, sig); !res { + t.Errorf("verify fails with custom dst") + } + + pks := make([]*PublicKeyVt, 10) + sigs := make([]*SignatureVt, 10) + pks[0] = pk + sigs[0] = sig + for i := 1; i < 10; i++ { + readRand(ikm, t) + pkt, skt, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Couldn't create custom dst keys: %v", err) + } + sigt, err := bls.Sign(skt, msg) + if err != nil { + t.Errorf("Couldn't sign with custom dst: %v", err) + } + pks[i] = pkt + sigs[i] = sigt + } + + if res, _ := bls.FastAggregateVerifyConstituent(pks, msg, sigs); !res { + t.Errorf("FastAggregateVerify failed with custom dst") + } + + pop, err := bls.PopProve(sk) + if err != nil { + t.Errorf("PopProve failed with custom dst") + } + + if res, _ := bls.PopVerify(pk, pop); !res { + t.Errorf("PopVerify failed with custom dst") + } +} + +func TestBlsPopG1KeyGenWithSeed(t *testing.T) { + ikm := []byte("Not enough bytes") + bls := NewSigPopVt() + _, _, err := bls.KeygenWithSeed(ikm) + if err == nil { + t.Errorf("Expected KeygenWithSeed to fail but succeeded") + } +} + +func TestBlsPopG1KeyGen(t *testing.T) { + bls := NewSigPopVt() + _, _, err := bls.Keygen() + if err != nil { + t.Errorf("Keygen failed: %v", err) + } +} + +func TestPopVtThresholdKeygenBadInputs(t *testing.T) { + bls := NewSigPopVt() + _, _, err := bls.ThresholdKeygen(0, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(1, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(3, 2) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } +} + +func TestPopVtThresholdKeygen(t *testing.T) { + bls := NewSigPopVt() + _, sks, err := bls.ThresholdKeygen(3, 5) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + if len(sks) != 5 { + t.Errorf("ThresholdKeygen did not produce enough shares") + } +} + +func TestPopPartialSignVt(t *testing.T) { + ikm := make([]byte, 32) + bls := NewSigPopVt() + pk, sks, err := bls.ThresholdKeygenWithSeed(ikm, 2, 4) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + msg := make([]byte, 10) + sig1, err := bls.PartialSign(sks[0], msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig2, err := bls.PartialSign(sks[1], msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig, err := bls.CombineSignatures(sig1, sig2) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + + if res, _ := bls.Verify(pk, msg, sig); !res { + t.Errorf("Combined signature does not verify") + } + + sig, err = bls.CombineSignatures(sig1) + if err == nil { + t.Errorf("CombineSignatures succeeded when it should've failed") + } + if res, _ := bls.Verify(pk, msg, sig); res { + t.Errorf("Combined signature verify succeeded when it should've failed") + } +} + +// Ensure that mixed partial signatures from distinct origins create invalid composite signatures +func TestPopVtPartialMixupShares(t *testing.T) { + total := uint(5) + ikm := make([]byte, 32) + bls := NewSigPopVt() + pk1, sks1, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + for i := range ikm { + ikm[i] = 1 + } + pk2, sks2, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + + // Generate partial signatures for both sets of keys + msg := make([]byte, 10) + sigs1 := make([]*PartialSignatureVt, total) + sigs2 := make([]*PartialSignatureVt, total) + for i := range sks1 { + sigs1[i], err = bls.PartialSign(sks1[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + sigs2[i], err = bls.PartialSign(sks2[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + } + + // Try combining 2 from group 1 and 2 from group 2 + sig, err := bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[2], sigs2[3]) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + // Signature shouldn't validate + if res, _ := bls.Verify(pk1, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + if res, _ := bls.Verify(pk2, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + // Should error out due to duplicate identifiers + _, err = bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[0], sigs2[1]) + if err == nil { + t.Errorf("CombineSignatures expected to fail but succeeded.") + } +} diff --git a/pkg/crypto/signatures/bls/bls_sig/usual_bls.go b/pkg/crypto/signatures/bls/bls_sig/usual_bls.go new file mode 100755 index 000000000..a827b1883 --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/usual_bls.go @@ -0,0 +1,446 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "fmt" +) + +const ( + // Domain separation tag for basic signatures + // according to section 4.2.1 in + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 + blsSignatureBasicDst = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_" + // Domain separation tag for basic signatures + // according to section 4.2.2 in + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 + blsSignatureAugDst = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_" + // Domain separation tag for proof of possession signatures + // according to section 4.2.3 in + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 + blsSignaturePopDst = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" + // Domain separation tag for proof of possession proofs + // according to section 4.2.3 in + // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 + blsPopProofDst = "BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" +) + +type BlsScheme interface { + Keygen() (*PublicKey, *SecretKey, error) + KeygenWithSeed(ikm []byte) (*PublicKey, *SecretKey, error) + Sign(sk *SecretKey, msg []byte) (*Signature, error) + Verify(pk *PublicKey, msg []byte, sig *Signature) bool + AggregateVerify(pks []*PublicKey, msgs [][]byte, sigs []*Signature) bool +} + +// generateKeys creates 32 bytes of random data to be fed to +// generateKeysWithSeed +func generateKeys() (*PublicKey, *SecretKey, error) { + ikm, err := generateRandBytes(32) + if err != nil { + return nil, nil, err + } + return generateKeysWithSeed(ikm) +} + +// generateKeysWithSeed generates a BLS key pair given input key material (ikm) +func generateKeysWithSeed(ikm []byte) (*PublicKey, *SecretKey, error) { + sk, err := new(SecretKey).Generate(ikm) + if err != nil { + return nil, nil, err + } + pk, err := sk.GetPublicKey() + if err != nil { + return nil, nil, err + } + return pk, sk, nil +} + +// thresholdGenerateKeys will generate random secret key shares and the corresponding public key +func thresholdGenerateKeys(threshold, total uint) (*PublicKey, []*SecretKeyShare, error) { + pk, sk, err := generateKeys() + if err != nil { + return nil, nil, err + } + shares, err := thresholdizeSecretKey(sk, threshold, total) + if err != nil { + return nil, nil, err + } + return pk, shares, nil +} + +// thresholdGenerateKeysWithSeed will generate random secret key shares and the corresponding public key +// using the corresponding seed `ikm` +func thresholdGenerateKeysWithSeed(ikm []byte, threshold, total uint) (*PublicKey, []*SecretKeyShare, error) { + pk, sk, err := generateKeysWithSeed(ikm) + if err != nil { + return nil, nil, err + } + shares, err := thresholdizeSecretKey(sk, threshold, total) + if err != nil { + return nil, nil, err + } + return pk, shares, nil +} + +// SigBasic is minimal-pubkey-size scheme that doesn't support FastAggregateVerificiation. +// see: https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03#section-4.2.1 +type SigBasic struct { + dst string +} + +// Creates a new BLS basic signature scheme with the standard domain separation tag used for signatures. +func NewSigBasic() *SigBasic { + return &SigBasic{dst: blsSignatureBasicDst} +} + +// Creates a new BLS basic signature scheme with a custom domain separation tag used for signatures. +func NewSigBasicWithDst(signDst string) *SigBasic { + return &SigBasic{dst: signDst} +} + +// Creates a new BLS key pair +func (b SigBasic) Keygen() (*PublicKey, *SecretKey, error) { + return generateKeys() +} + +// Creates a new BLS key pair +// Input key material (ikm) MUST be at least 32 bytes long, +// but it MAY be longer. +func (b SigBasic) KeygenWithSeed(ikm []byte) (*PublicKey, *SecretKey, error) { + return generateKeysWithSeed(ikm) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigBasic) ThresholdKeygen(threshold, total uint) (*PublicKey, []*SecretKeyShare, error) { + return thresholdGenerateKeys(threshold, total) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigBasic) ThresholdKeygenWithSeed(ikm []byte, threshold, total uint) (*PublicKey, []*SecretKeyShare, error) { + return thresholdGenerateKeysWithSeed(ikm, threshold, total) +} + +// Computes a signature in G2 from sk, a secret key, and a message +func (b SigBasic) Sign(sk *SecretKey, msg []byte) (*Signature, error) { + return sk.createSignature(msg, b.dst) +} + +// Compute a partial signature in G2 that can be combined with other partial signature +func (b SigBasic) PartialSign(sks *SecretKeyShare, msg []byte) (*PartialSignature, error) { + return sks.partialSign(msg, b.dst) +} + +// CombineSignatures takes partial signatures to yield a completed signature +func (b SigBasic) CombineSignatures(sigs ...*PartialSignature) (*Signature, error) { + return combineSigs(sigs) +} + +// Checks that a signature is valid for the message under the public key pk +func (b SigBasic) Verify(pk *PublicKey, msg []byte, sig *Signature) (bool, error) { + return pk.verifySignature(msg, sig, b.dst) +} + +// The AggregateVerify algorithm checks an aggregated signature over +// several (PK, message, signature) pairs. +// Each message must be different or this will return false. +// See section 3.1.1 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigBasic) AggregateVerify(pks []*PublicKey, msgs [][]byte, sigs []*Signature) (bool, error) { + if !allRowsUnique(msgs) { + return false, fmt.Errorf("all messages must be distinct") + } + asig, err := aggregateSignatures(sigs...) + if err != nil { + return false, err + } + return asig.aggregateVerify(pks, msgs, b.dst) +} + +// SigAug is minimal-pubkey-size scheme that doesn't support FastAggregateVerificiation. +// see: https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03#section-4.2.2 +type SigAug struct { + dst string +} + +// Creates a new BLS message augmentation signature scheme with the standard domain separation tag used for signatures. +func NewSigAug() *SigAug { + return &SigAug{dst: blsSignatureAugDst} +} + +// Creates a new BLS message augmentation signature scheme with a custom domain separation tag used for signatures. +func NewSigAugWithDst(signDst string) *SigAug { + return &SigAug{dst: signDst} +} + +// Creates a new BLS key pair +func (b SigAug) Keygen() (*PublicKey, *SecretKey, error) { + return generateKeys() +} + +// Creates a new BLS secret key +// Input key material (ikm) MUST be at least 32 bytes long, +// but it MAY be longer. +func (b SigAug) KeygenWithSeed(ikm []byte) (*PublicKey, *SecretKey, error) { + return generateKeysWithSeed(ikm) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigAug) ThresholdKeygen(threshold, total uint) (*PublicKey, []*SecretKeyShare, error) { + return thresholdGenerateKeys(threshold, total) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigAug) ThresholdKeygenWithSeed(ikm []byte, threshold, total uint) (*PublicKey, []*SecretKeyShare, error) { + return thresholdGenerateKeysWithSeed(ikm, threshold, total) +} + +// Computes a signature in G1 from sk, a secret key, and a message +// See section 3.2.1 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigAug) Sign(sk *SecretKey, msg []byte) (*Signature, error) { + if len(msg) == 0 { + return nil, fmt.Errorf("message cannot be empty or nil") + } + + pk, err := sk.GetPublicKey() + if err != nil { + return nil, err + } + bytes, err := pk.MarshalBinary() + if err != nil { + return nil, fmt.Errorf("MarshalBinary failed") + } + bytes = append(bytes, msg...) + return sk.createSignature(bytes, b.dst) +} + +// Compute a partial signature in G2 that can be combined with other partial signature +func (b SigAug) PartialSign(sks *SecretKeyShare, pk *PublicKey, msg []byte) (*PartialSignature, error) { + if len(msg) == 0 { + return nil, fmt.Errorf("message cannot be empty or nil") + } + + bytes, err := pk.MarshalBinary() + if err != nil { + return nil, fmt.Errorf("MarshalBinary failed") + } + bytes = append(bytes, msg...) + return sks.partialSign(bytes, b.dst) +} + +// CombineSignatures takes partial signatures to yield a completed signature +func (b SigAug) CombineSignatures(sigs ...*PartialSignature) (*Signature, error) { + return combineSigs(sigs) +} + +// Checks that a signature is valid for the message under the public key pk +// See section 3.2.2 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigAug) Verify(pk *PublicKey, msg []byte, sig *Signature) (bool, error) { + bytes, err := pk.MarshalBinary() + if err != nil { + return false, err + } + bytes = append(bytes, msg...) + return pk.verifySignature(bytes, sig, b.dst) +} + +// The AggregateVerify algorithm checks an aggregated signature over +// several (PK, message, signature) pairs. +// See section 3.2.3 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigAug) AggregateVerify(pks []*PublicKey, msgs [][]byte, sigs []*Signature) (bool, error) { + if len(pks) != len(msgs) { + return false, fmt.Errorf("the number of public keys does not match the number of messages: %v != %v", len(pks), len(msgs)) + } + data := make([][]byte, len(msgs)) + for i, msg := range msgs { + bytes, err := pks[i].MarshalBinary() + if err != nil { + return false, err + } + data[i] = append(bytes, msg...) + } + asig, err := aggregateSignatures(sigs...) + if err != nil { + return false, err + } + return asig.aggregateVerify(pks, data, b.dst) +} + +// SigEth2 supports signatures on Eth2. +// Internally is an alias for SigPop +type SigEth2 = SigPop + +// NewSigEth2 Creates a new BLS ETH2 signature scheme with the standard domain separation tag used for signatures. +func NewSigEth2() *SigEth2 { + return NewSigPop() +} + +// SigPop is minimal-pubkey-size scheme that supports FastAggregateVerification +// and requires using proofs of possession to mitigate rogue-key attacks +// see: https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03#section-4.2.3 +type SigPop struct { + sigDst string + popDst string +} + +// Creates a new BLS proof of possession signature scheme with the standard domain separation tag used for signatures. +func NewSigPop() *SigPop { + return &SigPop{sigDst: blsSignaturePopDst, popDst: blsPopProofDst} +} + +// Creates a new BLS message proof of possession signature scheme with a custom domain separation tag used for signatures. +func NewSigPopWithDst(signDst, popDst string) (*SigPop, error) { + if signDst == popDst { + return nil, fmt.Errorf("domain separation tags cannot be equal") + } + return &SigPop{sigDst: signDst, popDst: popDst}, nil +} + +// Creates a new BLS key pair +func (b SigPop) Keygen() (*PublicKey, *SecretKey, error) { + return generateKeys() +} + +// Creates a new BLS secret key +// Input key material (ikm) MUST be at least 32 bytes long, +// but it MAY be longer. +func (b SigPop) KeygenWithSeed(ikm []byte) (*PublicKey, *SecretKey, error) { + return generateKeysWithSeed(ikm) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigPop) ThresholdKeygen(threshold, total uint) (*PublicKey, []*SecretKeyShare, error) { + return thresholdGenerateKeys(threshold, total) +} + +// ThresholdKeyGen generates a public key and `total` secret key shares such that +// `threshold` of them can be combined in signatures +func (b SigPop) ThresholdKeygenWithSeed(ikm []byte, threshold, total uint) (*PublicKey, []*SecretKeyShare, error) { + return thresholdGenerateKeysWithSeed(ikm, threshold, total) +} + +// Computes a signature in G2 from sk, a secret key, and a message +// See section 2.6 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPop) Sign(sk *SecretKey, msg []byte) (*Signature, error) { + return sk.createSignature(msg, b.sigDst) +} + +// Compute a partial signature in G2 that can be combined with other partial signature +func (b SigPop) PartialSign(sks *SecretKeyShare, msg []byte) (*PartialSignature, error) { + return sks.partialSign(msg, b.sigDst) +} + +// CombineSignatures takes partial signatures to yield a completed signature +func (b SigPop) CombineSignatures(sigs ...*PartialSignature) (*Signature, error) { + return combineSigs(sigs) +} + +// Checks that a signature is valid for the message under the public key pk +// See section 2.7 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPop) Verify(pk *PublicKey, msg []byte, sig *Signature) (bool, error) { + return pk.verifySignature(msg, sig, b.sigDst) +} + +// The aggregateVerify algorithm checks an aggregated signature over +// several (PK, message, signature) pairs. +// Each message must be different or this will return false. +// See section 3.1.1 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPop) AggregateVerify(pks []*PublicKey, msgs [][]byte, sigs []*Signature) (bool, error) { + if !allRowsUnique(msgs) { + return false, fmt.Errorf("all messages must be distinct") + } + asig, err := aggregateSignatures(sigs...) + if err != nil { + return false, err + } + return asig.aggregateVerify(pks, msgs, b.sigDst) +} + +// Combine many signatures together to form a Multisignature. +// Multisignatures can be created when multiple signers jointly +// generate signatures over the same message. +func (b SigPop) AggregateSignatures(sigs ...*Signature) (*MultiSignature, error) { + g1, err := aggregateSignatures(sigs...) + if err != nil { + return nil, err + } + return &MultiSignature{value: g1.Value}, nil +} + +// Combine many public keys together to form a Multipublickey. +// Multipublickeys are used to verify multisignatures. +func (b SigPop) AggregatePublicKeys(pks ...*PublicKey) (*MultiPublicKey, error) { + g2, err := aggregatePublicKeys(pks...) + if err != nil { + return nil, err + } + return &MultiPublicKey{value: g2.value}, nil +} + +// Checks that a multisignature is valid for the message under the multi public key +// Similar to FastAggregateVerify except the keys and signatures have already been +// combined. See section 3.3.4 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPop) VerifyMultiSignature(pk *MultiPublicKey, msg []byte, sig *MultiSignature) (bool, error) { + s := &Signature{Value: sig.value} + p := &PublicKey{value: pk.value} + return p.verifySignature(msg, s, b.sigDst) +} + +// FastAggregateVerify verifies an aggregated signature against the specified message and set of public keys. +// See section 3.3.4 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPop) FastAggregateVerify(pks []*PublicKey, msg []byte, asig *Signature) (bool, error) { + apk, err := aggregatePublicKeys(pks...) + if err != nil { + return false, err + } + return apk.verifySignature(msg, asig, b.sigDst) +} + +// FastAggregateVerifyConstituent aggregates all constituent signatures and the verifies +// them against the specified message and public keys +// See section 3.3.4 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPop) FastAggregateVerifyConstituent(pks []*PublicKey, msg []byte, sigs []*Signature) (bool, error) { + // Aggregate the constituent signatures + asig, err := aggregateSignatures(sigs...) + if err != nil { + return false, err + } + // And verify + return b.FastAggregateVerify(pks, msg, asig) +} + +// Create a proof of possession for the corresponding public key. +// A proof of possession must be created for each public key to be used +// in FastAggregateVerify or a Multipublickey to avoid rogue key attacks. +// See section 3.3.2 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPop) PopProve(sk *SecretKey) (*ProofOfPossession, error) { + return sk.createProofOfPossession(b.popDst) +} + +// verify a proof of possession for the corresponding public key is valid. +// A proof of possession must be created for each public key to be used +// in FastAggregateVerify or a Multipublickey to avoid rogue key attacks. +// See section 3.3.3 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (b SigPop) PopVerify(pk *PublicKey, pop2 *ProofOfPossession) (bool, error) { + return pop2.verify(pk, b.popDst) +} diff --git a/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig.go b/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig.go new file mode 100755 index 000000000..5c1cc367b --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig.go @@ -0,0 +1,491 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// Implement BLS signatures on the BLS12-381 curve +// according to https://crypto.standford.edu/~dabo/pubs/papers/BLSmultisig.html +// and https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +// this file implements signatures in G2 and public keys in G1. +// Public Keys and Signatures can be aggregated but the consumer +// must use proofs of possession to defend against rogue-key attacks. + +const ( + // Public key size in G1 + PublicKeySize = 48 + // Signature size in G2 + SignatureSize = 96 + // Proof of Possession in G2 + ProofOfPossessionSize = 96 +) + +// Represents a public key in G1 +type PublicKey struct { + value bls12381.G1 +} + +// Serialize a public key to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (pk PublicKey) MarshalBinary() ([]byte, error) { + out := pk.value.ToCompressed() + return out[:], nil +} + +// Deserialize a public key from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the public key +// otherwise it will return an error +func (pk *PublicKey) UnmarshalBinary(data []byte) error { + if len(data) != PublicKeySize { + return fmt.Errorf("public key must be %d bytes", PublicKeySize) + } + var blob [PublicKeySize]byte + copy(blob[:], data) + p1, err := new(bls12381.G1).FromCompressed(&blob) + if err != nil { + return err + } + if p1.IsIdentity() == 1 { + return fmt.Errorf("public keys cannot be zero") + } + pk.value = *p1 + return nil +} + +// Represents a BLS signature in G2 +type Signature struct { + Value bls12381.G2 +} + +// Serialize a signature to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (sig Signature) MarshalBinary() ([]byte, error) { + out := sig.Value.ToCompressed() + return out[:], nil +} + +func (sig Signature) verify(pk *PublicKey, message []byte, signDst string) (bool, error) { + return pk.verifySignature(message, &sig, signDst) +} + +// The AggregateVerify algorithm checks an aggregated signature over +// several (PK, message) pairs. +// The Signature is the output of aggregateSignatures +// Each message must be different or this will return false +// See section 3.1.1 from +// https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (sig Signature) aggregateVerify(pks []*PublicKey, msgs [][]byte, signDst string) (bool, error) { + return sig.coreAggregateVerify(pks, msgs, signDst) +} + +func (sig Signature) coreAggregateVerify(pks []*PublicKey, msgs [][]byte, signDst string) (bool, error) { + if len(pks) < 1 { + return false, fmt.Errorf("at least one key is required") + } + if len(msgs) < 1 { + return false, fmt.Errorf("at least one message is required") + } + if len(pks) != len(msgs) { + return false, fmt.Errorf("the number of public keys does not match the number of messages: %v != %v", len(pks), len(msgs)) + } + if sig.Value.InCorrectSubgroup() == 0 { + return false, fmt.Errorf("signature is not in the correct subgroup") + } + + dst := []byte(signDst) + engine := new(bls12381.Engine) + // e(pk_1, H(m_1))*...*e(pk_N, H(m_N)) == e(g1, s) + // However, we use only one miller loop + // by doing the equivalent of + // e(pk_1, H(m_1))*...*e(pk_N, H(m_N)) * e(g1^-1, s) == 1 + for i, pk := range pks { + if pk == nil { + return false, fmt.Errorf("public key at %d is nil", i) + } + if pk.value.IsIdentity() == 1 || pk.value.InCorrectSubgroup() == 0 { + return false, fmt.Errorf("public key at %d is not in the correct subgroup", i) + } + p2 := new(bls12381.G2).Hash(native.EllipticPointHasherSha256(), msgs[i], dst) + engine.AddPair(&pk.value, p2) + } + engine.AddPairInvG1(new(bls12381.G1).Generator(), &sig.Value) + return engine.Check(), nil +} + +// Deserialize a signature from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the Signature +// otherwise it will return an error +func (sig *Signature) UnmarshalBinary(data []byte) error { + if len(data) != SignatureSize { + return fmt.Errorf("signature must be %d bytes", SignatureSize) + } + var blob [SignatureSize]byte + copy(blob[:], data) + p2, err := new(bls12381.G2).FromCompressed(&blob) + if err != nil { + return err + } + if p2.IsIdentity() == 1 { + return fmt.Errorf("signatures cannot be zero") + } + sig.Value = *p2 + return nil +} + +// Get the corresponding public key from a secret key +// Verifies the public key is in the correct subgroup +func (sk SecretKey) GetPublicKey() (*PublicKey, error) { + result := new(bls12381.G1).Generator() + result.Mul(result, sk.value) + if result.InCorrectSubgroup() == 0 || result.IsIdentity() == 1 { + return nil, fmt.Errorf("point is not in correct subgroup") + } + return &PublicKey{value: *result}, nil +} + +// Compute a signature from a secret key and message +// This signature is deterministic which protects against +// attacks arising from signing with bad randomness like +// the nonce reuse attack on ECDSA. `message` is +// hashed to a point in G2 as described in to +// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/?include_text=1 +// See Section 2.6 in https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +// nil message is not permitted but empty slice is allowed +func (sk SecretKey) createSignature(message []byte, dst string) (*Signature, error) { + if message == nil { + return nil, fmt.Errorf("message cannot be nil") + } + if sk.value.IsZero() == 1 { + return nil, fmt.Errorf("invalid secret key") + } + p2 := new(bls12381.G2).Hash(native.EllipticPointHasherSha256(), message, []byte(dst)) + result := new(bls12381.G2).Mul(p2, sk.value) + if result.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("point is not on correct subgroup") + } + return &Signature{Value: *result}, nil +} + +// Verify a signature is valid for the message under this public key. +// See Section 2.7 in https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-03 +func (pk PublicKey) verifySignature(message []byte, signature *Signature, dst string) (bool, error) { + if signature == nil || message == nil || pk.value.IsIdentity() == 1 { + return false, fmt.Errorf("signature and message and public key cannot be nil or zero") + } + if signature.Value.IsIdentity() == 1 || signature.Value.InCorrectSubgroup() == 0 { + return false, fmt.Errorf("signature is not in the correct subgroup") + } + engine := new(bls12381.Engine) + + p2 := new(bls12381.G2).Hash(native.EllipticPointHasherSha256(), message, []byte(dst)) + // e(pk, H(m)) == e(g1, s) + // However, we can reduce the number of miller loops + // by doing the equivalent of + // e(pk^-1, H(m)) * e(g1, s) == 1 + engine.AddPair(&pk.value, p2) + engine.AddPairInvG1(new(bls12381.G1).Generator(), &signature.Value) + return engine.Check(), nil +} + +// Combine public keys into one aggregated key +func aggregatePublicKeys(pks ...*PublicKey) (*PublicKey, error) { + if len(pks) < 1 { + return nil, fmt.Errorf("at least one public key is required") + } + result := new(bls12381.G1).Identity() + for i, k := range pks { + if k == nil { + return nil, fmt.Errorf("key at %d is nil, keys cannot be nil", i) + } + if k.value.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("key at %d is not in the correct subgroup", i) + } + result.Add(result, &k.value) + } + return &PublicKey{value: *result}, nil +} + +// Combine signatures into one aggregated signature +func aggregateSignatures(sigs ...*Signature) (*Signature, error) { + if len(sigs) < 1 { + return nil, fmt.Errorf("at least one signature is required") + } + result := new(bls12381.G2).Identity() + for i, s := range sigs { + if s == nil { + return nil, fmt.Errorf("signature at %d is nil, signature cannot be nil", i) + } + if s.Value.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("signature at %d is not in the correct subgroup", i) + } + result.Add(result, &s.Value) + } + return &Signature{Value: *result}, nil +} + +// A proof of possession scheme uses a separate public key validation +// step, called a proof of possession, to defend against rogue key +// attacks. This enables an optimization to aggregate signature +// verification for the case that all signatures are on the same +// message. +type ProofOfPossession struct { + value bls12381.G2 +} + +// Generates a proof-of-possession (PoP) for this secret key. The PoP signature should be verified before +// before accepting any aggregate signatures related to the corresponding pubkey. +func (sk SecretKey) createProofOfPossession(popDst string) (*ProofOfPossession, error) { + pk, err := sk.GetPublicKey() + if err != nil { + return nil, err + } + msg, err := pk.MarshalBinary() + if err != nil { + return nil, err + } + sig, err := sk.createSignature(msg, popDst) + if err != nil { + return nil, err + } + return &ProofOfPossession{value: sig.Value}, nil +} + +// Serialize a proof of possession to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (pop ProofOfPossession) MarshalBinary() ([]byte, error) { + out := pop.value.ToCompressed() + return out[:], nil +} + +// Deserialize a proof of possession from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the Signature +// otherwise it will return an error +func (pop *ProofOfPossession) UnmarshalBinary(data []byte) error { + p2 := new(Signature) + err := p2.UnmarshalBinary(data) + if err != nil { + return err + } + pop.value = p2.Value + return nil +} + +// Verifies that PoP is valid for this pubkey. In order to prevent rogue key attacks, a PoP must be validated +// for each pubkey in an aggregated signature. +func (pop ProofOfPossession) verify(pk *PublicKey, popDst string) (bool, error) { + if pk == nil { + return false, fmt.Errorf("public key cannot be nil") + } + msg, err := pk.MarshalBinary() + if err != nil { + return false, err + } + return pk.verifySignature(msg, &Signature{Value: pop.value}, popDst) +} + +// Represents an MultiSignature in G2. A multisignature is used when multiple signatures +// are calculated over the same message vs an aggregate signature where each message signed +// is a unique. +type MultiSignature struct { + value bls12381.G2 +} + +// Serialize a multi-signature to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (sig MultiSignature) MarshalBinary() ([]byte, error) { + out := sig.value.ToCompressed() + return out[:], nil +} + +// Check a multisignature is valid for a multipublickey and a message +func (sig MultiSignature) verify(pk *MultiPublicKey, message []byte, signDst string) (bool, error) { + if pk == nil { + return false, fmt.Errorf("public key cannot be nil") + } + p := PublicKey{value: pk.value} + return p.verifySignature(message, &Signature{Value: sig.value}, signDst) +} + +// Deserialize a signature from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the Signature +// otherwise it will return an error +func (sig *MultiSignature) UnmarshalBinary(data []byte) error { + if len(data) != SignatureSize { + return fmt.Errorf("multi signature must be %v bytes", SignatureSize) + } + s2 := new(Signature) + err := s2.UnmarshalBinary(data) + if err != nil { + return err + } + sig.value = s2.Value + return nil +} + +// Represents accumulated multiple Public Keys in G1 for verifying a multisignature +type MultiPublicKey struct { + value bls12381.G1 +} + +// Serialize a public key to a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +func (pk MultiPublicKey) MarshalBinary() ([]byte, error) { + out := pk.value.ToCompressed() + return out[:], nil +} + +// Deserialize a public key from a byte array in compressed form. +// See +// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization +// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html +// If successful, it will assign the public key +// otherwise it will return an error +func (pk *MultiPublicKey) UnmarshalBinary(data []byte) error { + if len(data) != PublicKeySize { + return fmt.Errorf("multi public key must be %v bytes", PublicKeySize) + } + p1 := new(PublicKey) + err := p1.UnmarshalBinary(data) + if err != nil { + return err + } + pk.value = p1.value + return nil +} + +// Check a multisignature is valid for a multipublickey and a message +func (pk MultiPublicKey) verify(message []byte, sig *MultiSignature, signDst string) (bool, error) { + return sig.verify(&pk, message, signDst) +} + +// PartialSignature represents threshold Gap Diffie-Hellman BLS signature +// that can be combined with other partials to yield a completed BLS signature +// See section 3.2 in +type PartialSignature struct { + Identifier byte + Signature bls12381.G2 +} + +// partialSign creates a partial signature that can be combined with other partial signatures +// to yield a complete signature +func (sks SecretKeyShare) partialSign(message []byte, signDst string) (*PartialSignature, error) { + if len(message) == 0 { + return nil, fmt.Errorf("message cannot be empty or nil") + } + p2 := new(bls12381.G2).Hash(native.EllipticPointHasherSha256(), message, []byte(signDst)) + + var blob [SecretKeySize]byte + copy(blob[:], internal.ReverseScalarBytes(sks.value)) + s, err := bls12381.Bls12381FqNew().SetBytes(&blob) + if err != nil { + return nil, err + } + result := new(bls12381.G2).Mul(p2, s) + if result.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("point is not on correct subgroup") + } + return &PartialSignature{Identifier: sks.identifier, Signature: *result}, nil +} + +// combineSigs gathers partial signatures and yields a complete signature +func combineSigs(partials []*PartialSignature) (*Signature, error) { + if len(partials) < 2 { + return nil, fmt.Errorf("must have at least 2 partial signatures") + } + if len(partials) > 255 { + return nil, fmt.Errorf("unsupported to combine more than 255 signatures") + } + + // Don't know the actual values so put the minimum + xVars, yVars, err := splitXY(partials) + if err != nil { + return nil, err + } + + sTmp := new(bls12381.G2).Identity() + sig := new(bls12381.G2).Identity() + + // Lagrange interpolation + basis := bls12381.Bls12381FqNew().SetOne() + for i, xi := range xVars { + basis.SetOne() + + for j, xj := range xVars { + if i == j { + continue + } + + num := bls12381.Bls12381FqNew().Neg(xj) // - x_m + den := bls12381.Bls12381FqNew().Sub(xi, xj) // x_j - x_m + _, wasInverted := den.Invert(den) + // wasInverted == false if den == 0 + if !wasInverted { + return nil, fmt.Errorf("signatures cannot be recombined") + } + basis.Mul(basis, num.Mul(num, den)) + } + sTmp.Mul(yVars[i], basis) + sig.Add(sig, sTmp) + } + if sig.InCorrectSubgroup() == 0 { + return nil, fmt.Errorf("signature is not in the correct subgroup") + } + + return &Signature{Value: *sig}, nil +} + +// Ensure no duplicates x values and convert x values to field elements +func splitXY(partials []*PartialSignature) ([]*native.Field, []*bls12381.G2, error) { + x := make([]*native.Field, len(partials)) + y := make([]*bls12381.G2, len(partials)) + + dup := make(map[byte]bool) + + for i, sp := range partials { + if sp == nil { + return nil, nil, fmt.Errorf("partial signature cannot be nil") + } + if _, exists := dup[sp.Identifier]; exists { + return nil, nil, fmt.Errorf("duplicate signature included") + } + if sp.Signature.InCorrectSubgroup() == 0 { + return nil, nil, fmt.Errorf("signature is not in the correct subgroup") + } + dup[sp.Identifier] = true + x[i] = bls12381.Bls12381FqNew().SetUint64(uint64(sp.Identifier)) + y[i] = &sp.Signature + } + return x, y, nil +} diff --git a/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_aug_test.go b/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_aug_test.go new file mode 100755 index 000000000..31414f352 --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_aug_test.go @@ -0,0 +1,409 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "testing" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" +) + +func generateAugSignatureG2(sk *SecretKey, msg []byte, t *testing.T) *Signature { + bls := NewSigAug() + sig, err := bls.Sign(sk, msg) + if err != nil { + t.Errorf("Aug Sign failed") + } + return sig +} + +func generateAugAggregateDataG2(t *testing.T) ([]*PublicKey, []*Signature, [][]byte) { + msgs := make([][]byte, numAggregateG2) + pks := make([]*PublicKey, numAggregateG2) + sigs := make([]*Signature, numAggregateG2) + ikm := make([]byte, 32) + bls := NewSigAug() + + for i := 0; i < numAggregateG2; i++ { + readRand(ikm, t) + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } + msg := make([]byte, 20) + readRand(msg, t) + sig := generateAugSignatureG2(sk, msg, t) + msgs[i] = msg + sigs[i] = sig + pks[i] = pk + } + return pks, sigs, msgs +} + +func TestAugKeyGenG2Works(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigAug() + _, _, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } +} + +func TestAugKeyGenG2Fail(t *testing.T) { + ikm := make([]byte, 10) + readRand(ikm, t) + bls := NewSigAug() + _, _, err := bls.KeygenWithSeed(ikm) + if err == nil { + t.Errorf("Aug KeyGen succeeded when it should've failed") + } +} + +func TestAugCustomDstG2(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigAugWithDst("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_TEST") + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug Custom Dst KeyGen failed") + } + + readRand(ikm, t) + sig, err := bls.Sign(sk, ikm) + if err != nil { + t.Errorf("Aug Custom Dst Sign failed") + } + + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Aug Custon Dst Verify failed") + } + + ikm[0] = 0 + if res, _ := bls.Verify(pk, ikm, sig); res { + t.Errorf("Aug Custom Dst Verify succeeded when it should've failed.") + } +} + +func TestAugSigningG2(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigAug() + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + readRand(ikm, t) + sig := generateAugSignatureG2(sk, ikm, t) + + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Aug Verify failed") + } + + ikm[0] += 1 + if res, _ := bls.Verify(pk, ikm, sig); res { + t.Errorf("Aug Verify succeeded when it should've failed.") + } +} + +func TestAugSignEmptyMessage(t *testing.T) { + bls := NewSigAug() + _, sk, err := bls.Keygen() + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + // Sign a nil message + _, err = bls.Sign(sk, nil) + if err == nil { + t.Errorf("Expected sign of nil message to fail") + } +} + +func TestAugSignNilMessage(t *testing.T) { + bls := NewSigAug() + _, sk, err := bls.Keygen() + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + // Sign an empty message + _, err = bls.Sign(sk, []byte{}) + if err == nil { + t.Errorf("Expected sign of empty message to fail") + } +} + +func TestAugAggregateVerifyG2Works(t *testing.T) { + pks, sigs, msgs := generateAugAggregateDataG2(t) + bls := NewSigAug() + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Aug AggregateVerify failed") + } +} + +func TestAugAggregateVerifyG2BadPks(t *testing.T) { + bls := NewSigAug() + pks, sigs, msgs := generateAugAggregateDataG2(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Aug AggregateVerify failed") + } + + pks[0] = pks[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug AggregateVerify succeeded when it should've failed") + } + + // Try a zero key to make sure it doesn't crash + pkValue := new(bls12381.G1).Identity() + pks[0] = &PublicKey{value: *pkValue} + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug AggregateVerify succeeded with zero byte public key it should've failed") + } + + // Try with base generator + pkValue.Generator() + pks[0] = &PublicKey{value: *pkValue} + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded with the base generator public key it should've failed") + } +} + +func TestAugAggregateVerifyG2BadSigs(t *testing.T) { + bls := NewSigAug() + pks, sigs, msgs := generateAugAggregateDataG2(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Aug aggregateVerify failed") + } + + sigs[0] = sigs[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded when it should've failed") + } + + // Try a zero key to make sure it doesn't crash + sigValue := new(bls12381.G2).Identity() + sigs[0] = &Signature{Value: *sigValue} + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded with zero byte signature it should've failed") + } + + // Try with base generator + sigValue.Generator() + sigs[0] = &Signature{Value: *sigValue} + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded with the base generator signature it should've failed") + } +} + +func TestAugAggregateVerifyG2BadMsgs(t *testing.T) { + bls := NewSigAug() + pks, sigs, msgs := generateAugAggregateDataG2(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Aug aggregateVerify failed") + } + + // Test len(pks) != len(msgs) + if res, _ := bls.AggregateVerify(pks, msgs[0:8], sigs); res { + t.Errorf("Aug aggregateVerify succeeded when it should've failed") + } + + msgs[0] = msgs[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Aug aggregateVerify succeeded when it should've failed") + } +} + +func TestAugAggregateVerifyG2DupMsg(t *testing.T) { + bls := NewSigAug() + + // Only two messages but repeated + messages := make([][]byte, numAggregateG2) + messages[0] = []byte("Yes") + messages[1] = []byte("No") + for i := 2; i < numAggregateG2; i++ { + messages[i] = messages[i%2] + } + + pks := make([]*PublicKey, numAggregateG2) + sigs := make([]*Signature, numAggregateG2) + + ikm := make([]byte, 32) + for i := 0; i < numAggregateG2; i++ { + readRand(ikm, t) + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Aug KeyGen failed") + } + + sig := generateAugSignatureG2(sk, messages[i], t) + pks[i] = pk + sigs[i] = sig + } + + if res, _ := bls.AggregateVerify(pks, messages, sigs); !res { + t.Errorf("Aug aggregateVerify failed for duplicate messages") + } +} + +func TestBlsAugG2KeyGen(t *testing.T) { + bls := NewSigAug() + _, _, err := bls.Keygen() + if err != nil { + t.Errorf("Keygen failed: %v", err) + } +} + +func TestAugThresholdKeygenBadInputs(t *testing.T) { + bls := NewSigAug() + _, _, err := bls.ThresholdKeygen(0, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(1, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(3, 2) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } +} + +func TestAugThresholdKeygen(t *testing.T) { + bls := NewSigAug() + _, sks, err := bls.ThresholdKeygen(3, 5) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + if len(sks) != 5 { + t.Errorf("ThresholdKeygen did not produce enough shares") + } +} + +func TestAugPartialSign(t *testing.T) { + ikm := make([]byte, 32) + bls := NewSigAug() + pk, sks, err := bls.ThresholdKeygenWithSeed(ikm, 2, 4) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + msg := make([]byte, 10) + sig1, err := bls.PartialSign(sks[0], pk, msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig2, err := bls.PartialSign(sks[1], pk, msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig, err := bls.CombineSignatures(sig1, sig2) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + + if res, _ := bls.Verify(pk, msg, sig); !res { + t.Errorf("Combined signature does not verify") + } + + sig, err = bls.CombineSignatures(sig1) + if err == nil { + t.Errorf("CombineSignatures succeeded when it should've failed") + } + if res, _ := bls.Verify(pk, msg, sig); res { + t.Errorf("Combined signature verify succeeded when it should've failed") + } +} + +// Ensure that mixed partial signatures from distinct origins create invalid composite signatures +func TestAugPartialMixupShares(t *testing.T) { + total := uint(5) + ikm := make([]byte, 32) + bls := NewSigAug() + pk1, sks1, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + for i := range ikm { + ikm[i] = 1 + } + pk2, sks2, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + + // Generate partial signatures for both sets of keys + msg := make([]byte, 10) + sigs1 := make([]*PartialSignature, total) + sigs2 := make([]*PartialSignature, total) + for i := range sks1 { + sigs1[i], err = bls.PartialSign(sks1[i], pk1, msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + sigs2[i], err = bls.PartialSign(sks2[i], pk2, msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + } + + // Try combining 2 from group 1 and 2 from group 2 + sig, err := bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[2], sigs2[3]) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + // Signature shouldn't validate + if res, _ := bls.Verify(pk1, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + if res, _ := bls.Verify(pk2, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + // Should error out due to duplicate identifiers + _, err = bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[0], sigs2[1]) + if err == nil { + t.Errorf("CombineSignatures expected to fail but succeeded.") + } +} + +func TestAugPartialSignEmptyMessage(t *testing.T) { + bls := NewSigAug() + pk, sks, err := bls.ThresholdKeygen(2, 2) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + + // Test signing an empty message + _, err = bls.PartialSign(sks[0], pk, []byte{}) + if err == nil { + t.Errorf("Expected partial sign of empty message to fail") + } +} + +func TestAugPartialSignNilMessage(t *testing.T) { + bls := NewSigAug() + pk, sks, err := bls.ThresholdKeygen(7, 7) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + + // Test signing a nil message + _, err = bls.PartialSign(sks[0], pk, nil) + if err == nil { + t.Errorf("Expected partial sign of nil message to fail") + } +} diff --git a/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_basic_test.go b/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_basic_test.go new file mode 100755 index 000000000..36ebe014f --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_basic_test.go @@ -0,0 +1,409 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "testing" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" +) + +func generateBasicSignatureG2(sk *SecretKey, msg []byte, t *testing.T) *Signature { + bls := NewSigBasic() + sig, err := bls.Sign(sk, msg) + if err != nil { + t.Errorf("Basic Sign failed") + } + return sig +} + +func generateBasicAggregateDataG2(t *testing.T) ([]*PublicKey, []*Signature, [][]byte) { + msgs := make([][]byte, numAggregateG2) + pks := make([]*PublicKey, numAggregateG2) + sigs := make([]*Signature, numAggregateG2) + ikm := make([]byte, 32) + bls := NewSigBasic() + + for i := 0; i < numAggregateG2; i++ { + readRand(ikm, t) + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Basic KeyGen failed") + } + msg := make([]byte, 20) + readRand(msg, t) + sig := generateBasicSignatureG2(sk, msg, t) + msgs[i] = msg + sigs[i] = sig + pks[i] = pk + } + return pks, sigs, msgs +} + +func TestBasicKeyGenG2Works(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigBasic() + _, _, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Basic KeyGen failed") + } +} + +func TestBasicKeyGenG2Fail(t *testing.T) { + ikm := make([]byte, 10) + readRand(ikm, t) + bls := NewSigBasic() + _, _, err := bls.KeygenWithSeed(ikm) + if err == nil { + t.Errorf("Basic KeyGen succeeded when it should've failed") + } +} + +func TestBasicCustomDstG2(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigBasicWithDst("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_TEST") + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Basic Custom Dst KeyGen failed") + } + + readRand(ikm, t) + sig, err := bls.Sign(sk, ikm) + if err != nil { + t.Errorf("Basic Custom Dst Sign failed") + } + + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Basic Custon Dst verify failed") + } + + ikm[0] += 1 + if res, _ := bls.Verify(pk, ikm, sig); res { + t.Errorf("Basic Custom Dst verify succeeded when it should've failed.") + } +} + +func TestBasicSigningG2(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigBasic() + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Basic KeyGen failed") + } + + readRand(ikm, t) + sig := generateBasicSignatureG2(sk, ikm, t) + + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Basic verify failed") + } + + ikm[0] += 1 + if res, _ := bls.Verify(pk, ikm, sig); res { + t.Errorf("Basic verify succeeded when it should've failed.") + } +} + +func TestBasicSigningG2EmptyMessage(t *testing.T) { + // So basic + bls := NewSigBasic() + _, sk, err := bls.Keygen() + if err != nil { + t.Errorf("Basic KeyGen failed") + } + + // Sign an empty message + _, err = bls.Sign(sk, []byte{}) + if err != nil { + t.Errorf("Expected signing empty message to succeed: %v", err) + } +} + +func TestBasicSigningG2NilMessage(t *testing.T) { + // So basic + bls := NewSigBasic() + _, sk, err := bls.Keygen() + if err != nil { + t.Errorf("Basic KeyGen failed") + } + + // Sign an empty message + _, err = bls.Sign(sk, nil) + if err == nil { + t.Errorf("Expected signing nil message to fail") + } +} + +func TestBasicAggregateVerifyG2Works(t *testing.T) { + pks, sigs, msgs := generateBasicAggregateDataG2(t) + bls := NewSigBasic() + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Basic AggregateVerify failed") + } +} + +func TestBasicAggregateVerifyG2BadPks(t *testing.T) { + bls := NewSigBasic() + pks, sigs, msgs := generateBasicAggregateDataG2(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Basic AggregateVerify failed") + } + + pks[0] = pks[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic AggregateVerify succeeded when it should've failed") + } + + // Try a zero key to make sure it doesn't crash + pkValue := new(bls12381.G1).Identity() + pks[0] = &PublicKey{value: *pkValue} + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic AggregateVerify succeeded with zero byte public key it should've failed") + } + + // Try with base generator + pkValue.Generator() + pks[0] = &PublicKey{value: *pkValue} + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded with the base generator public key it should've failed") + } +} + +func TestBasicAggregateVerifyG2BadSigs(t *testing.T) { + bls := NewSigBasic() + pks, sigs, msgs := generateBasicAggregateDataG2(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Basic aggregateVerify failed") + } + + sigs[0] = sigs[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded when it should've failed") + } + + // Try a zero key to make sure it doesn't crash + sigValue := new(bls12381.G2).Identity() + sigs[0] = &Signature{Value: *sigValue} + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded with zero byte signature it should've failed") + } + + // Try with base generator + sigValue.Generator() + sigs[0] = &Signature{Value: *sigValue} + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded with the base generator signature it should've failed") + } +} + +func TestBasicAggregateVerifyG2BadMsgs(t *testing.T) { + bls := NewSigBasic() + pks, sigs, msgs := generateBasicAggregateDataG2(t) + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); !res { + t.Errorf("Basic aggregateVerify failed") + } + + msgs[0] = msgs[1] + + if res, _ := bls.AggregateVerify(pks, msgs, sigs); res { + t.Errorf("Basic aggregateVerify succeeded when it should've failed") + } +} + +func TestBasicThresholdKeygenBadInputs(t *testing.T) { + bls := NewSigBasic() + _, _, err := bls.ThresholdKeygen(0, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(1, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(3, 2) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } +} + +func TestBasicThresholdKeygen(t *testing.T) { + bls := NewSigBasic() + _, sks, err := bls.ThresholdKeygen(3, 5) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + if len(sks) != 5 { + t.Errorf("ThresholdKeygen did not produce enough shares") + } +} + +func TestBasicPartialSign(t *testing.T) { + ikm := make([]byte, 32) + bls := NewSigBasic() + pk, sks, err := bls.ThresholdKeygenWithSeed(ikm, 2, 4) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + msg := make([]byte, 10) + sig1, err := bls.PartialSign(sks[0], msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig2, err := bls.PartialSign(sks[1], msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig, err := bls.CombineSignatures(sig1, sig2) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + + if res, _ := bls.Verify(pk, msg, sig); !res { + t.Errorf("Combined signature does not verify") + } + + sig, err = bls.CombineSignatures(sig1) + if err == nil { + t.Errorf("CombineSignatures succeeded when it should've failed") + } + if res, _ := bls.Verify(pk, msg, sig); res { + t.Errorf("Combined signature verify succeeded when it should've failed") + } +} + +// Ensure that duplicate partial signatures cannot be used to create a complete one +func TestBasicPartialDuplicateShares(t *testing.T) { + total := uint(5) + ikm := make([]byte, 32) + bls := NewSigBasic() + pk1, sks1, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + + // Generate partial signatures for both sets of keys + msg := make([]byte, 10) + sigs1 := make([]*PartialSignature, total) + for i := range sks1 { + sigs1[i], err = bls.PartialSign(sks1[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + } + + // Try combining duplicates from group 1 + sig, err := bls.CombineSignatures(sigs1[0], sigs1[0], sigs1[1], sigs1[1]) + if err == nil { + t.Errorf("CombineSignatures expected to fail but succeeded") + } + // Signature shouldn't validate + if res, _ := bls.Verify(pk1, msg, sig); res { + t.Errorf("CombineSignatures worked with duplicate partial signatures") + } +} + +// Ensure that mixed partial signatures from distinct origins create invalid composite signatures +func TestBasicPartialMixupShares(t *testing.T) { + total := uint(5) + ikm := make([]byte, 32) + bls := NewSigBasic() + pk1, sks1, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + for i := range ikm { + ikm[i] = 1 + } + pk2, sks2, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + + // Generate partial signatures for both sets of keys + msg := make([]byte, 10) + sigs1 := make([]*PartialSignature, total) + sigs2 := make([]*PartialSignature, total) + for i := range sks1 { + sigs1[i], err = bls.PartialSign(sks1[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + sigs2[i], err = bls.PartialSign(sks2[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + } + + // Try combining 2 from group 1 and 2 from group 2 + sig, err := bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[2], sigs2[3]) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + // Signature shouldn't validate + if res, _ := bls.Verify(pk1, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + if res, _ := bls.Verify(pk2, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + // Should error out due to duplicate identifiers + _, err = bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[0], sigs2[1]) + if err == nil { + t.Errorf("CombineSignatures expected to fail but succeeded.") + } +} + +func TestIdentityPublicKey(t *testing.T) { + bls := NewSigBasic() + _, sk, err := bls.Keygen() + if err != nil { + t.Errorf("Keygen failed: %v", err) + } + msg := []byte{0, 0, 0, 0} + sig, _ := bls.Sign(sk, msg) + pk := PublicKey{value: *new(bls12381.G1).Identity()} + if res, _ := bls.Verify(&pk, msg, sig); res { + t.Errorf("Verify succeeded when the public key is the identity.") + } +} + +func TestThresholdSignTooHighAndLow(t *testing.T) { + bls := NewSigBasic() + _, sks, err := bls.ThresholdKeygen(3, 5) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + msg := make([]byte, 10) + + ps, err := bls.PartialSign(sks[0], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + + _, err = bls.CombineSignatures(ps) + if err == nil { + t.Errorf("CombinSignatures succeeded when it should've failed") + } + + pss := make([]*PartialSignature, 256) + + _, err = bls.CombineSignatures(pss...) + if err == nil { + t.Errorf("CombinSignatures succeeded when it should've failed") + } +} diff --git a/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_pop_test.go b/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_pop_test.go new file mode 100755 index 000000000..985d262c0 --- /dev/null +++ b/pkg/crypto/signatures/bls/bls_sig/usual_bls_sig_pop_test.go @@ -0,0 +1,867 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package bls_sig + +import ( + "bytes" + "math/big" + "math/rand" + "testing" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/bls12381" +) + +const numAggregateG2 = 10 + +func TestGetPublicKeyG1(t *testing.T) { + sk := genSecretKey(t) + pk := genPublicKey(sk, t) + actual := marshalStruct(pk, t) + expected := []byte{166, 149, 173, 50, 93, 252, 126, 17, 145, 251, 201, 241, 134, 245, 142, 255, 66, 166, 52, 2, 151, 49, 177, 131, 128, 255, 137, 191, 66, 196, 100, 164, 44, 184, 202, 85, 178, 0, 240, 81, 245, 127, 30, 24, 147, 198, 135, 89} + if !bytes.Equal(actual, expected) { + t.Errorf("Expected GetPublicKey to pass but failed.") + } +} + +func testSignG2(message []byte, t *testing.T) { + sk := genSecretKey(t) + sig := genSignature(sk, message, t) + pk := genPublicKey(sk, t) + + bls := NewSigPop() + + if res, err := bls.Verify(pk, message, sig); !res { + t.Errorf("createSignature failed when it should've passed: %v", err) + } +} + +func TestSignG2EmptyMessage(t *testing.T) { + bls := NewSigPop() + sk := genSecretKey(t) + sig, _ := bls.Sign(sk, nil) + pk := genPublicKey(sk, t) + + if res, _ := bls.Verify(pk, nil, sig); res { + t.Errorf("createSignature succeeded when it should've failed") + } + + message := []byte{} + sig = genSignature(sk, message, t) + + if res, err := bls.Verify(pk, message, sig); !res { + t.Errorf("create and verify failed on empty message: %v", err) + } +} + +func TestSignG2OneByteMessage(t *testing.T) { + message := []byte{1} + testSignG2(message, t) +} + +func TestSignG2LargeMessage(t *testing.T) { + message := make([]byte, 1048576) + testSignG2(message, t) +} + +func TestSignG2RandomMessage(t *testing.T) { + message := make([]byte, 65537) + readRand(message, t) + testSignG2(message, t) +} + +func TestSignG2BadMessage(t *testing.T) { + message := make([]byte, 1024) + sk := genSecretKey(t) + sig := genSignature(sk, message, t) + pk := genPublicKey(sk, t) + message = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0} + + bls := NewSigPop() + + if res, _ := bls.Verify(pk, message, sig); res { + t.Errorf("Expected signature to not verify") + } +} + +func TestBadConversionsG2(t *testing.T) { + sk := genSecretKey(t) + message := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0} + sig := genSignature(sk, message, t) + pk := genPublicKey(sk, t) + + bls := NewSigPop() + + if res, _ := bls.Verify(pk, message, sig); !res { + t.Errorf("Signature should be valid") + } + if res, _ := sig.verify(pk, message, blsSignaturePopDst); !res { + t.Errorf("Signature should be valid") + } + + // Convert public key to signature in G2 + sig2 := new(SignatureVt) + err := sig2.UnmarshalBinary(marshalStruct(pk, t)) + if err != nil { + t.Errorf("Should be able to convert to signature in G2") + } + pk2 := new(PublicKeyVt) + err = pk2.UnmarshalBinary(marshalStruct(sig, t)) + if err != nil { + t.Errorf("Should be able to convert to public key in G1") + } + + if res, _ := pk2.verifySignatureVt(message, sig2, blsSignaturePopDst); res { + t.Errorf("The signature shouldn't verify") + } +} + +func TestAggregatePublicKeysG1(t *testing.T) { + pks := []*PublicKey{} + ikm := make([]byte, 32) + for i := 0; i < 20; i++ { + readRand(ikm, t) + sk := genRandSecretKey(ikm, t) + pk := genPublicKey(sk, t) + pks = append(pks, pk) + } + apk1, err := aggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + rand.Seed(1234567890) + rand.Shuffle(len(pks), func(i, j int) { pks[i], pks[j] = pks[j], pks[i] }) + apk2, err := aggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(marshalStruct(apk1, t), marshalStruct(apk2, t)) { + t.Errorf("Aggregated public keys should be equal") + } + rand.Shuffle(len(pks), func(i, j int) { pks[i], pks[j] = pks[j], pks[i] }) + apk1, err = aggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(marshalStruct(apk1, t), marshalStruct(apk2, t)) { + t.Errorf("Aggregated public keys should be equal") + } +} + +func TestAggregateSignaturesG2(t *testing.T) { + var sigs []*Signature + ikm := make([]byte, 32) + for i := 0; i < 20; i++ { + readRand(ikm, t) + sk := genRandSecretKey(ikm, t) + sig := genSignature(sk, ikm, t) + sigs = append(sigs, sig) + } + asig1, err := aggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + rand.Seed(1234567890) + rand.Shuffle(len(sigs), func(i, j int) { sigs[i], sigs[j] = sigs[j], sigs[i] }) + asig2, err := aggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(marshalStruct(asig1, t), marshalStruct(asig2, t)) { + t.Errorf("Aggregated signatures should be equal") + } + rand.Shuffle(len(sigs), func(i, j int) { sigs[i], sigs[j] = sigs[j], sigs[i] }) + asig1, err = aggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(marshalStruct(asig1, t), marshalStruct(asig2, t)) { + t.Errorf("Aggregated signatures should be equal") + } +} + +func initAggregatedTestValuesG2(messages [][]byte, t *testing.T) ([]*PublicKey, []*Signature) { + pks := []*PublicKey{} + sigs := []*Signature{} + ikm := make([]byte, 32) + for i := 0; i < numAggregateG2; i++ { + readRand(ikm, t) + sk := genRandSecretKey(ikm, t) + sig := genSignature(sk, messages[i%len(messages)], t) + sigs = append(sigs, sig) + pk := genPublicKey(sk, t) + pks = append(pks, pk) + } + return pks, sigs +} + +func TestAggregatedFunctionalityG2(t *testing.T) { + message := make([]byte, 20) + messages := make([][]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG2(messages, t) + + bls := NewSigPop() + asig, err := bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + apk, err := bls.AggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + if res, _ := bls.VerifyMultiSignature(apk, message, asig); !res { + t.Errorf("Should verify aggregated signatures with same message") + } + if res, _ := asig.verify(apk, message, blsSignaturePopDst); !res { + t.Errorf("MultiSignature.verify failed.") + } + if res, _ := apk.verify(message, asig, blsSignaturePopDst); !res { + t.Errorf("MultiPublicKey.verify failed.") + } +} + +func TestBadAggregatedFunctionalityG2(t *testing.T) { + message := make([]byte, 20) + messages := make([][]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG2(messages, t) + + bls := NewSigPop() + + apk, err := bls.AggregatePublicKeys(pks[2:]...) + if err != nil { + t.Errorf("%v", err) + } + asig, err := bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + + if res, _ := bls.VerifyMultiSignature(apk, message, asig); res { + t.Errorf("Should not verify aggregated signatures with same message when some public keys are missing") + } + + apk, err = bls.AggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + asig, err = bls.AggregateSignatures(sigs[2:]...) + if err != nil { + t.Errorf("%v", err) + } + if res, _ := bls.VerifyMultiSignature(apk, message, asig); res { + t.Errorf("Should not verify aggregated signatures with same message when some signatures are missing") + } + + asig, err = bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + + badmsg := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} + if res, _ := bls.VerifyMultiSignature(apk, badmsg, asig); res { + t.Errorf("Should not verify aggregated signature with bad message") + } +} + +func TestAggregateVerifyG2Pass(t *testing.T) { + messages := make([][]byte, numAggregateG2) + for i := 0; i < numAggregateG2; i++ { + message := make([]byte, 20) + readRand(message, t) + messages[i] = message + } + pks, sigs := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + if res, _ := bls.AggregateVerify(pks, messages, sigs); !res { + t.Errorf("Expected aggregateVerify to pass but failed") + } +} + +func TestAggregateVerifyG2MsgSigCntMismatch(t *testing.T) { + messages := make([][]byte, 8) + for i := 0; i < 8; i++ { + message := make([]byte, 20) + readRand(message, t) + messages[i] = message + } + + pks, sigs := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + if res, _ := bls.AggregateVerify(pks, messages, sigs); res { + t.Errorf("Expected AggregateVerifyG2 to fail with duplicate message but passed") + } +} + +func TestAggregateVerifyG2FailDupMsg(t *testing.T) { + messages := make([][]byte, 10) + for i := 0; i < 9; i++ { + message := make([]byte, 20) + readRand(message, t) + messages[i] = message + } + // Duplicate message + messages[9] = messages[0] + pks, sigs := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + if res, _ := bls.AggregateVerify(pks, messages, sigs); res { + t.Errorf("Expected aggregateVerify to fail with duplicate message but passed") + } +} + +func TestAggregateVerifyG2FailIncorrectMsg(t *testing.T) { + messages := make([][]byte, 10) + for i := 0; i < 9; i++ { + message := make([]byte, 20) + readRand(message, t) + messages[i] = message + } + // Duplicate message + messages[9] = messages[0] + pks, sigs := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + if res, _ := bls.AggregateVerify(pks[2:], messages[2:], sigs); res { + t.Errorf("Expected aggregateVerify to fail with duplicate message but passed") + } +} + +func TestAggregateVerifyG2OneMsg(t *testing.T) { + messages := make([][]byte, 1) + messages[0] = make([]byte, 20) + sk := genSecretKey(t) + sig := genSignature(sk, messages[0], t) + pk := genPublicKey(sk, t) + bls := NewSigPop() + // Should be the same as verifySignature + if res, _ := bls.AggregateVerify([]*PublicKey{pk}, messages, []*Signature{sig}); !res { + t.Errorf("Expected AggregateVerifyG2OneMsg to pass but failed") + } +} + +func TestVerifyG2Mutability(t *testing.T) { + // verify should not change any inputs + ikm := make([]byte, 32) + ikm_copy := make([]byte, 32) + readRand(ikm, t) + copy(ikm_copy, ikm) + bls := NewSigPop() + pk, sk, err := bls.KeygenWithSeed(ikm) + + if !bytes.Equal(ikm, ikm_copy) { + t.Errorf("SigPop.KeygenWithSeed modifies ikm") + } + if err != nil { + t.Errorf("Expected KeygenWithSeed to succeed but failed.") + } + sig, err := bls.Sign(sk, ikm) + if !bytes.Equal(ikm, ikm_copy) { + t.Errorf("SigPop.Sign modifies message") + } + if err != nil { + t.Errorf("SigPop.KeygenWithSeed to succeed but failed.") + } + sigCopy := marshalStruct(sig, t) + if res, _ := bls.Verify(pk, ikm, sig); !res { + t.Errorf("Expected verify to succeed but failed.") + } + if !bytes.Equal(ikm, ikm_copy) { + t.Errorf("SigPop.verify modifies message") + } + if !bytes.Equal(sigCopy, marshalStruct(sig, t)) { + t.Errorf("SigPop.verify modifies signature") + } +} + +func TestPublicKeyG1FromBadBytes(t *testing.T) { + pk := make([]byte, 32) + err := new(PublicKey).UnmarshalBinary(pk) + if err == nil { + t.Errorf("Expected PublicKeyG1FromBytes to fail but passed") + } + // All zeros + pk = make([]byte, PublicKeySize) + // See https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization + // 1 << 7 == compressed + // 1 << 6 == infinity or zero + pk[0] = 0xc0 + err = new(PublicKey).UnmarshalBinary(pk) + if err == nil { + t.Errorf("Expected PublicKeyG1FromBytes to fail but passed") + } + sk := genSecretKey(t) + pk1, err := sk.GetPublicKey() + if err != nil { + t.Errorf("Expected GetPublicKey to pass but failed.") + } + out := marshalStruct(pk1, t) + out[3] += 1 + err = new(PublicKey).UnmarshalBinary(pk) + if err == nil { + t.Errorf("Expected PublicKeyG1FromBytes to fail but passed") + } +} + +func TestSignatureG2FromBadBytes(t *testing.T) { + sig := make([]byte, 32) + err := new(Signature).UnmarshalBinary(sig) + if err == nil { + t.Errorf("Expected SignatureG2FromBytes to fail but passed") + } + // All zeros + sig = make([]byte, SignatureSize) + // See https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization + // 1 << 7 == compressed + // 1 << 6 == infinity or zero + sig[0] = 0xc0 + err = new(Signature).UnmarshalBinary(sig) + if err == nil { + t.Errorf("Expected SignatureG2FromBytes to fail but passed") + } +} + +func TestBadSecretKeyG2(t *testing.T) { + sk := &SecretKey{value: bls12381.Bls12381FqNew()} + pk, err := sk.GetPublicKey() + if err == nil { + t.Errorf("Expected GetPublicKey to fail with 0 byte secret key but passed: %v", pk) + } + _ = sk.UnmarshalBinary(sk.value.Params.BiModulus.Bytes()) + pk, err = sk.GetPublicKey() + if err == nil { + t.Errorf("Expected GetPublicKey to fail with secret key with Q but passed: %v", pk) + } + + err = sk.UnmarshalBinary([]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) + if err == nil { + t.Errorf("Expected SecretKeyFromBytes to fail with not enough bytes but passed: %v", pk) + } + + err = sk.UnmarshalBinary(make([]byte, 32)) + if err == nil { + t.Errorf("Expected SecretKeyFromBytes to fail with all zeros but passed: %v", pk) + } +} + +func TestProofOfPossessionG2Works(t *testing.T) { + ikm := make([]byte, 32) + readRand(ikm, t) + bls := NewSigPop() + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Key gen failed but should've succeeded") + } + pop, err := bls.PopProve(sk) + if err != nil { + t.Errorf("PopProve failed but should've succeeded") + } + if res, _ := bls.PopVerify(pk, pop); !res { + t.Errorf("PopVerify failed but should've succeeded") + } +} + +func TestProofOfPossessionG2FromBadKey(t *testing.T) { + ikm := make([]byte, 32) + value := new(big.Int) + value.SetBytes(ikm) + sk := SecretKey{value: bls12381.Bls12381FqNew().SetBigInt(value)} + _, err := sk.createProofOfPossession(blsSignaturePopDst) + if err == nil { + t.Errorf("createProofOfPossession should've failed but succeeded.") + } +} + +func TestProofOfPossessionG2BytesWorks(t *testing.T) { + sk := genSecretKey(t) + pop, err := sk.createProofOfPossession(blsSignaturePopDst) + if err != nil { + t.Errorf("CreateProofOfPossesionG2 failed but shouldn've succeeded.") + } + out := marshalStruct(pop, t) + if len(out) != ProofOfPossessionSize { + t.Errorf("ProofOfPossessionBytes incorrect size: expected %v, got %v", ProofOfPossessionSize, len(out)) + } + pop2 := new(ProofOfPossession) + err = pop2.UnmarshalBinary(out) + if err != nil { + t.Errorf("ProofOfPossession.UnmarshalBinary failed: %v", err) + } + out2 := marshalStruct(pop2, t) + if !bytes.Equal(out, out2) { + t.Errorf("ProofOfPossession.UnmarshalBinary failed, not equal when deserialized") + } +} + +func TestProofOfPossessionG2BadBytes(t *testing.T) { + zeros := make([]byte, ProofOfPossessionSize) + temp := new(ProofOfPossession) + err := temp.UnmarshalBinary(zeros) + if err == nil { + t.Errorf("ProofOfPossession.UnmarshalBinary shouldn've failed but succeeded.") + } +} + +func TestProofOfPossessionG2Fails(t *testing.T) { + sk := genSecretKey(t) + pop, err := sk.createProofOfPossession(blsSignaturePopDst) + if err != nil { + t.Errorf("Expected createProofOfPossession to succeed but failed.") + } + + ikm := make([]byte, 32) + readRand(ikm, t) + sk = genRandSecretKey(ikm, t) + bad, err := sk.GetPublicKey() + if err != nil { + t.Errorf("Expected PublicKeyG1FromBytes to succeed but failed: %v", err) + } + if res, _ := pop.verify(bad, blsSignaturePopDst); res { + t.Errorf("Expected ProofOfPossession verify to fail but succeeded.") + } +} + +func TestMultiSigG2Bytes(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 20) + messages[0] = message + _, sigs := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + msig, err := bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + msigBytes := marshalStruct(msig, t) + if len(msigBytes) != SignatureSize { + t.Errorf("Invalid multi-sig length. Expected %d bytes, found %d", SignatureSize, len(msigBytes)) + } + msig2 := new(MultiSignature) + err = msig2.UnmarshalBinary(msigBytes) + if err != nil { + t.Errorf("MultiSignatureG2FromBytes failed with %v", err) + } + msigBytes2 := marshalStruct(msig2, t) + + if !bytes.Equal(msigBytes, msigBytes2) { + t.Errorf("Bytes methods not equal.") + } +} + +func TestMultiSigG2BadBytes(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 20) + messages[0] = message + _, sigs := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + msig, err := bls.AggregateSignatures(sigs...) + if err != nil { + t.Errorf("%v", err) + } + msigBytes := marshalStruct(msig, t) + if len(msigBytes) != SignatureSize { + t.Errorf("Invalid multi-sig length. Expected %d bytes, found %d", SignatureSize, len(msigBytes)) + } + msigBytes[0] = 0 + temp := new(MultiSignature) + err = temp.UnmarshalBinary(msigBytes) + if err == nil { + t.Errorf("MultiSignatureG2FromBytes should've failed but succeeded") + } + msigBytes = make([]byte, SignatureSize) + err = temp.UnmarshalBinary(msigBytes) + if err == nil { + t.Errorf("MultiSignatureG2FromBytes should've failed but succeeded") + } +} + +func TestMultiPubkeyG1Bytes(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 20) + messages[0] = message + pks, _ := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + apk, err := bls.AggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + apkBytes := marshalStruct(apk, t) + if len(apkBytes) != PublicKeySize { + t.Errorf("MultiPublicKey has an incorrect size") + } + apk2 := new(MultiPublicKey) + err = apk2.UnmarshalBinary(apkBytes) + if err != nil { + t.Errorf("MultiPublicKey.UnmarshalBinary failed with %v", err) + } + apk2Bytes := marshalStruct(apk2, t) + if !bytes.Equal(apkBytes, apk2Bytes) { + t.Errorf("Bytes methods not equal.") + } +} + +func TestMultiPubkeyG1BadBytes(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 20) + messages[0] = message + pks, _ := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + apk, err := bls.AggregatePublicKeys(pks...) + if err != nil { + t.Errorf("%v", err) + } + apkBytes := marshalStruct(apk, t) + if len(apkBytes) != PublicKeySize { + t.Errorf("MultiPublicKey has an incorrect size") + } + apkBytes[0] = 0 + temp := new(MultiPublicKey) + err = temp.UnmarshalBinary(apkBytes) + if err == nil { + t.Errorf("MultiPublicKey.UnmarshalBinary should've failed but succeeded") + } + apkBytes = make([]byte, PublicKeySize) + err = temp.UnmarshalBinary(apkBytes) + if err == nil { + t.Errorf("MultiPublicKey.UnmarshalBinary should've failed but succeeded") + } +} + +func TestFastAggregateVerifyG2Works(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG2(messages, t) + asigs, _ := aggregateSignatures(sigs...) + bls := NewSigPop() + if res, _ := bls.FastAggregateVerify(pks, message, asigs); !res { + t.Errorf("FastAggregateVerify failed.") + } +} + +func TestFastAggregateVerifyConstituentG2Works(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + if res, _ := bls.FastAggregateVerifyConstituent(pks, message, sigs); !res { + t.Errorf("FastAggregateVerify failed.") + } +} + +func TestFastAggregateVerifyG2Fails(t *testing.T) { + messages := make([][]byte, 1) + message := make([]byte, 1) + messages[0] = message + pks, sigs := initAggregatedTestValuesG2(messages, t) + bls := NewSigPop() + message[0] = 1 + if res, _ := bls.FastAggregateVerifyConstituent(pks, message, sigs); res { + t.Errorf("FastAggregateVerify verified when it should've failed.") + } +} + +func TestCustomPopDstG2Works(t *testing.T) { + bls, _ := NewSigPopWithDst("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_TEST", + "BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_TEST") + msg := make([]byte, 20) + ikm := make([]byte, 32) + pk, sk, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Couldn't create custom dst keys: %v", err) + } + sig, err := bls.Sign(sk, msg) + if err != nil { + t.Errorf("Couldn't sign with custom dst: %v", err) + } + if res, _ := bls.Verify(pk, msg, sig); !res { + t.Errorf("verify fails with custom dst") + } + + pks := make([]*PublicKey, 10) + sigs := make([]*Signature, 10) + pks[0] = pk + sigs[0] = sig + for i := 1; i < 10; i++ { + readRand(ikm, t) + pkt, skt, err := bls.KeygenWithSeed(ikm) + if err != nil { + t.Errorf("Couldn't create custom dst keys: %v", err) + } + sigt, err := bls.Sign(skt, msg) + if err != nil { + t.Errorf("Couldn't sign with custom dst: %v", err) + } + pks[i] = pkt + sigs[i] = sigt + } + + if res, _ := bls.FastAggregateVerifyConstituent(pks, msg, sigs); !res { + t.Errorf("FastAggregateVerify failed with custom dst") + } + + pop, err := bls.PopProve(sk) + if err != nil { + t.Errorf("PopProve failed with custom dst") + } + + if res, _ := bls.PopVerify(pk, pop); !res { + t.Errorf("PopVerify failed with custom dst") + } +} + +func TestBlsPopG2KeyGenWithSeed(t *testing.T) { + ikm := []byte("Not enough bytes") + bls := NewSigPop() + _, _, err := bls.KeygenWithSeed(ikm) + if err == nil { + t.Errorf("Expected KeygenWithSeed to fail but succeeded") + } +} + +func TestBlsPopG2KeyGen(t *testing.T) { + bls := NewSigPop() + _, _, err := bls.Keygen() + if err != nil { + t.Errorf("Keygen failed: %v", err) + } +} + +func TestPopThresholdKeygenBadInputs(t *testing.T) { + bls := NewSigPop() + _, _, err := bls.ThresholdKeygen(0, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(1, 0) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } + _, _, err = bls.ThresholdKeygen(3, 2) + if err == nil { + t.Errorf("ThresholdKeygen should've failed but succeeded") + } +} + +func TestPopThresholdKeygen(t *testing.T) { + bls := NewSigPop() + _, sks, err := bls.ThresholdKeygen(3, 5) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + if len(sks) != 5 { + t.Errorf("ThresholdKeygen did not produce enough shares") + } +} + +func TestPopPartialSign(t *testing.T) { + ikm := make([]byte, 32) + bls := NewSigPop() + pk, sks, err := bls.ThresholdKeygenWithSeed(ikm, 2, 4) + if err != nil { + t.Errorf("ThresholdKeygen failed") + } + msg := make([]byte, 10) + sig1, err := bls.PartialSign(sks[0], msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig2, err := bls.PartialSign(sks[1], msg) + if err != nil { + t.Errorf("partialSign failed: %v", err) + } + sig, err := bls.CombineSignatures(sig1, sig2) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + + if res, _ := bls.Verify(pk, msg, sig); !res { + t.Errorf("Combined signature does not verify") + } + + sig, err = bls.CombineSignatures(sig1) + if err == nil { + t.Errorf("CombineSignatures succeeded when it should've failed") + } + if res, _ := bls.Verify(pk, msg, sig); res { + t.Errorf("Combined signature verify succeeded when it should've failed") + } +} + +// Ensure that mixed partial signatures from distinct origins create invalid composite signatures +func TestPopPartialMixupShares(t *testing.T) { + total := uint(5) + ikm := make([]byte, 32) + bls := NewSigPop() + pk1, sks1, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + for i := range ikm { + ikm[i] = 1 + } + pk2, sks2, err := bls.ThresholdKeygenWithSeed(ikm, 3, total) + if err != nil { + t.Errorf("ThresholdKeygen failed: %v", err) + } + + // Generate partial signatures for both sets of keys + msg := make([]byte, 10) + sigs1 := make([]*PartialSignature, total) + sigs2 := make([]*PartialSignature, total) + for i := range sks1 { + sigs1[i], err = bls.PartialSign(sks1[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + sigs2[i], err = bls.PartialSign(sks2[i], msg) + if err != nil { + t.Errorf("PartialSign failed: %v", err) + } + } + + // Try combining 2 from group 1 and 2 from group 2 + sig, err := bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[2], sigs2[3]) + if err != nil { + t.Errorf("CombineSignatures failed: %v", err) + } + // Signature shouldn't validate + if res, _ := bls.Verify(pk1, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + if res, _ := bls.Verify(pk2, msg, sig); res { + t.Errorf("CombineSignatures worked with different shares of two secret keys for the same message") + } + // Should error out due to duplicate identifiers + _, err = bls.CombineSignatures(sigs1[0], sigs1[1], sigs2[0], sigs2[1]) + if err == nil { + t.Errorf("CombineSignatures expected to fail but succeeded.") + } +} + +func TestNewSigEth2KeyGen(t *testing.T) { + eth2 := NewSigEth2() + _, _, err := eth2.Keygen() + if err != nil { + t.Errorf("Keygen failed: %v", err) + } +} + +func TestSigEth2SignRoundTrip(t *testing.T) { + eth2 := NewSigEth2() + pop := NewSigPop() + eth2Pk, eth2Sk, err := eth2.Keygen() + if err != nil { + t.Errorf("Keygen failed: %v", err) + } + + sig, err := pop.Sign(eth2Sk, []byte{0, 0}) + if err != nil { + t.Errorf("Sign failed: %v", err) + } + if ok, err := eth2.Verify(eth2Pk, []byte{0, 0}, sig); err != nil || !ok { + t.Errorf("Verify failed: %v", err) + } +} diff --git a/pkg/crypto/signatures/bls/rust/Cargo.toml b/pkg/crypto/signatures/bls/rust/Cargo.toml new file mode 100755 index 000000000..9b17a1f2e --- /dev/null +++ b/pkg/crypto/signatures/bls/rust/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "miracl" +version = "0.1.0" +authors = ["Mike Lodder "] +edition = "2018" + +[dependencies] +bls_sigs_ref = "0.3" +hex = "0.4" +miracl_core = { version = "2.3", features = [ + "bls12381", +], default-features = false } +pairing-plus = "0.19" +rand = "0.8" +serious = { version = "0.1", git = "https://github.com/mikelodder7/malutils" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +sha2 = "0.8" +structopt = "0.3" diff --git a/pkg/crypto/signatures/bls/rust/README.md b/pkg/crypto/signatures/bls/rust/README.md new file mode 100755 index 000000000..e0f8e8d17 --- /dev/null +++ b/pkg/crypto/signatures/bls/rust/README.md @@ -0,0 +1,13 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## Note + +This rust package is added for the sole purpose of comparing the result of our Go package with other +implementations, including the rust package. diff --git a/pkg/crypto/signatures/bls/rust/src/main.rs b/pkg/crypto/signatures/bls/rust/src/main.rs new file mode 100755 index 000000000..43aebd966 --- /dev/null +++ b/pkg/crypto/signatures/bls/rust/src/main.rs @@ -0,0 +1,388 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +use bls_sigs_ref::BLSSignaturePop; +use miracl_core::bls12381::{big::BIG, ecp::ECP, ecp2::ECP2, rom::MODULUS}; +use pairing_plus::{ + bls12_381::{Fr, G1, G2}, + hash_to_field::BaseFromRO, + serdes::SerDes, + CurveProjective, +}; +use rand::prelude::*; +use serde::Deserialize; +use serious::Encoding; +use sha2::digest::generic_array::GenericArray; +use std::{ + fs::File, + io::{self, Cursor, Read}, + path::PathBuf, +}; +use structopt::StructOpt; + +fn main() { + let args = CliArgs::from_args(); + + match args { + CliArgs::Generate { number } => generate(number), + CliArgs::PublicKey { keys } => pubkey(keys), + CliArgs::Sign { number, data } => sign(number, data), + CliArgs::Verify { keys } => verify(keys), + } +} + +fn generate(number: usize) { + let mut rng = thread_rng(); + print!("["); + let mut sep = ""; + for _ in 0..number { + let mut buf = [0u8; 48]; + rng.fill_bytes(&mut buf); + // let mut sk = buf; + let fr = Fr::from_okm(GenericArray::from_slice(&buf)); + let mut pk = G1::one(); + pk.mul_assign(fr); + + pk.serialize(&mut buf.as_mut(), true).unwrap(); + print!("{}\"{}\"", sep, hex::encode(buf)); + sep = ","; + + // Miracl expects 48 bytes for secret key even though the top 16 bytes are zeros + // sk = [0u8; 48]; + // fr.serialize(&mut sk[16..].as_mut(), true).unwrap(); + // let s = BIG::frombytes(&sk[..]); + // let x = _compress_g1(g1mul(&ECP::generator(), &s)); + // + // println!("Miracl = {}", hex::encode(x)); + } + print!("]"); +} + +/// Compress to BLS12-381 standard vs ANSI X9.62 +fn _compress_g1(pk: ECP) -> [u8; 48] { + let mut x = [0u8; 48]; + pk.getx().tobytes(&mut x); + if pk.is_infinity() { + // Set the second-most significant bit to indicate this point + // is at infinity. + x[0] |= 1 << 6; + } else { + let m = BIG { w: MODULUS }; + let mut negy = BIG::new(); + negy.add(&BIG::modneg(&pk.gety(), &m)); + negy.rmod(&m); + negy.norm(); + // Set the third most significant bit if the correct y-coordinate + // is lexicographically largest. + if BIG::comp(&pk.gety(), &negy) == 1 { + x[0] |= 1 << 5; + } + } + // Set highest bit to distinguish this as a compressed element. + x[0] |= 1 << 7; + x +} + +fn _compress_g2(sig: ECP2) -> [u8; 96] { + let mut x = [0u8; 96]; + sig.getx().geta().tobytes(&mut x[..48]); + sig.getx().getb().tobytes(&mut x[48..]); + if sig.is_infinity() { + // Set the second-most significant bit to indicate this point + // is at infinity. + x[0] |= 1 << 6; + } else { + let mut negy = sig.clone(); + negy.neg(); + + // Set the third most significant bit if the correct y-coordinate + // is lexicographically largest. + negy.sub(&sig); + + if negy.gety().sign() > 0 { + x[0] |= 1 << 5; + } + } + // Set highest bit to distinguish this as a compressed element. + x[0] |= 1 << 7; + x +} + +fn pubkey(keys: String) { + let res = read_input(&keys).unwrap(); + + for pubkey in serde_json::from_slice::>(&res).unwrap() { + let res = hex::decode(&pubkey); + if res.is_err() { + println!("Invalid hex format {}", res.unwrap_err()); + continue; + } + let mut key = res.unwrap(); + let mut cur = Cursor::new(key.as_slice()); + print!("ZCash {} - ", pubkey); + let res = G1::deserialize(&mut cur, true); + + if let Err(e) = res { + println!("fail - {}", e); + } else { + println!("pass"); + } + + let res = _uncompress_g1(key.as_mut_slice()); + + print!("Miracl {} - ", pubkey); + if let Err(e) = res { + println!("fail - {}", e); + } else { + println!("pass"); + } + } +} + +fn _uncompress_g1(d: &[u8]) -> Result { + if d.len() != 48 { + return Err("Invalid length".to_string()); + } + + if d[0] & 0x80 != 0x80 { + return Err("Expected compressed point".to_string()); + } + + // Expect point at infinity + if d[0] & 0x40 == 0x40 { + return if !d.iter().skip(1).all(|b| *b == 0) { + Err("Expected point at infinity but found another point".to_string()) + } else { + Ok(ECP::new()) + }; + } + + let s = d[0] & 0x20; + // Unset top bits + let mut dd = [0u8; 48]; + dd.copy_from_slice(d); + dd[0] &= 0x1F; + let x = BIG::frombytes(&dd); + Ok(ECP::new_bigint(&x, s as isize)) +} + +fn _uncompress_g2(d: &[u8]) -> Result { + if d.len() != 96 { + return Err("Invalid length".to_string()); + } + + if d[0] & 0x80 != 0x80 { + return Err("Expected compressed point".to_string()); + } + + // Expect point at infinity + if d[0] & 0x40 == 0x40 { + return if !d.iter().skip(1).all(|b| *b == 0) { + Err("Expected point at infinity but found another point".to_string()) + } else { + Ok(ECP2::new()) + }; + } + + let s = d[0] & 0x20; + let mut dd = [0u8; 97]; + dd[1..].copy_from_slice(d); + dd[1] &= 0x1F; + // Unset top bits + dd[0] = if s > 0 { 0x3 } else { 0x2 }; + Ok(ECP2::frombytes(&dd)) +} + +fn sign(number: usize, data: String) { + let mut rng = thread_rng(); + let bytes = data.as_bytes(); + let mut sep = ""; + print!("["); + for _ in 0..number { + let mut buf = [0u8; 48]; + rng.fill_bytes(&mut buf); + let fr = Fr::from_okm(GenericArray::from_slice(&buf)); + let mut pk = G1::one(); + pk.mul_assign(fr); + + let mut pubkey = [0u8; 48]; + pk.serialize(&mut pubkey.as_mut(), true).unwrap(); + + let signature = G2::sign(fr, bytes); + let mut sig = [0u8; 96]; + signature.serialize(&mut sig.as_mut(), true).unwrap(); + + print!("{}{{", sep); + print!(r#""data":"{}","#, data); + print!( + r#""public_key":"{}","#, + Encoding::encode(pubkey, Encoding::LowHex).into_string() + ); + print!( + r#""signature":"{}""#, + Encoding::encode(sig, Encoding::LowHex).into_string() + ); + print!("}}"); + sep = ","; + } + print!("]"); +} + +fn verify(keys: String) { + let res = read_input(&keys).unwrap(); + + for req in serde_json::from_slice::>(&res).unwrap() { + let pubkey = Encoding::decode(&req.public_key, Encoding::LowHex).unwrap(); + let sig = Encoding::decode(&req.signature, Encoding::LowHex).unwrap(); + let mut cur = Cursor::new(pubkey.as_slice()); + let verkey = G1::deserialize(&mut cur, true).unwrap(); + cur = Cursor::new(sig.as_slice()); + let signature = G2::deserialize(&mut cur, true).unwrap(); + + print!("ZCash {} - ", req.public_key); + if G2::verify(verkey, signature, req.data.as_bytes()) { + println!("pass"); + } else { + println!("fail"); + } + } +} + +#[derive(Debug, StructOpt)] +enum CliArgs { + Generate { + #[structopt(short, long)] + number: usize, + }, + PublicKey { + #[structopt(name = "KEYS")] + keys: String, + }, + Sign { + #[structopt(short, long)] + number: usize, + #[structopt(short, long)] + data: String, + }, + Verify { + #[structopt(name = "KEYS")] + keys: String, + }, +} + +#[derive(Deserialize)] +struct VerifyRequest { + data: String, + public_key: String, + signature: String, +} + +fn read_input(value: &str) -> Result, String> { + if !value.is_empty() { + match get_file(value) { + Some(file) => match File::open(file.as_path()) { + Ok(mut f) => Ok(read_stream(&mut f)), + Err(_) => Err(format!("Unable to read file {}", file.to_str().unwrap())), + }, + None => Ok(value.as_bytes().to_vec()), + } + } else { + let mut f = io::stdin(); + Ok(read_stream(&mut f)) + } +} + +fn read_stream(f: &mut R) -> Vec { + let mut bytes = Vec::new(); + let mut buffer = [0u8; 4096]; + + let mut read = f.read(&mut buffer); + while read.is_ok() { + let n = read.unwrap(); + + if n == 0 { + break; + } + + bytes.extend_from_slice(&buffer[..n]); + + read = f.read(&mut buffer); + } + + bytes +} + +fn get_file(name: &str) -> Option { + if name.len() > 256 { + // too long to be a file + return None; + } + let mut file = PathBuf::new(); + file.push(name); + if file.as_path().is_file() { + let metadata = file + .as_path() + .symlink_metadata() + .expect("symlink_metadata call failed"); + if metadata.file_type().is_symlink() { + if let Ok(f) = file.as_path().read_link() { + file = f + } else { + return None; + } + } + Some(file) + } else { + None + } +} + +// fn from_encoding(src: &str) -> Result { +// Encoding::parse(src).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e)) +// } + +// fn hash_to_g2(d: &[u8]) -> ECP2 { +// const DST: &'static str = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; +// let y = >>::hash_to_curve(d.as_ref(), DST); +// let mut d = [0u8; 193]; +// d[0] = 0x4; +// y.serialize(&mut d[1..].as_mut(), false); +// ECP2::frombytes(&d) +// } + +// fn ceil(a: usize, b: usize) -> usize { +// (a-1)/b+1 +// } +// +// fn hash_to_field(hash: usize, hlen: usize, u: &mut [FP2], dst: &[u8], m: &[u8], ctr: usize) { +// let q = BIG { w: MODULUS }; +// let el = ceil(q.nbits()+AESKEY*16, 8); +// +// let mut okm = [0u8; 512]; +// let mut fd = [0u8; 256]; +// xmd_expand(hash, hlen, &mut okm, el*ctr, &dst, &m); +// u[0] = FP2::new_fps( +// &FP::new_big(&DBIG::frombytes(&okm[0..el]).dmod(&q)), +// &FP::new_big(&DBIG::frombytes(&okm[el..(2*el)]).dmod(&q)) +// ); +// u[1] = FP2::new_fps( +// &FP::new_big(&DBIG::frombytes(&okm[(2*el)..(3*el)]).dmod(&q)), +// &FP::new_big(&DBIG::frombytes(&okm[(3*el)..]).dmod(&q)) +// ); +// } +// +// fn hash_to_ecp2(m: &[u8]) -> ECP2 { +// let dst = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; +// let mut u = [FP2::new(); 2]; +// hash_to_field(hmac::MC_SHA2, ecp::HASH_TYPE, &mut u, &dst[..], m, 2); +// +// let mut p = ECP2::map2point(&u[0]); +// let q = ECP2::map2point(&u[1]); +// p.add(&q); +// p.cfp(); +// p.affine(); +// p +// } diff --git a/pkg/crypto/signatures/bls/tests/bls/main.go b/pkg/crypto/signatures/bls/tests/bls/main.go new file mode 100755 index 000000000..2388e931f --- /dev/null +++ b/pkg/crypto/signatures/bls/tests/bls/main.go @@ -0,0 +1,237 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package main + +import ( + "bufio" + "encoding/hex" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "os" + + bls "github.com/onsonr/sonr/pkg/crypto/signatures/bls/bls_sig" +) + +type signOp struct { + Data string `json:"data"` + PublicKey string `json:"public_key"` + Signature string `json:"signature"` +} + +type cmdFlags struct { + Generate bool + PublicKeys bool + Sign bool + Verify bool + Number int +} + +func parseCliArgs() cmdFlags { + var generate, publickeys, sign, verify bool + var number int + flag.BoolVar(&generate, "g", false, "Generate public keys") + flag.BoolVar(&publickeys, "p", false, "Verify public keys") + flag.BoolVar(&sign, "s", false, "Generate signatures") + flag.BoolVar(&verify, "v", false, "Verify signatures") + flag.IntVar(&number, "n", 25, "The number of items to generate") + flag.Parse() + return cmdFlags{ + generate, publickeys, sign, verify, number, + } +} + +func main() { + flags := parseCliArgs() + + if flags.Generate { + generate(flags.Number) + } else if flags.PublicKeys { + publicKeys() + } else if flags.Sign { + sign(flags.Number) + } else if flags.Verify { + verify() + } +} + +func generate(number int) { + scheme := bls.NewSigPop() + publicKeys := make([]string, number) + for i := 0; i < number; i++ { + publicKey, _, err := scheme.Keygen() + if err != nil { + fmt.Printf("Keygen error occurred: %v\n", err) + os.Exit(1) + } + b, _ := publicKey.MarshalBinary() + publicKeys[i] = hex.EncodeToString(b) + } + out, _ := json.Marshal(publicKeys) + fmt.Println(string(out)) +} + +func publicKeys() { + input, err := getInput() + if err != nil { + fmt.Printf("Unable to read input: %v", err) + os.Exit(1) + } + var pubkeys []string + err = json.Unmarshal(input, &pubkeys) + if err != nil { + fmt.Printf("Unable to parse json input: %v", err) + os.Exit(1) + } + fmt.Printf("Checking public keys") + for _, pk := range pubkeys { + data, err := hex.DecodeString(pk) + if err != nil { + fmt.Printf("Unable to parse hex input: %v", err) + os.Exit(1) + } + pubkey := new(bls.PublicKey) + fmt.Printf("Checking %s - ", pk) + err = pubkey.UnmarshalBinary(data) + if err != nil { + fmt.Printf("fail\n") + os.Exit(1) + } + fmt.Printf("pass\n") + } +} + +func sign(number int) { + tests := []string{ + "", "aaa", "aaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + } + + var err error + scheme := bls.NewSigPop() + secretKeys := make([]*bls.SecretKey, number) + publicKeys := make([]*bls.PublicKey, number) + for i := 0; i < number; i++ { + publicKeys[i], secretKeys[i], err = scheme.Keygen() + if err != nil { + fmt.Printf("Keygen error occurred: %v\n", err) + os.Exit(1) + } + } + + sigs := make([]*signOp, number*len(tests)) + + k := 0 + for _, t := range tests { + for j := 0; j < len(secretKeys); j++ { + signature, err := scheme.Sign(secretKeys[j], []byte(t)) + if err != nil { + fmt.Printf("Signing failed: %v\n", err) + os.Exit(1) + } + pk, _ := publicKeys[j].MarshalBinary() + sig, _ := signature.MarshalBinary() + sigs[k] = &signOp{ + Data: t, + PublicKey: hex.EncodeToString(pk), + Signature: hex.EncodeToString(sig), + } + k++ + } + } + + data, err := json.Marshal(sigs) + if err != nil { + fmt.Printf("Unable to convert signatures to json") + os.Exit(1) + } + fmt.Print(string(data)) +} + +func verify() { + input, err := getInput() + if err != nil { + fmt.Printf("Unable to read input: %v", err) + os.Exit(1) + } + var operations []signOp + err = json.Unmarshal(input, &operations) + if err != nil { + fmt.Printf("Unable to parse json input: %v", err) + os.Exit(1) + } + scheme := bls.NewSigPop() + for _, op := range operations { + fmt.Printf("Checking %s - ", op.PublicKey) + data, err := hex.DecodeString(op.PublicKey) + if err != nil { + fmt.Printf("fail. Unable to parse hex input: %v", err) + os.Exit(1) + } + pubkey := new(bls.PublicKey) + err = pubkey.UnmarshalBinary(data) + if err != nil { + fmt.Printf("fail. Invalid public key: %v", err) + os.Exit(1) + } + data, err = hex.DecodeString(op.Signature) + if err != nil { + fmt.Printf("fail. Unable to parse hex input: %v", err) + os.Exit(1) + } + sig := new(bls.Signature) + err = sig.UnmarshalBinary(data) + if err != nil { + fmt.Printf("fail. Invalid signature format: %v", err) + os.Exit(1) + } + ok, err := scheme.Verify(pubkey, []byte(op.Data), sig) + if !ok || err != nil { + fmt.Printf("fail. Invalid signature") + os.Exit(1) + } + fmt.Printf("pass.") + } +} + +func getInput() ([]byte, error) { + fi, _ := os.Stdin.Stat() + + var data []byte + + if (fi.Mode() & os.ModeCharDevice) == 0 { + // Read from pipe + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + data = append(data, scanner.Bytes()...) + } + + if err := scanner.Err(); err != nil { + return nil, err + } + } else { + // Read from file + arguments := flag.Args() + if len(arguments) < 1 { + return nil, fmt.Errorf("expected data argument") + } + + _, err := os.Stat(arguments[0]) + + if os.IsNotExist(err) { + data = []byte(arguments[0]) + } else { + contents, err := ioutil.ReadFile(arguments[0]) + if err != nil { + return nil, err + } + data = contents + } + } + + return data, nil +} diff --git a/pkg/crypto/signatures/bls/tmp.json b/pkg/crypto/signatures/bls/tmp.json new file mode 100755 index 000000000..6a6e84d49 --- /dev/null +++ b/pkg/crypto/signatures/bls/tmp.json @@ -0,0 +1,3 @@ +[ + "8f69b452faa4f2a451237988c70d844ea1311c991c55311ccad0b37863c668774c5ecf4b6d5dbca8578f24048a34b717" +] diff --git a/pkg/crypto/signatures/common/challenge.go b/pkg/crypto/signatures/common/challenge.go new file mode 100755 index 000000000..3d14285cc --- /dev/null +++ b/pkg/crypto/signatures/common/challenge.go @@ -0,0 +1,14 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package common + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// Challenge generated by fiat-shamir heuristic +type Challenge = curves.Scalar diff --git a/pkg/crypto/signatures/common/commitment.go b/pkg/crypto/signatures/common/commitment.go new file mode 100755 index 000000000..77905ff1a --- /dev/null +++ b/pkg/crypto/signatures/common/commitment.go @@ -0,0 +1,15 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package common + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// Commitment represents a point Pedersen commitment of one or more +// points multiplied by scalars +type Commitment = curves.Point diff --git a/pkg/crypto/signatures/common/hmacdrbg.go b/pkg/crypto/signatures/common/hmacdrbg.go new file mode 100755 index 000000000..025e3dfe8 --- /dev/null +++ b/pkg/crypto/signatures/common/hmacdrbg.go @@ -0,0 +1,99 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package common + +import ( + "crypto/hmac" + "hash" +) + +// HmacDrbg is an HMAC deterministic random bit generator +// that can use any hash function. Handles reseeding +// automatically +type HmacDrbg struct { + k, v []byte + count int + hasher func() hash.Hash +} + +func NewHmacDrbg(entropy, nonce, pers []byte, hasher func() hash.Hash) *HmacDrbg { + drbg := new(HmacDrbg) + h := hasher() + drbg.k = make([]byte, h.Size()) + drbg.v = make([]byte, h.Size()) + drbg.count = 0 + drbg.hasher = hasher + + for i := range drbg.v { + drbg.v[i] = 1 + } + + drbg.update([][]byte{entropy, nonce, pers}) + drbg.count += 1 + return drbg +} + +func (drbg *HmacDrbg) Read(dst []byte) (n int, err error) { + toRead := len(dst) + if toRead == 0 { + return 0, nil + } + i := 0 + for i < toRead { + vmac := drbg.getHmac() + _, _ = vmac.Write(drbg.v) + drbg.v = vmac.Sum(nil) + + for j, b := range drbg.v { + dst[i+j] = b + } + i += len(drbg.v) + } + drbg.update(nil) + drbg.count++ + return i, nil +} + +func (drbg *HmacDrbg) Reseed(entropy []byte) { + drbg.update([][]byte{entropy}) +} + +func (drbg *HmacDrbg) getHmac() hash.Hash { + return hmac.New(drbg.hasher, drbg.k) +} + +func (drbg *HmacDrbg) update(seeds [][]byte) { + kmac := drbg.getHmac() + _, _ = kmac.Write(drbg.v) + _, _ = kmac.Write([]byte{0}) + if len(seeds) > 0 { + for _, seed := range seeds { + _, _ = kmac.Write(seed) + } + } + drbg.k = kmac.Sum(nil) + + vmac := drbg.getHmac() + _, _ = vmac.Write(drbg.v) + drbg.v = vmac.Sum(nil) + + if len(seeds) == 0 { + return + } + + kmac = drbg.getHmac() + _, _ = kmac.Write(drbg.v) + _, _ = kmac.Write([]byte{1}) + for _, seed := range seeds { + _, _ = kmac.Write(seed) + } + drbg.k = kmac.Sum(nil) + + vmac = drbg.getHmac() + _, _ = vmac.Write(drbg.v) + drbg.v = vmac.Sum(nil) +} diff --git a/pkg/crypto/signatures/common/nonce.go b/pkg/crypto/signatures/common/nonce.go new file mode 100755 index 000000000..48ccb53de --- /dev/null +++ b/pkg/crypto/signatures/common/nonce.go @@ -0,0 +1,15 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package common + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// Nonce is used for zero-knowledge proofs to prevent replay attacks +// and prove freshness +type Nonce = curves.Scalar diff --git a/pkg/crypto/signatures/common/proof_committed_builder.go b/pkg/crypto/signatures/common/proof_committed_builder.go new file mode 100755 index 000000000..538fb6dfb --- /dev/null +++ b/pkg/crypto/signatures/common/proof_committed_builder.go @@ -0,0 +1,86 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package common + +import ( + "fmt" + "io" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +const limit = 65535 + +// ProofCommittedBuilder is used to create +// proofs from multiple commitments where +// each secret is committed with a random blinding factor +// and turned into a Schnorr proof +type ProofCommittedBuilder struct { + points []curves.Point + scalars []curves.Scalar + curve *curves.Curve +} + +// NewProofCommittedBuilder creates a new builder using the specified curve +func NewProofCommittedBuilder(curve *curves.Curve) *ProofCommittedBuilder { + return &ProofCommittedBuilder{ + points: []curves.Point{}, + scalars: []curves.Scalar{}, + curve: curve, + } +} + +// CommitRandom uses the specified point and commits a random value to it +func (pcb *ProofCommittedBuilder) CommitRandom(point curves.Point, reader io.Reader) error { + if len(pcb.points) > limit { + return fmt.Errorf("limit for commitments reached") + } + pcb.points = append(pcb.points, point) + pcb.scalars = append(pcb.scalars, pcb.curve.Scalar.Random(reader)) + return nil +} + +// Commit uses the specified point and scalar to create a commitment +func (pcb *ProofCommittedBuilder) Commit(point curves.Point, scalar curves.Scalar) error { + if len(pcb.points) > limit { + return fmt.Errorf("limit for commitments reached") + } + pcb.points = append(pcb.points, point) + pcb.scalars = append(pcb.scalars, scalar) + return nil +} + +// Get returns the point and scalar at the specified index +func (pcb *ProofCommittedBuilder) Get(index int) (curves.Point, curves.Scalar) { + if index >= len(pcb.points) || index < 0 { + return nil, nil + } + return pcb.points[index], pcb.scalars[index] +} + +// GetChallengeContribution returns the bytes that should be added to +// a sigma protocol transcript for generating the challenge +func (pcb ProofCommittedBuilder) GetChallengeContribution() []byte { + commitment := pcb.curve.Point.SumOfProducts(pcb.points, pcb.scalars) + if commitment == nil { + return nil + } + return commitment.ToAffineCompressed() +} + +// GenerateProof converts the blinding factors and secrets into Schnorr proofs +func (pcb ProofCommittedBuilder) GenerateProof(challenge curves.Scalar, secrets []curves.Scalar) ([]curves.Scalar, error) { + if len(secrets) != len(pcb.scalars) { + return nil, fmt.Errorf("secrets is not equal to blinding factors") + } + + proofs := make([]curves.Scalar, len(pcb.scalars)) + for i, sc := range pcb.scalars { + proofs[i] = secrets[i].MulAdd(challenge, sc) + } + return proofs, nil +} diff --git a/pkg/crypto/signatures/common/proof_message.go b/pkg/crypto/signatures/common/proof_message.go new file mode 100755 index 000000000..ab462c91b --- /dev/null +++ b/pkg/crypto/signatures/common/proof_message.go @@ -0,0 +1,79 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package common + +import ( + "io" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// ProofMessage classifies how a message is presented in a proof +// Either Revealed or Hidden. Hidden has two sub categories: +// proof specific i.e. the message is only used for this proof or +// shared i.e. the message should be proved to be common across proofs +type ProofMessage interface { + // IsHidden indicates the message should be hidden + IsHidden() bool + // GetBlinding is used for hidden messages + // blindings can either be proof specific to a signature + // or involved with other proofs like boundchecks, + // set memberships, or inequalities so the blinding + // factor is shared among proofs to produce a common + // schnorr linking proof + GetBlinding(reader io.Reader) curves.Scalar + // GetMessage returns the underlying message + GetMessage() curves.Scalar +} + +type RevealedMessage struct { + Message curves.Scalar +} + +func (r RevealedMessage) IsHidden() bool { + return false +} + +func (r RevealedMessage) GetBlinding(reader io.Reader) curves.Scalar { + return nil +} + +func (r RevealedMessage) GetMessage() curves.Scalar { + return r.Message +} + +type ProofSpecificMessage struct { + Message curves.Scalar +} + +func (ps ProofSpecificMessage) IsHidden() bool { + return true +} + +func (ps ProofSpecificMessage) GetBlinding(reader io.Reader) curves.Scalar { + return ps.Message.Random(reader) +} + +func (ps ProofSpecificMessage) GetMessage() curves.Scalar { + return ps.Message +} + +type SharedBlindingMessage struct { + Message, Blinding curves.Scalar +} + +func (ps SharedBlindingMessage) IsHidden() bool { + return true +} + +func (ps SharedBlindingMessage) GetBlinding(reader io.Reader) curves.Scalar { + return ps.Blinding +} + +func (ps SharedBlindingMessage) GetMessage() curves.Scalar { + return ps.Message +} diff --git a/pkg/crypto/signatures/common/signature_blinding.go b/pkg/crypto/signatures/common/signature_blinding.go new file mode 100755 index 000000000..e6988cc82 --- /dev/null +++ b/pkg/crypto/signatures/common/signature_blinding.go @@ -0,0 +1,14 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package common + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// SignatureBlinding is a value used for computing blind signatures +type SignatureBlinding = curves.PairingScalar diff --git a/pkg/crypto/signatures/schnorr/mina/bitvector.go b/pkg/crypto/signatures/schnorr/mina/bitvector.go new file mode 100755 index 000000000..70f86bd3d --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/bitvector.go @@ -0,0 +1,232 @@ +// Copyright (c) 2014 Dropbox, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package mina + +// A BitVector is a variable sized vector of bits. It supports +// lookups, sets, appends, insertions, and deletions. +// +// This class is not thread safe. +type BitVector struct { + data []byte + length int +} + +// NewBitVector creates and initializes a new bit vector with length +// elements, using data as its initial contents. +func NewBitVector(data []byte, length int) *BitVector { + return &BitVector{ + data: data, + length: length, + } +} + +// Bytes returns a slice of the contents of the bit vector. If the caller changes the returned slice, +// the contents of the bit vector may change. +func (vector *BitVector) Bytes() []byte { + return vector.data +} + +// Length returns the current number of elements in the bit vector. +func (vector *BitVector) Length() int { + return vector.length +} + +// This function shifts a byte slice one bit lower (less significant). +// bit (either 1 or 0) contains the bit to put in the most significant +// position of the last byte in the slice. +// This returns the bit that was shifted off of the last byte. +func shiftLower(bit byte, b []byte) byte { + bit = bit << 7 + for i := len(b) - 1; i >= 0; i-- { + newByte := b[i] >> 1 + newByte |= bit + bit = (b[i] & 1) << 7 + b[i] = newByte + } + return bit >> 7 +} + +// This function shifts a byte slice one bit higher (more significant). +// bit (either 1 or 0) contains the bit to put in the least significant +// position of the first byte in the slice. +// This returns the bit that was shifted off the last byte. +func shiftHigher(bit byte, b []byte) byte { + for i := 0; i < len(b); i++ { + newByte := b[i] << 1 + newByte |= bit + bit = (b[i] & 0x80) >> 7 + b[i] = newByte + } + return bit +} + +// Returns the minimum number of bytes needed for storing the bit vector. +func (vector *BitVector) bytesLength() int { + lastBitIndex := vector.length - 1 + lastByteIndex := lastBitIndex >> 3 + return lastByteIndex + 1 +} + +// Panics if the given index is not within the bounds of the bit vector. +func (vector *BitVector) indexAssert(i int) { + if i < 0 || i >= vector.length { + panic("Attempted to access element outside buffer") + } +} + +// Append adds a bit to the end of a bit vector. +func (vector *BitVector) Append(bit byte) { + index := uint32(vector.length) + vector.length++ + + if vector.bytesLength() > len(vector.data) { + vector.data = append(vector.data, 0) + } + + byteIndex := index >> 3 + byteOffset := index % 8 + oldByte := vector.data[byteIndex] + var newByte byte + if bit == 1 { + newByte = oldByte | 1<> 3 + byteOffset := uint32(i % 8) + b := vector.data[byteIndex] + // Check the offset bit + return (b >> byteOffset) & 1 +} + +// Set changes the bit in the ith index of the bit vector to the value specified in +// bit. +func (vector *BitVector) Set(bit byte, index int) { + vector.indexAssert(index) + byteIndex := uint32(index >> 3) + byteOffset := uint32(index % 8) + + oldByte := vector.data[byteIndex] + + var newByte byte + if bit == 1 { + // turn on the byteOffset'th bit + newByte = oldByte | 1< len(vector.data) { + vector.data = append(vector.data, 0) + } + + byteIndex := uint32(index >> 3) + byteOffset := uint32(index % 8) + var bitToInsert byte + if bit == 1 { + bitToInsert = 1 << byteOffset + } + + oldByte := vector.data[byteIndex] + // This bit will need to be shifted into the next byte + leftoverBit := (oldByte & 0x80) >> 7 + // Make masks to pull off the bits below and above byteOffset + // This mask has the byteOffset lowest bits set. + bottomMask := byte((1 << byteOffset) - 1) + // This mask has the 8 - byteOffset top bits set. + topMask := ^bottomMask + top := (oldByte & topMask) << 1 + newByte := bitToInsert | (oldByte & bottomMask) | top + + vector.data[byteIndex] = newByte + // Shift the rest of the bytes in the slice one higher, append + // the leftoverBit obtained above. + shiftHigher(leftoverBit, vector.data[byteIndex+1:]) +} + +// Delete removes the bit in the supplied index of the bit vector. All +// bits in positions greater than or equal to index before the call will +// be shifted down by one. +func (vector *BitVector) Delete(index int) { + vector.indexAssert(index) + vector.length-- + byteIndex := uint32(index >> 3) + byteOffset := uint32(index % 8) + + oldByte := vector.data[byteIndex] + + // Shift all the bytes above the byte we're modifying, return the + // leftover bit to include in the byte we're modifying. + bit := shiftLower(0, vector.data[byteIndex+1:]) + + // Modify oldByte. + // At a high level, we want to select the bits above byteOffset, + // and shift them down by one, removing the bit at byteOffset. + + // This selects the bottom bits + bottomMask := byte((1 << byteOffset) - 1) + // This selects the top (8 - byteOffset - 1) bits + topMask := byte(^((1 << (byteOffset + 1)) - 1)) + // newTop is the top bits, shifted down one, combined with the leftover bit from shifting + // the other bytes. + newTop := (oldByte&topMask)>>1 | (bit << 7) + // newByte takes the bottom bits and combines with the new top. + newByte := (bottomMask & oldByte) | newTop + vector.data[byteIndex] = newByte + + // The desired length is the byte index of the last element plus one, + // where the byte index of the last element is the bit index of the last + // element divided by 8. + byteLength := vector.bytesLength() + if byteLength < len(vector.data) { + vector.data = vector.data[:byteLength] + } +} diff --git a/pkg/crypto/signatures/schnorr/mina/challenge_derive.go b/pkg/crypto/signatures/schnorr/mina/challenge_derive.go new file mode 100755 index 000000000..345ee66cd --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/challenge_derive.go @@ -0,0 +1,42 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type MinaTSchnorrHandler struct{} + +func (m MinaTSchnorrHandler) DeriveChallenge(msg []byte, pubKey curves.Point, r curves.Point) (curves.Scalar, error) { + txn := new(Transaction) + err := txn.UnmarshalBinary(msg) + if err != nil { + return nil, err + } + input := new(roinput).Init(3, 75) + txn.addRoInput(input) + + pt, ok := pubKey.(*curves.PointPallas) + if !ok { + return nil, fmt.Errorf("invalid point") + } + R, ok := r.(*curves.PointPallas) + if !ok { + return nil, fmt.Errorf("invalid point") + } + + pk := new(PublicKey) + pk.value = pt.GetEp() + + sc := msgHash(pk, R.X(), input, ThreeW, MainNet) + s := new(curves.ScalarPallas) + s.SetFq(sc) + return s, nil +} diff --git a/pkg/crypto/signatures/schnorr/mina/keys.go b/pkg/crypto/signatures/schnorr/mina/keys.go new file mode 100755 index 000000000..231064ea2 --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/keys.go @@ -0,0 +1,272 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + crand "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "encoding/binary" + "fmt" + "io" + + "github.com/mr-tron/base58" + "golang.org/x/crypto/blake2b" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fq" +) + +const ( + version = 0xcb + nonZeroCurvePointVersion = 0x01 + isCompressed = 0x01 +) + +// PublicKey is the verification key +type PublicKey struct { + value *curves.Ep +} + +// GenerateAddress converts the public key to an address +func (pk PublicKey) GenerateAddress() string { + var payload [40]byte + payload[0] = version + payload[1] = nonZeroCurvePointVersion + payload[2] = isCompressed + + buffer := pk.value.ToAffineUncompressed() + copy(payload[3:35], buffer[:32]) + payload[35] = buffer[32] & 1 + hash1 := sha256.Sum256(payload[:36]) + hash2 := sha256.Sum256(hash1[:]) + copy(payload[36:40], hash2[:4]) + return base58.Encode(payload[:]) +} + +// ParseAddress converts a given string into a public key returning an error on failure +func (pk *PublicKey) ParseAddress(b58 string) error { + buffer, err := base58.Decode(b58) + if err != nil { + return err + } + if len(buffer) != 40 { + return fmt.Errorf("invalid byte sequence") + } + if buffer[0] != version { + return fmt.Errorf("invalid version") + } + if buffer[1] != nonZeroCurvePointVersion { + return fmt.Errorf("invalid non-zero curve point version") + } + if buffer[2] != isCompressed { + return fmt.Errorf("invalid compressed flag") + } + hash1 := sha256.Sum256(buffer[:36]) + hash2 := sha256.Sum256(hash1[:]) + if subtle.ConstantTimeCompare(hash2[:4], buffer[36:40]) != 1 { + return fmt.Errorf("invalid checksum") + } + x := buffer[3:35] + x[31] |= buffer[35] << 7 + value, err := new(curves.Ep).FromAffineCompressed(x) + if err != nil { + return err + } + pk.value = value + return nil +} + +func (pk PublicKey) MarshalBinary() ([]byte, error) { + return pk.value.ToAffineCompressed(), nil +} + +func (pk *PublicKey) UnmarshalBinary(input []byte) error { + pt, err := new(curves.Ep).FromAffineCompressed(input) + if err != nil { + return err + } + pk.value = pt + return nil +} + +func (pk *PublicKey) SetPointPallas(pallas *curves.PointPallas) { + pk.value = pallas.GetEp() +} + +// SecretKey is the signing key +type SecretKey struct { + value *fq.Fq +} + +// GetPublicKey returns the corresponding verification +func (sk SecretKey) GetPublicKey() *PublicKey { + pk := new(curves.Ep).Mul(new(curves.Ep).Generator(), sk.value) + return &PublicKey{pk} +} + +func (sk SecretKey) MarshalBinary() ([]byte, error) { + t := sk.value.Bytes() + return t[:], nil +} + +func (sk *SecretKey) UnmarshalBinary(input []byte) error { + if len(input) != 32 { + return fmt.Errorf("invalid byte sequence") + } + var buf [32]byte + copy(buf[:], input) + value, err := new(fq.Fq).SetBytes(&buf) + if err != nil { + return err + } + sk.value = value + return nil +} + +func (sk *SecretKey) SetFq(fq *fq.Fq) { + sk.value = fq +} + +// NewKeys creates a new keypair using a CSPRNG +func NewKeys() (*PublicKey, *SecretKey, error) { + return NewKeysFromReader(crand.Reader) +} + +// NewKeysFromReader creates a new keypair using the specified reader +func NewKeysFromReader(reader io.Reader) (*PublicKey, *SecretKey, error) { + t := new(curves.ScalarPallas).Random(reader) + sc, ok := t.(*curves.ScalarPallas) + if !ok || t.IsZero() { + return nil, nil, fmt.Errorf("invalid key") + } + sk := sc.GetFq() + pk := new(curves.Ep).Mul(new(curves.Ep).Generator(), sk) + if pk.IsIdentity() { + return nil, nil, fmt.Errorf("invalid key") + } + + return &PublicKey{pk}, &SecretKey{sk}, nil +} + +// SignTransaction generates a signature over the specified txn and network id +// See https://github.com/MinaProtocol/c-reference-signer/blob/master/crypto.c#L1020 +func (sk *SecretKey) SignTransaction(transaction *Transaction) (*Signature, error) { + input := new(roinput).Init(3, 75) + transaction.addRoInput(input) + return sk.finishSchnorrSign(input, transaction.NetworkId) +} + +// SignMessage signs a _string_. this is somewhat non-standard; we do it by just adding bytes to the roinput. +// See https://github.com/MinaProtocol/c-reference-signer/blob/master/crypto.c#L1020 +func (sk *SecretKey) SignMessage(message string) (*Signature, error) { + input := new(roinput).Init(0, len(message)) + input.AddBytes([]byte(message)) + return sk.finishSchnorrSign(input, MainNet) +} + +func (sk *SecretKey) finishSchnorrSign(input *roinput, networkId NetworkType) (*Signature, error) { + if sk.value.IsZero() { + return nil, fmt.Errorf("invalid secret key") + } + pk := sk.GetPublicKey() + k := sk.msgDerive(input, pk, networkId) + if k.IsZero() { + return nil, fmt.Errorf("invalid nonce generated") + } + // r = k*G + r := new(curves.Ep).Generator() + r.Mul(r, k) + + if r.Y().IsOdd() { + k.Neg(k) + } + rx := r.X() + e := msgHash(pk, rx, input, ThreeW, networkId) + + // S = k + e*sk + e.Mul(e, sk.value) + s := new(fq.Fq).Add(k, e) + if rx.IsZero() || s.IsZero() { + return nil, fmt.Errorf("invalid signature") + } + return &Signature{ + R: rx, + S: s, + }, nil +} + +// VerifyTransaction checks if the signature is over the given transaction using this public key +func (pk *PublicKey) VerifyTransaction(sig *Signature, transaction *Transaction) error { + input := new(roinput).Init(3, 75) + transaction.addRoInput(input) + return pk.finishSchnorrVerify(sig, input, transaction.NetworkId) +} + +// VerifyMessage checks if the claimed signature on a _string_ is valid. this is nonstandard; see above. +func (pk *PublicKey) VerifyMessage(sig *Signature, message string) error { + input := new(roinput).Init(0, len(message)) + input.AddBytes([]byte(message)) + return pk.finishSchnorrVerify(sig, input, MainNet) +} + +func (pk *PublicKey) finishSchnorrVerify(sig *Signature, input *roinput, networkId NetworkType) error { + if pk.value.IsIdentity() { + return fmt.Errorf("invalid public key") + } + if sig.R.IsZero() || sig.S.IsZero() { + return fmt.Errorf("invalid signature") + } + e := msgHash(pk, sig.R, input, ThreeW, networkId) + sg := new(curves.Ep).Generator() + sg.Mul(sg, sig.S) + + epk := new(curves.Ep).Mul(pk.value, e) + epk.Neg(epk) + + r := new(curves.Ep).Add(sg, epk) + if !r.Y().IsOdd() && r.X().Equal(sig.R) { + return nil + } else { + return fmt.Errorf("signature verification failed") + } +} + +func msgHash(pk *PublicKey, rx *fp.Fp, input *roinput, hashType Permutation, networkId NetworkType) *fq.Fq { + input.AddFp(pk.value.X()) + input.AddFp(pk.value.Y()) + input.AddFp(rx) + + ctx := new(Context).Init(hashType, networkId) + fields := input.Fields() + ctx.Update(fields) + return ctx.Digest() +} + +func (sk SecretKey) msgDerive(msg *roinput, pk *PublicKey, networkId NetworkType) *fq.Fq { + input := msg.Clone() + input.AddFp(pk.value.X()) + input.AddFp(pk.value.Y()) + input.AddFq(sk.value) + input.AddBytes([]byte{byte(networkId)}) + inputBytes := input.Bytes() + + h, _ := blake2b.New(32, []byte{}) + _, _ = h.Write(inputBytes) + hash := h.Sum(nil) + + // Clear top two bits + hash[31] &= 0x3F + tmp := [4]uint64{ + binary.LittleEndian.Uint64(hash[:8]), + binary.LittleEndian.Uint64(hash[8:16]), + binary.LittleEndian.Uint64(hash[16:24]), + binary.LittleEndian.Uint64(hash[24:32]), + } + return new(fq.Fq).SetRaw(&tmp) +} diff --git a/pkg/crypto/signatures/schnorr/mina/keys_test.go b/pkg/crypto/signatures/schnorr/mina/keys_test.go new file mode 100755 index 000000000..d48844058 --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/keys_test.go @@ -0,0 +1,132 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fq" +) + +func TestNewKeys(t *testing.T) { + pk, sk, err := NewKeys() + require.NoError(t, err) + require.NotNil(t, sk) + require.NotNil(t, pk) + require.False(t, sk.value.IsZero()) + require.False(t, pk.value.IsIdentity()) +} + +func TestSecretKeySignTransaction(t *testing.T) { + // See https://github.com/MinaProtocol/c-reference-signer/blob/master/reference_signer.c#L15 + skValue := &fq.Fq{ + 0xca14d6eed923f6e3, 0x61185a1b5e29e6b2, 0xe26d38de9c30753b, 0x3fdf0efb0a5714, + } + sk := &SecretKey{value: skValue} + /* + This illustrates constructing and signing the following transaction. + amounts are in nanocodas. + { + "common": { + "fee": "3", + "fee_token": "1", + "fee_payer_pk": "B62qiy32p8kAKnny8ZFwoMhYpBppM1DWVCqAPBYNcXnsAHhnfAAuXgg", + "nonce": "200", + "valid_until": "10000", + "memo": "E4Yq8cQXC1m9eCYL8mYtmfqfJ5cVdhZawrPQ6ahoAay1NDYfTi44K" + }, + "body": [ + "Payment", + { + "source_pk": "B62qiy32p8kAKnny8ZFwoMhYpBppM1DWVCqAPBYNcXnsAHhnfAAuXgg", + "receiver_pk": "B62qrcFstkpqXww1EkSGrqMCwCNho86kuqBd4FrAAUsPxNKdiPzAUsy", + "token_id": "1", + "amount": "42" + } + ] + } + */ + feePayerPk := new(PublicKey) + err := feePayerPk.ParseAddress("B62qiy32p8kAKnny8ZFwoMhYpBppM1DWVCqAPBYNcXnsAHhnfAAuXgg") + require.NoError(t, err) + sourcePk := new(PublicKey) + err = sourcePk.ParseAddress("B62qiy32p8kAKnny8ZFwoMhYpBppM1DWVCqAPBYNcXnsAHhnfAAuXgg") + require.NoError(t, err) + receiverPk := new(PublicKey) + err = receiverPk.ParseAddress("B62qrcFstkpqXww1EkSGrqMCwCNho86kuqBd4FrAAUsPxNKdiPzAUsy") + require.NoError(t, err) + txn := &Transaction{ + Fee: 3, + FeeToken: 1, + Nonce: 200, + ValidUntil: 10000, + Memo: "this is a memo", + FeePayerPk: feePayerPk, + SourcePk: sourcePk, + ReceiverPk: receiverPk, + TokenId: 1, + Amount: 42, + Locked: false, + Tag: [3]bool{false, false, false}, + NetworkId: MainNet, + } + sig, err := sk.SignTransaction(txn) + require.NoError(t, err) + pk := sk.GetPublicKey() + require.NoError(t, pk.VerifyTransaction(sig, txn)) +} + +func TestSecretKeySignMessage(t *testing.T) { + // See https://github.com/MinaProtocol/c-reference-signer/blob/master/reference_signer.c#L15 + skValue := &fq.Fq{ + 0xca14d6eed923f6e3, 0x61185a1b5e29e6b2, 0xe26d38de9c30753b, 0x3fdf0efb0a5714, + } + sk := &SecretKey{value: skValue} + sig, err := sk.SignMessage("A test message.") + require.NoError(t, err) + pk := sk.GetPublicKey() + require.NoError(t, pk.VerifyMessage(sig, "A test message.")) +} + +func TestSecretKeySignTransactionStaking(t *testing.T) { + // https://github.com/MinaProtocol/c-reference-signer/blob/master/reference_signer.c#L128 + skValue := &fq.Fq{ + 0xca14d6eed923f6e3, 0x61185a1b5e29e6b2, 0xe26d38de9c30753b, 0x3fdf0efb0a5714, + } + sk := &SecretKey{value: skValue} + + feePayerPk := new(PublicKey) + err := feePayerPk.ParseAddress("B62qiy32p8kAKnny8ZFwoMhYpBppM1DWVCqAPBYNcXnsAHhnfAAuXgg") + require.NoError(t, err) + sourcePk := new(PublicKey) + err = sourcePk.ParseAddress("B62qiy32p8kAKnny8ZFwoMhYpBppM1DWVCqAPBYNcXnsAHhnfAAuXgg") + require.NoError(t, err) + receiverPk := new(PublicKey) + err = receiverPk.ParseAddress("B62qkfHpLpELqpMK6ZvUTJ5wRqKDRF3UHyJ4Kv3FU79Sgs4qpBnx5RR") + require.NoError(t, err) + txn := &Transaction{ + Fee: 3, + FeeToken: 1, + Nonce: 10, + ValidUntil: 4000, + Memo: "more delegates more fun", + FeePayerPk: feePayerPk, + SourcePk: sourcePk, + ReceiverPk: receiverPk, + TokenId: 1, + Amount: 0, + Locked: false, + Tag: [3]bool{false, false, true}, + NetworkId: MainNet, + } + sig, err := sk.SignTransaction(txn) + require.NoError(t, err) + pk := sk.GetPublicKey() + require.NoError(t, pk.VerifyTransaction(sig, txn)) +} diff --git a/pkg/crypto/signatures/schnorr/mina/poseidon_config.go b/pkg/crypto/signatures/schnorr/mina/poseidon_config.go new file mode 100755 index 000000000..d2fbfaca4 --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/poseidon_config.go @@ -0,0 +1,112 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fp" +) + +// SBox is the type of exponentiation to perform +type SBox int + +const ( + Cube = iota // x^3 + Quint // x^5 + Sept // x^7 + Inverse // x^-1 +) + +// Exp mutates f by computing x^3, x^5, x^7 or x^-1 as described in +// https://eprint.iacr.org/2019/458.pdf page 8 +func (sbox SBox) Exp(f *fp.Fp) { + switch sbox { + case Cube: + t := new(fp.Fp).Square(f) + f.Mul(t, f) + case Quint: + t := new(fp.Fp).Square(f) + t.Square(t) + f.Mul(t, f) + case Sept: + f2 := new(fp.Fp).Square(f) + f4 := new(fp.Fp).Square(f2) + t := new(fp.Fp).Mul(f2, f4) + f.Mul(t, f) + case Inverse: + f.Invert(f) + default: + } +} + +// Permutation is the permute function to use +type Permutation int + +const ( + ThreeW = iota + FiveW + Three +) + +// Permute executes the poseidon hash function +func (p Permutation) Permute(ctx *Context) { + switch p { + case ThreeW: + for r := 0; r < ctx.fullRounds; r++ { + ark(ctx, r) + sbox(ctx) + mds(ctx) + } + ark(ctx, ctx.fullRounds) + case Three: + fallthrough + case FiveW: + // Full rounds only + for r := 0; r < ctx.fullRounds; r++ { + sbox(ctx) + mds(ctx) + ark(ctx, r) + } + default: + } +} + +func ark(ctx *Context, round int) { + for i := 0; i < ctx.spongeWidth; i++ { + ctx.state[i].Add(ctx.state[i], ctx.roundKeys[round][i]) + } +} + +func sbox(ctx *Context) { + for i := 0; i < ctx.spongeWidth; i++ { + ctx.sBox.Exp(ctx.state[i]) + } +} + +func mds(ctx *Context) { + state2 := make([]*fp.Fp, len(ctx.state)) + for i := range ctx.state { + state2[i] = new(fp.Fp).SetZero() + } + for row := 0; row < ctx.spongeWidth; row++ { + for col := 0; col < ctx.spongeWidth; col++ { + t := new(fp.Fp).Mul(ctx.state[col], ctx.mdsMatrix[row][col]) + state2[row].Add(state2[row], t) + } + } + for i, f := range state2 { + ctx.state[i].Set(f) + } +} + +// NetworkType is which Mina network id to use +type NetworkType int + +const ( + TestNet = iota + MainNet + NullNet +) diff --git a/pkg/crypto/signatures/schnorr/mina/poseidon_hash.go b/pkg/crypto/signatures/schnorr/mina/poseidon_hash.go new file mode 100755 index 000000000..f45fdb6e6 --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/poseidon_hash.go @@ -0,0 +1,1182 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fq" +) + +type Context struct { + state []*fp.Fp + absorbed, spongeWidth, spongeRate, fullRounds int + sBox SBox + pType Permutation + spongeIv [][]*fp.Fp + roundKeys [][]*fp.Fp + mdsMatrix [][]*fp.Fp +} + +var contexts = []*Context{ + // threeW + { + spongeWidth: 3, + spongeRate: 2, + fullRounds: 63, + sBox: Quint, + pType: ThreeW, + roundKeys: [][]*fp.Fp{ + { + {0xd2425a07cfec91d, 0x6130240fd42af5be, 0x3fb56f00f649325, 0x107d26d6fefb125f}, + {0x1dcedf2d0ebcb628, 0x2381dfa5face2460, 0x24e92a6d36d75404, 0xce8a325b8f74c91}, + {0x5df2ca8d054dc3a, 0x7fb9bf2f82379968, 0x424e2934a76cffb8, 0xb775aeab9b31f6a}, + }, + { + {0x9e6d7a567eaacc30, 0xced5d7ac222f233c, 0x2fe5c196ec8ffd26, 0x2a8f0caeda769601}, + {0xdc68662e69f84551, 0x1495455fbfab4087, 0xab2e97a03e2a079d, 0x3e93afa4e82ac2a0}, + {0x4cc46cd35daca246, 0x54dcc54ee433c73f, 0x893be89025513bde, 0x3b52fbe29b9d1b53}, + }, + { + {0xd96382010ec8b913, 0x9921d471216af4b5, 0xa7df09d5ecf06de, 0xa360d0e19232e76}, + {0x408add78a89dcf34, 0xb15031ad7e3ec92, 0x8ef35f1ab8093a79, 0x23276aa7a64b85a4}, + {0xdac52436f6c1cdd0, 0x46257295a42ee0b2, 0x3090799e349ade62, 0x261f8de11adb9313}, + }, + { + {0x51fb0207578466ed, 0xace76bd4ce53012a, 0x45f74735a873a7a6, 0x25be1a7e5c85f326}, + {0xdee055cc9572cc61, 0x9373df1526d6e34b, 0x2084c5641a3122a3, 0x3062d3265012feed}, + {0x1bd9070c51f40e9b, 0x9ea653d50b3fa6f, 0xa31a6b51060fc899, 0x703ce3434f96fea}, + }, + { + {0x937e0bd5442efc15, 0xc1b3a953fbd209b7, 0xb3737616f1f7eb8b, 0x5b10777bdf5dacd}, + {0x10791e59a7d5788a, 0x12f9041014d93ea, 0xb4bc24f34f470c71, 0x2f00cd1954db2d8c}, + {0xe912d7ae74abca54, 0xc5c26a35e725fd41, 0xb6af66a891d1c628, 0x3e5ec2bf0970d4a3}, + }, + { + {0x8340c5579ef76e75, 0x84685beb75f0fd3d, 0xd3a06c47523190d2, 0x308b8895c2d04040}, + {0x457356859f821f53, 0x8abdeeacf3a1ba9e, 0x43b602e5b2ad8b28, 0xc1879b3610fd2f4}, + {0x97b86a707b5809bc, 0x8dd94d73fb34a3ee, 0x5141652598014000, 0x32e8c24d1cee432e}, + }, + { + {0xa998c731389a48f3, 0x74fa8b44a0ab13b, 0x1ad03f591da71333, 0x2f03d178701bcb30}, + {0x8ff226bd0dd22c53, 0x26157e7a0aa47f2a, 0xe2531d8e88c5531d, 0x13d2bbc731281e5f}, + {0x76d7f22ef74ebe99, 0x245727aa206d8c55, 0x4e9bda26e39fe51, 0x72b21a3b6ea088d}, + }, + { + {0x67aff49f723add69, 0xccae0df20e3d633b, 0x85d57c5cda0e022c, 0xa398b1d3e6f2db1}, + {0x3fda2e26bcb6fc68, 0x593102ff961e4b40, 0xcaca5e29529738de, 0x2af42667a6e9b6cc}, + {0x9d05ac0056c6910a, 0x51343579482ba8b5, 0x33398f54089da2a3, 0x1879180149c97c34}, + }, + { + {0xfa93dc63c73d6490, 0x898847d037d78917, 0xf104b998c8ba5384, 0x1c6102bfd9c26df2}, + {0x3b13a7624fe64fc3, 0xae197dfb77fc7968, 0x855c3edfd013edc, 0x247f5769ca4aa6}, + {0x58bf743e0004f4eb, 0xa168da971a4635e8, 0xae0d93fc0aa0ca7c, 0x2e94bd91ee0eedec}, + }, + { + {0x826688455b3034d9, 0xd7a8296917d9820f, 0xbf14001a68903362, 0x3029935cebc0e1b5}, + {0x45622b94048f7c58, 0x1025e0f2169c46c1, 0x93dccace2e8635fa, 0x2110fe2a3a9c405b}, + {0xe6249e1fd6ae6204, 0x359cea9c7fc56811, 0x4561c87d295edc47, 0x3462ff6269ff9b7f}, + }, + { + {0xe88503091bf18fdb, 0xc7c9e48c7792429a, 0x7c2bedc34044daad, 0x239b54131c85ebfe}, + {0x9f92ac6cdf6d115c, 0x64fe79c6ea405241, 0x3fdbbe356870f930, 0x3c0d419e26ff24c1}, + {0xeb4e19e81548807b, 0x30d9ca531360e746, 0xe7fd824c32ef0f3d, 0x25c98a72c313174a}, + }, + { + {0xed7835758762c591, 0xd3a5813b88ed365f, 0x954d02a8633dba6f, 0x3da1af9d7eb3a01e}, + {0x86a8692d3ed59690, 0xf2873c2381bf29b6, 0x5d8735bb1f3f459, 0x3c9a66efcbdbfd6e}, + {0x7acc7d7a0e1d24a3, 0x8614a6c50e15e4f7, 0xac5ee237c5548dd4, 0x12061a68b6963446}, + }, + { + {0x81bc9093c7730d5, 0xbf3e57fb7d94a12f, 0xab7caef0406ad333, 0x30d704e038c83cee}, + {0x53fd9bef62ab35ab, 0xdd9258a43a400a0e, 0x41fc71c1f14a3fe0, 0xaafb95e685e323a}, + {0xbb168efcfbc6417d, 0x6eec41829c340ecc, 0x3e1a203ea728cf86, 0x32403a5339001606}, + }, + { + {0xaa842cc888cce8e1, 0xaf60b8e8cfa84e30, 0xa8345e318e18911e, 0x23adb957cfe95986}, + {0x9b565aa4fc6cbed, 0x715714218a6da1db, 0x60740ecb2b402402, 0x3446170f139a28ee}, + {0x2d56545ce19df759, 0x2e62009452ac4624, 0xf834fd669efdc382, 0x3cdb040c5a2c8135}, + }, + { + {0x2c093b07989ac45b, 0xbc5a7ce41629b4d8, 0xf9f8f9ccd52de847, 0xa6852ff99c0df59}, + {0x62ec3921cae6ad0c, 0xed01dd4b15bc12e2, 0xcf099203d7296486, 0x10c70f52d8e4c35c}, + {0xe3afb13d98e0aa36, 0xd5c2e410a19ecae7, 0x7ef462f8ef00f1ee, 0x3b2666c865ffaf5f}, + }, + { + {0x2a34a9799fb10dea, 0xae3b7ac93a88e642, 0x9ce2e0a5b4676e62, 0x35338d2e290f6835}, + {0x704c2116789cd3e, 0x55c9408a44e87b39, 0x9a178778cf8123ac, 0x2a237d751ce80e22}, + {0xe73cc5f3949b8dac, 0x25fcebdc28f57fc2, 0xb8f4c26538ae8063, 0x160d42c37b816d52}, + }, + { + {0x78bba3a1b4334fec, 0xe1ad733be7312e24, 0x166c29284c5e74cf, 0x1e39c10d204c6e}, + {0xeba34937ed572fb8, 0xec650563d7045e13, 0xbf694cf0e16bc82c, 0x14394f78ca804fcb}, + {0xa28d8e959c93e39c, 0xfe2361a2d86799e3, 0xb04a4d8890bfaa19, 0x3bd58529949c0ff6}, + }, + { + {0x29225c95f5b1b6f9, 0xa6deebafdf12f757, 0x4d08632fbf4f058, 0x22ca57e20c30a4e2}, + {0xbd76f38890b3567b, 0x26cf81518916ab2, 0xe6096fe367359511, 0x1f5e2a08564c51ca}, + {0x522b7903b745f6ae, 0x97976d9feb2f329a, 0x4042a062305c3dd, 0x10e8bfbac34f6ab}, + }, + { + {0x53a7679692da3aa1, 0xe450599e85d31d58, 0x7b0eb8260f95a840, 0x1ace63dc713e7378}, + {0x725231ba432706f4, 0xccfededdca80880, 0xeba96b0dfbc1ccb5, 0x2584d3df4dd8a065}, + {0xe55f4913a1b47696, 0x34767187e1938949, 0xdbe1913ab957b7f2, 0x3c4be85646076541}, + }, + { + {0x96165fe1910385e3, 0xd8d34657e37bf741, 0x2dc65b5bd92b7412, 0x17c70695eabaad8c}, + {0x1aa94fbcda906296, 0x92b63261bad15d4, 0xde1fae454d20bc2, 0xff4dd19e7bb91c}, + {0x9a3c6bb3b3792b29, 0xba9a9d2d8c8f32fb, 0x90cae23b992784b0, 0x682d0d05588a0a4}, + }, + { + {0x8bea2f0e3b07fdae, 0xa2bcf89d80d35726, 0x544cd1414cc270fe, 0x113a9293d2324718}, + {0xae456164d267504c, 0x571cb023dbc1ce73, 0x21bac9730f19acbf, 0x3233efcc4435feb}, + {0x8c75648ce93bee2e, 0x6a7b2664251ea438, 0xca0e6900ef478974, 0x2ea2eb8e4287afe1}, + }, + { + {0x5acd5490088631ea, 0x796fd55cbfe132ea, 0xca378169084f5b20, 0x3bf94c0b770e6732}, + {0x3c7cc5fe22e9da10, 0x8c8312f4ace0a8a5, 0xc87567978ce028f8, 0x5a6f235fb313cd5}, + {0x2e6558b92407dcaf, 0x47e50ce3601012f4, 0x1e5797dd5bec08f6, 0x3f8733eee4c3467}, + }, + { + {0x94d2410224bcb62d, 0x3a926c5d9a86b7d4, 0x4e194b53953a44be, 0x352e9b3d78b5bcc}, + {0x54883a363d4cf9d5, 0x11f8990c505f0d36, 0x6bc1b45721bf8c66, 0x1741726454535739}, + {0x6f9a3ecf74a296b, 0x5de95fe78d089d68, 0xd73cd49e13d43129, 0x2093f7ce8f9a0900}, + }, + { + {0xe9cb00b14e26ff0d, 0x3f08fd94461dc18e, 0x631adca53058abce, 0x3214d344acadc846}, + {0xded7eb4dbd85489a, 0x88fec23b8cd8b77, 0x16d4ed13eab05211, 0x2846ac03154cebb9}, + {0xfac2a0ad57a4f26, 0xc1f76ecd19989adf, 0xaf30edcd16db54f2, 0x126d20470a443867}, + }, + { + {0xcff7162b34203071, 0xe55b077617c9a757, 0x2130b1adac59d068, 0x14c5aaf1e7b110eb}, + {0x699dd6dbcf0482c0, 0xea319e0d0b2bb999, 0xaa9e419d224d713d, 0x1f4d7ca828085388}, + {0xe0ce736d12ec2b2e, 0x2f38bcf04ebf093c, 0x4b4b4eb19457afe9, 0x36a6b22a47328281}, + }, + { + {0x787526c6865dcd1e, 0xc2680fe54617f4a8, 0xb727dbb67712e717, 0x3a271ba53713445c}, + {0x806dc7288ade48b8, 0x37ae24211f9b6b9d, 0x8ca3d974dbf15054, 0x10fd6d9432eb0b68}, + {0xec73bef3a5597993, 0x911600cb416be443, 0x3ea4d6875cf79676, 0x1b77d3b73ff96642}, + }, + { + {0x599dae5eba7bbf12, 0xad64c1aab4e1e894, 0x5d661ccb5ee325bf, 0x126b7751010f9d3f}, + {0x5ed0e07555bb26cd, 0x6e878aa29bf2c2e8, 0xf5a5eeccbaa31dc1, 0x1d3867eb4e090941}, + {0x2937ca036763d28b, 0x86e99a452605b663, 0x724c2748daf8484b, 0xebc687217853e09}, + }, + { + {0x4dbc428bc8ad6e5d, 0xa2f7ba399263b882, 0x7bf0cdf85013257c, 0x28aeab12f70ef4a}, + {0x3c7790781e18b6e, 0x1bb3023fe1e655cb, 0xed1fdfcb455dca1a, 0x32e02d39a4d657a}, + {0x44e6d9c3a1dff228, 0xdf469cea3c0a5407, 0x299c3245b897c072, 0x2be7edf85aee84d5}, + }, + { + {0x7cef1e98b43bf15c, 0x5a8dd042cde4ffe2, 0xd86af3fcf5e44a3b, 0x126fff14c130fdf6}, + {0x902d3cbb3b8bffd3, 0xd0510141c9be133a, 0x1153608479eba1e3, 0x33b9a4fa153248fb}, + {0x2267900dcf1e0fe4, 0xaf0c04b7861398c6, 0x55b20fd2619336f9, 0x3729ba618d213b74}, + }, + { + {0x7bccad65b5fd53a3, 0x275fd70abbee0824, 0x6fce1c43407f5ddd, 0x381402c3966b0d15}, + {0xd4e90f5f5d1b1215, 0x7abfb980598b6f39, 0x6cc413a7353c523b, 0x3af9e5c6dbcecf69}, + {0xfc86b3533d23176f, 0xf2f83c14f801bf0f, 0x5fb324c8b8b84f4c, 0x2a9949609d62d389}, + }, + { + {0xfca79d23caa474da, 0x94af585882c48b4, 0x9184e6e773524de, 0x1971a4bd05472cc6}, + {0xe14a7a9f4d347481, 0xf68eb0d753ed0146, 0x624211b6c3d94cff, 0x399c54dc6cd81b81}, + {0x86039539dbb961f9, 0xa5af68dc06d8ea6, 0xcc02fcf05e368eed, 0xf64acd9952a945b}, + }, + { + {0x88c5c3ea3b0286e6, 0x8c0cf8675f0040d5, 0xc0f11c1177699ea2, 0xe3cc78066df561b}, + {0x49162b2f404f976c, 0x9a40001b3ac29cdd, 0x17287f8ca8386222, 0x39ca8d14934343bf}, + {0xa8dd36db44116537, 0x42dbe51eb9216283, 0xfec6c18c5ea56c1c, 0x9b0bc57ea6681fa}, + }, + { + {0x53684675590d10f8, 0x228bd6ed1447104c, 0xcac8753557c5e945, 0x2533527c9ad29ad6}, + {0x5e26e312638c73b4, 0x34e1114452f840c, 0xc90124a9e02e5aad, 0x2af2662d93aa4250}, + {0x76bb15558221d4af, 0x41d2a02a322e09b9, 0x29727b4d6c29e353, 0x13f30e86ab0297f6}, + }, + { + {0x8b113723e368b29c, 0x2ebddd5dcfd07680, 0x90027a89063fd6b, 0xab82f5420ead368}, + {0x6102c2fbeb0b8f83, 0x37caec74787f8363, 0xef4c7fedf4d49d09, 0x157481ef03f526da}, + {0x897dc99e348f8989, 0xfae2d8c6ca328b03, 0xd2a217387ae7e8fa, 0x2309412d902ce2d3}, + }, + { + {0x57895d8995bb037b, 0x4f303912d7010f4, 0x89d126adee61fd7b, 0x16ae40bb98717e4a}, + {0x970b8cda0d943140, 0xd07503f516f70525, 0xb14ed69e29e5ede5, 0x2316911f23d9bed1}, + {0x632e10c13ba9d605, 0x23723cd16be7a1a3, 0xc0804d9b3264d489, 0x25b18b66bd5a14b1}, + }, + { + {0x2cc13abb89f41136, 0x7b209265228a3e0b, 0xde1b3e0db09f17e0, 0x10e37b1b53ecfceb}, + {0x765eb14dd8c343a4, 0x3359bbc963368294, 0xeb4667bd15fd4a6c, 0x2db8142000298d91}, + {0x916a19d68c0ed401, 0x5002ac7be8c90d22, 0x8ae3857c98f24376, 0xb2557905a7150c}, + }, + { + {0xf2b38d5f2758254d, 0x236745488b58741a, 0x394898e9d7458c8c, 0x37be2b56562adda1}, + {0x4aa28e0e6f54d290, 0x115bb413d8c4a639, 0x3944ec613d50506e, 0xbc68674dac60a3e}, + {0x82db6a2e85fec32c, 0x97802c924aadd00a, 0xbb6cc8685d8b265f, 0x16b975c2e70b76e6}, + }, + { + {0xe2f39f5ef957115b, 0x9a9db22a4623e0fa, 0x86f28972da216598, 0x11dc93268964d29c}, + {0xd8842bd61b12b92a, 0x6b1e45e4a6b4da39, 0xc2541381b20e4fc2, 0x3cc006d14574ded2}, + {0xfe0a6647ec349b4a, 0x7d7f9c30364402f9, 0x8f30b3425f1e6b75, 0xa08c94f56352fda}, + }, + { + {0xe8678e25a4d59721, 0x7c2331e36880e306, 0x82ad2f154d53292f, 0x38f905d3bf125a0d}, + {0x37c5ba5cf32727dd, 0x4e50703bbe74875c, 0x6e81ccf687c1edf3, 0x13d5a0a5cd167d3e}, + {0x549db53e76170f2d, 0x6601954d27f0614d, 0xa2e8516c0a8be8db, 0xe97e0bdc860ec97}, + }, + { + {0xab07a7c64e7a0c19, 0x3231ef6a85c561a2, 0x45cb8d5c9e495f6c, 0x3c130965bd821488}, + {0x4e85b1262b64c882, 0x148a4053173c6bbf, 0x2d30540d2bdf16b4, 0x1c4069538aad6db3}, + {0xe6f0d54ae64a6b4c, 0x8e435e285f5a0431, 0x89f8a4e55b2e5266, 0xc59b65276e7adbf}, + }, + { + {0xb3c5e9a0a063ba3c, 0xa5f4f9456cd30d09, 0x6d04f16139358814, 0xfe50ec7b61f34d3}, + {0x397f9724c5df2d2c, 0xebd5168a65e7dd00, 0x6e2d8f4b4688dfcc, 0x2089bd58ed27155}, + {0x4edc28aa719ba453, 0xd106c9909fe6d1bf, 0x583c7c64a6b2b9b9, 0x337410bcfb086e51}, + }, + { + {0xab6b2a207aa0b5dc, 0x4a8b65d7af08b29c, 0x933af8749e812390, 0x279107e984004c7f}, + {0x905ad996b3c96494, 0x64c09614294ad370, 0xe3a6ebea9d5f50c7, 0x39f0c91fd7487f70}, + {0xfb555601b96a98f6, 0x2779c5a69548b485, 0x1024d8abadf302ac, 0x9d7b11afa205c31}, + }, + { + {0x28cc587976dcbd5f, 0x7ec12e67d9fd9bff, 0x8519c024bfaacb31, 0xc3c59eef0b57c4}, + {0x7049bc5718274ce, 0xc5d45c2b8efbc27b, 0x1f2519b69fd58b2, 0x21d203679cf4943f}, + {0xdf1c276d845b18b, 0x83b415bcfd6f4794, 0x18cd69a7c02ec588, 0x28286f8440aac608}, + }, + { + {0xab9395e8f09c0e5e, 0x54e90df06eeabe37, 0x989b955540f5df9, 0x47eea2cb710d36a}, + {0x1ebb22981a2358d4, 0x978b30395e4ae485, 0x9b80f8337febb2dc, 0x6eadd7dff66e6fc}, + {0x8235f76b05fb36f3, 0xe81d3e6b55c01c67, 0xef1c4fbfd4f2689f, 0x356208269cd6bf63}, + }, + { + {0xdade3c9e413ae12e, 0xf0e6ec9130474658, 0xaf6a528f73acabe0, 0x25fa114c625e684a}, + {0x46eb556fec530561, 0xf037878098d1e6fa, 0x16665ada231de2c6, 0xe5526a3c3f20a1f}, + {0x8cf9f26ffb620afb, 0x10b561ad3be8bf53, 0xd095012a132c7d3f, 0x29dcadbf2a3da8a2}, + }, + { + {0xc1f246cabd2b3006, 0xa36999931ad6917e, 0xa86d5a37a14ebfc6, 0x233db2873238ccef}, + {0x6acabbbf7f09c6ab, 0x62e42b55c506b5ac, 0x20d3e5414eabcf58, 0x3047b6ea2b2ead12}, + {0xebb686baebe27e60, 0x6e299977bf344ce, 0x62074c04b5eaa97, 0x2f8be92e4b475d6c}, + }, + { + {0x68ec476c77321432, 0x6dc59804560e83e6, 0xad6ec6887fa80a57, 0xd2381657826abc9}, + {0xb377a593d24bcde1, 0x9a3338ee6dc43188, 0xfda6b04c6b645795, 0x1ebafbaa3cac50f4}, + {0xf53a7e9aa0eaf7a2, 0xc425d1cf708205ee, 0xc4bf63055e40b848, 0x31fd982712a1810}, + }, + { + {0x6aaec40a5ee97dc6, 0x1b740fec535e8d07, 0x72eb71573af7f8dc, 0x32a6cfd27721af}, + {0x4422e0763e1715cb, 0x2cc98a9c36481c08, 0x90a04c2c1100cf7, 0x14bdba391dc19c19}, + {0xf7ed8041fc74c1ba, 0x2da17664b7e0a39d, 0x7f194ed781738bd0, 0x185a0fb1e41d78e2}, + }, + { + {0x362d5eb8cf158562, 0x2cbda32193e3b946, 0x54a1587b53b6d3e, 0x3f6a83a8d453698e}, + {0xe4f331c807d7dbe4, 0x268c8fd3827cafa, 0x8128d4066a80b733, 0x3ac9356638ef0909}, + {0xc173b74baf5d10c0, 0xef4884b5f01dcb2a, 0x8ee4fbaf7d1af482, 0x3a631a390c1ace3a}, + }, + { + {0x8db20233cb7664ef, 0xcbd2b0d64c8e2b19, 0xb09d212d4b96af9b, 0xa41894a30594d96}, + {0xc87ad145936cc7b5, 0x831d623d07e2d55a, 0xb9f94b89928f0348, 0x32480b57ca35650c}, + {0x8df84ce2e7f6469f, 0x901e9cc791984cf9, 0xc8fcb9b481d64cbe, 0x3f5d039f9330361e}, + }, + { + {0xbf7db6c50e4b6c8e, 0xec86607f277ed803, 0x788b68697fc5fc3d, 0x31e6a675fa09e651}, + {0x1132c9835ce2f214, 0xe753150f8c8b375f, 0x8621813806da885e, 0xefb3b636dc3218c}, + {0x4ce5ce169e972cad, 0x36c4e02c437c353d, 0x91d0f983117961d3, 0x3fab66c8f61b43f4}, + }, + { + {0x26e7f148037e4831, 0xc898cea85a6d9ce7, 0x296eb709b0bce897, 0x13c7e41ce4a9413a}, + {0x364510c0cc6957d1, 0xc25f1640446d6363, 0xa38c8faccf2af7bc, 0x302f893eb7f3a293}, + {0xf47cdc9a193b6a1a, 0xbd3e81440b147a51, 0x1b8e11dc417ad50b, 0xbc7ad99db78ba74}, + }, + { + {0x5693220ff22b64e3, 0x95b8a7d6f5f07e88, 0xbb3aaa303d8a574, 0x20f50189f52021f3}, + {0xac8d038b73e50e93, 0x613109576b0dfb1e, 0x4ac8d41e35f9b309, 0xa7ad75a9d37c68c}, + {0x9c979eb72d6864c7, 0x8f1b33a9db15c462, 0xd9dfc2decd86ff41, 0x536ee7d16b7b5d5}, + }, + { + {0x624a1196b5b7005f, 0xb8d9cdf932bdf18, 0x14682525e48adc4a, 0x1d434955ccf03ab0}, + {0x719a6381517b8c7a, 0x6168713e68dfa531, 0x9b6cf63daf06a7ee, 0x1d259cdc7f7100c8}, + {0x6f1e012d7c9270c9, 0xe523c121eae14ae6, 0x50e570fed81bd490, 0x3604d717343ea349}, + }, + { + {0x4eb31e3e9fb8bc15, 0xaa82d889ed027926, 0x861770ba9013af2c, 0x379ab47829cd822c}, + {0x6f9b1e3a7b6dce3, 0xc5c9ef5c6b7a53d0, 0xc8d12ce69f47f1d6, 0xbc256406e070545}, + {0x6440d55f63d23009, 0x74c5732854d7e658, 0x4f7e9fd81fd40c7b, 0x399992d613926dad}, + }, + { + {0xc29845928af2930, 0xa0130ffd9a9f0e2a, 0x48033877dafbdd89, 0x8c39d86214ce71a}, + {0x9af58f43601d6790, 0xd1af4f75b46b599b, 0x4a8b0b5e6e229017, 0x187b443781223437}, + {0xe4304790543ef2b4, 0x9c231e915d799bd, 0x200b86e24d27b2ce, 0x2b71199749ffc729}, + }, + { + {0xf4ba819f140a9647, 0x959dd33caab9515e, 0xfd99be65b9533f42, 0x28a03868f0a95555}, + {0x6afe5aee6300eeb3, 0x950ea44539e2fa43, 0xbd9aae96c7978e8f, 0x2e3b4f7256ec9b73}, + {0xcc62f85dcccaf357, 0xb56baaa116eae113, 0xd39121b0dcf3259b, 0x46f25e4866044af}, + }, + { + {0xfa220016b44669a2, 0xfbe99bbe5092f557, 0xe04b667a942bafa6, 0x26854edc78b0bd2e}, + {0x93c3a940486a4eb8, 0x74cbbc7bd198d4a2, 0xd64f6e74ed8521f2, 0x80843fa28104df1}, + {0xd544d8f569cb4c5d, 0x9be59548e6b93d2d, 0x65c0c8fe0898dd66, 0x2199702a5841ff1c}, + }, + { + {0xf4502dae36e05405, 0xd06e02b361bd5640, 0x783d406554218c20, 0x2f8b5506aeba914c}, + {0xe3e3f0f92963d863, 0xb3e9c513b7af16e, 0x3248dce06f85e561, 0x257525c4550a214b}, + {0x87b7d8d05103a90b, 0x775220d219e02ff3, 0x930897d4af90307d, 0x14fa87e7b059d3eb}, + }, + { + {0x646e9e36c66167c6, 0x8b8c8990b4cc40f8, 0x2392a8027c056fa3, 0x3468cae95b73113a}, + {0xbcbaaa65cae2ad7b, 0xa381602916655d36, 0x1e74c496a740a52f, 0x3e5d35946fd70251}, + {0x720ef833761a1b2a, 0xd2e1ad032e9ed61f, 0x1284360fc1bc35f0, 0x1d10c1b1e832840d}, + }, + { + {0xf018bd00e4ba7073, 0xc5c912b1fb1f136a, 0x4fa748314dd8ceb2, 0x2a5f7e0ca57c7b77}, + {0xcdf3b35babdc87d5, 0x2475d527ee5ef5e9, 0x7bbb70f05dbf6d98, 0x983fe2aff185429}, + {0x88ab0d4fb8c260a1, 0x78a852ca5a6f034a, 0xd04dfc8b6d06ada9, 0x306dbc4ba1531639}, + }, + { + {0x10dd644c6e5743c2, 0xa2114971e3faae9, 0xd9fbefe6b48e618c, 0x3e38b722e0705ba8}, + {0x46ad6b9283d7e0c3, 0x2e308fb2ac0d8c2a, 0x3e1cb59c2a9f60de, 0x3230c38937f63858}, + {0x77fcd1b48730d90a, 0x388ebff7f7ca5f87, 0xa37bd480d5a52d33, 0x1bee5d4ec9503e54}, + }, + { + {0x9e939970e11081bd, 0x72a0c62c6cf51be1, 0x6e8fd8f7900a914b, 0x36036298567aa99c}, + {0xd6faab04a619d2f5, 0x4a25d62545a6d348, 0xb7ad6f35c22f47b1, 0x1de168bf0fbefdec}, + {0x1345bfdadaae5f21, 0x59e61cc1ee11a507, 0xd8115cbdd6eec40b, 0x139c3f6dd5233369}, + }, + { + {0x58ba96a14e408681, 0xa06d5b071e1ae71c, 0x1a06d51e6e7f692d, 0x1207ba481447ae8d}, + {0xac27f34f246f6412, 0x6419a4c21404724a, 0x5eb99bc09179a67c, 0x251da17ba5f44d7f}, + {0x7c7edb3d3d4d0be, 0xebbd780f9995055f, 0x219149388a5fd89c, 0x46ecaa2536098}, + }, + }, + mdsMatrix: [][]*fp.Fp{ + { + {0x32f4f94379d14f6, 0x666eef381fb1d4b0, 0xd760525c85a9299a, 0x70288de13f861f}, + {0x2ab57684465d1ca, 0xf12514d37806396c, 0x825085389a26a582, 0x308efdddaf47d944}, + {0x1b2098a19e203e93, 0x914dcdea2a56e245, 0xc64ed9aa2aef8379, 0xb176f95c389478e}, + }, + { + {0x8f85e752c76f7c9c, 0x8297f4f031b02763, 0x30e4ea62df5067b7, 0x2821d0423006dcae}, + {0x5cece392cc5d403f, 0x123da1ba8becd2de, 0x193510960c81a54f, 0x1be17f43c42fe5c0}, + {0x65fc36e3c120e5dd, 0x51a4797b81835701, 0x3123b2b88ae51832, 0x19f174900d86138a}, + }, + { + {0xd03df46130dd77b4, 0xe694d8c7d8fd4ef4, 0xf71d2a65470713aa, 0x255c475344778d2c}, + {0x78597119a27f97bb, 0x1b1fb7c15ccb3746, 0xb86d8ab32d6a6edf, 0xb1e00f75148f670}, + {0x875597b15bf7ed8d, 0x73fa4e676bb9cc5f, 0x96babdc32ae359e, 0x31e6d9f5ccaa763e}, + }, + }, + spongeIv: [][]*fp.Fp{ + // Testnet + { + {0x67097c15f1a46d64, 0xc76fd61db3c20173, 0xbdf9f393b220a17, 0x10c0e352378ab1fd}, + {0x57dbbe3a20c2a32, 0x486f1b93a41e04c7, 0xa21341e97da1bdc1, 0x24a095608e4bf2e9}, + {0xd4559679d839ff92, 0x577371d495f4d71b, 0x3227c7db607b3ded, 0x2ca212648a12291e}, + }, + // Mainnet + { + {0xc21e7c13c81e894, 0x710189d783717f27, 0x7825ac132f04e050, 0x6fd140c96a52f28}, + {0x25611817aeec99d8, 0x24e1697f7e63d4b4, 0x13dabc79c3b8bba9, 0x232c7b1c778fbd08}, + {0x70bff575f3c9723c, 0x96818a1c2ae2e7ef, 0x2eec149ee0aacb0c, 0xecf6e7248a576ad}, + }, + }, + }, + // fiveW + { + spongeWidth: 5, + spongeRate: 4, + fullRounds: 53, + sBox: Sept, + roundKeys: [][]*fp.Fp{ + { + {0x6342181358ae2f17, 0x5a321a1614499301, 0x4359bc382232456a, 0x3c06cd69a97c028b}, + {0xc8f709e31405ba8d, 0x2ad4d6aa3c7651a4, 0x64ceac42dd7ccf06, 0x35c6bf27e315e7b9}, + {0x42218b11632afaf, 0x90b0a10532f0546, 0x9e04edfc8863e7f9, 0x1ff6086dc7ed5384}, + {0x16d30e86f07fe92b, 0x49034fc6f7a0437c, 0x7e969951637e0a28, 0x290172d88a15ab18}, + {0xd254d8abb8cde612, 0xd4661c22ac9199eb, 0x512959a2410883d0, 0x35b38913f7bb3552}, + }, + { + {0x49f9638de015c972, 0xad7264c15c3300ef, 0xa62f4865d8c45b04, 0x315e43c0ae02c353}, + {0xb3801cb83df2182f, 0xcaaccf3669280a81, 0xd23d1db585bf366e, 0x116befc5fb4b732a}, + {0x208bcd0d2edd006c, 0x10eb450d1445d24e, 0x430c3ea6421ac01c, 0x2faf9819445679d3}, + {0x7d2dedb966b0ebb4, 0x4209eee542441a34, 0xf0d333d24b06af71, 0x10dedf831bfe44d8}, + {0x382b013bde3a59ae, 0xebafdd87c283d4af, 0x32d9c8ef1bce04a8, 0x37556fb5c9dfe161}, + }, + { + {0xe7016d6ae4ed55a4, 0xbadf50c278ef084f, 0x5f2fc45b67f08884, 0x718c8e8163346fb}, + {0x2d21d77bdfad5760, 0x6ed140b4216a3a63, 0x43b402fb536c00d2, 0xb47d43fb0ea216d}, + {0x36a2aed80574b2f1, 0x43955b0622809eb3, 0x6feacba71072e845, 0x28df76e003ac1ce6}, + {0x95e3a1a7336bd728, 0xd87d937c7f109e25, 0x8ce854afc1645048, 0x2fd788ebb6f37b5e}, + {0x4e4171605858df04, 0x6f56c8c5f323deed, 0x6a570e86d39294ba, 0x6a33164c054814e}, + }, + { + {0xe182b857a075e511, 0x1246b8af401e6e, 0x498681baac02e546, 0x317e99888d6935e3}, + {0xbbb9ff9616a4c70, 0xbd5c5a42104dcf4, 0x92895e7865a8d476, 0x3c40b0adcfe6deb8}, + {0xfc63b58d228c1ad9, 0xb912e4ec588e1a52, 0x601be7d93b9e73fe, 0x1d52635b6bf4a796}, + {0x8defc77d5096467a, 0xfb8b83bb3cee16b9, 0x1498e0216590fc1d, 0x337571eb0ad8f47a}, + {0x8fed932080f3d458, 0x8a1ca06c98c3849f, 0x1644f9415395314f, 0x2919282dc8950b51}, + }, + { + {0x749d4e7efe5fad9b, 0x33b58b4510a5f0a1, 0xce62030d41fdca38, 0x239d5d59f87e0ddf}, + {0x55d59bdcc39fb71b, 0x7c183b304cad27d1, 0xb84182c63c47f121, 0x2469351d6d7b0ac4}, + {0xbe942f1ad599f550, 0xfa1e12f8c552df88, 0x1ce36aa79f22cf45, 0x18e7e49a56a18f41}, + {0x5a85fc171d1c0130, 0xee3b8aebc4fb144c, 0xb7910bda1c5a2946, 0x2ef6a9412227b683}, + {0xe3f397f0634ba64, 0xb24c5da645b804a8, 0x8efdcb393a1c51d1, 0x388a37934aa31a42}, + }, + { + {0xf0aeba711a86d351, 0x917e0a9875d8182e, 0x255ebbbe4e9633da, 0x3edb9c2a8feb51c7}, + {0xf7085a35274435d5, 0x4e859571631715f8, 0xd465913c64aecaac, 0x3df65e7104e3d373}, + {0x95964ef5b04dba5a, 0x86296dcb59e4f8b5, 0x340fae9fdeb8e75e, 0x3c095e04bcd91636}, + {0x6ca87eaf42d54b9d, 0x5efd6b2fd3843e9a, 0x1a9120a05cc3b07c, 0xbb0503c4b83daca}, + {0xfdd237f0786fa203, 0x76e67649a894dff6, 0xcea3a7485eb3522, 0x371ed39b30e34b8}, + }, + { + {0xb9ea58fb107cee4e, 0xea9f1a7f2d6d936f, 0x60883d0bd19662e8, 0x137e698d12aceebf}, + {0x37d5024d477cbc47, 0xbd489bbac329f617, 0x37201ef9b7544c1f, 0x1019235cf42868cb}, + {0xa676a36a225fd2d0, 0x16c1d622bd02030a, 0x71b81aab0eacb647, 0x36af1193dcd5753f}, + {0xe00395d80fc7fa84, 0x2122fd483a170d2e, 0x6786ca04c13fbe30, 0x159d681f1d489146}, + {0xacbab2cc73b4508f, 0x47443d2762112d66, 0x26c9a77344312882, 0xa68b32d6c0b1024}, + }, + { + {0xe5943e9ec5816b5f, 0x78f97275cb9e7f63, 0x28d993db0402e6f5, 0x35023474a298a50a}, + {0xd5f6f7304d58bd86, 0xbeed688b64192acc, 0xd7211bea14f1a406, 0x24f92d631c9c4bc}, + {0x6952a1fd17d693e3, 0xc04dd964f234b8cf, 0x7caf0fe8884ef070, 0x1c1fdcd698bf94b5}, + {0xca8b6804ac41ba2d, 0x81794823bc0576ff, 0xd4a19f41722a0f09, 0x2846565f83dc9972}, + {0x51ea8b6d4a20f06e, 0xcfc9a709b77cbe9d, 0x30ff8818851924e9, 0x211d3ce41b7ee763}, + }, + { + {0xff21fe3230917894, 0xab2870fddeb86f88, 0x62e4a41add2270a6, 0x15884194ae363d14}, + {0x4a6fb13b70e67a19, 0xc5247d0dba887080, 0x31b4c6c5e685c605, 0x2e9f9208fcc2515a}, + {0x1c90f4fb1e0414b4, 0x8ff65aee4323cf80, 0xa13dda064773ad4d, 0x810a513ddf12c38}, + {0xe053ad98a6ec9bef, 0x39b9faf0e080b472, 0x818c7ad0f950eae0, 0xf1cd4227514673}, + {0xd196b25dc683b945, 0xd724c2ad624ad4a9, 0xa02ff7daa5b740a1, 0x15d55dbe3c7b4e13}, + }, + { + {0xb315a1ea41fe829c, 0x18713cd306622126, 0x6118592ab4ec0503, 0x3ed3f347d4db5134}, + {0x5975228afeaccf0c, 0xfe4e4239b60b0efc, 0xc9cca90df89e496b, 0x230f526cd9442560}, + {0x5a49f311ef676e8a, 0xad7cb07e3ed9efad, 0x2a417082abc3cf1a, 0x21601ac12eba703e}, + {0xdf338b83df06f68c, 0x63cd7cb53f8cdce4, 0x1f0fdaf0eecf7ab6, 0xcb74130d7ea6889}, + {0xd99c453addc57eae, 0x2e5ca7b4ccd548e9, 0x1d61848bbc4141ef, 0x1502dc917545edad}, + }, + { + {0x31688174ae3a3088, 0xc2f2735e215a8858, 0xe021199a3e4ad81c, 0x3c3a13210a719854}, + {0x5cd766b0b1aa7928, 0x9469f3c1ab1f06d1, 0x23c181781a8a1af8, 0x669f23736966be7}, + {0x5e43af558f0a0b, 0x7568a76e8644aa47, 0xa49bfc0b2c3a0969, 0xdaabd0e2866cfd8}, + {0x3f57582785bde7cc, 0x95a273aed529176e, 0xef25328aff37a9e8, 0x116b8853ab55ee5a}, + {0xeda91d71ffd7b2a0, 0x6efe645946126c4c, 0xe9f09dd2a7027804, 0x387a2c92b4e648d5}, + }, + { + {0x64ab4aa2e9f0aff2, 0xe966eeaf6883d60c, 0xb94697e6a3a0a4df, 0x38f0fc799ed7a14a}, + {0x1511dd33c4afdbf3, 0xe36ee2b5ffe811cc, 0x505a5de39ec98985, 0x3df8294a06678e64}, + {0xc710119f6242f55d, 0x2466c6cb6d325477, 0xb1774657e651de5, 0x310d190e78ee5dfd}, + {0xb1e6071ea081861b, 0xe92b3ce474295159, 0x77456109d94dc351, 0x1d893fd638fd7a1b}, + {0xc782a16511338c59, 0xd18c9bc3c41203d7, 0x847badef6c2b829f, 0x126c269e06a4a430}, + }, + { + {0xa0e7271d058e1b65, 0xc29f191eed5dc914, 0x89207dbde1650706, 0x1bd2a2d62a9947b2}, + {0x6ae20ca1c2d65d68, 0x80f9d7daed9c8c8c, 0xad5cf3b156b2f1de, 0x509f8b72998a87c}, + {0xb03a6b97357d97f0, 0x593eee3fbeacfe95, 0x9fee173d856a5b7c, 0x133fc88ee7b23b27}, + {0x4b9a0736e24a0f26, 0x405d5a665f66fbc4, 0x4d4d5268d0b8b9d9, 0x3238606d9b26856a}, + {0xd073bfc69cab34f0, 0xb4133b646eb1841b, 0x10a149c352b6f7df, 0x20cf915f29d33c57}, + }, + { + {0x307d2b8cb0fd415, 0xc8319598907073a4, 0x6b773db66a05a6a2, 0x33e6c0d1d806c5ce}, + {0xc08315afa7ec4292, 0xdf1042b5d5054c91, 0xa610476590769545, 0x354676a843acb066}, + {0xa1c7c9de915601be, 0x69cadc4f1bbf31a7, 0x47661b8d743f21e, 0x2939e4566b8e1260}, + {0xf8166d26b5875ae8, 0x391c8625906a68c9, 0x97a671ae3e7920b6, 0xb62d4ddc6a61f73}, + {0x5b13bd8369bec282, 0xe2ea0c100e5347a6, 0x2d9c57262923cb1, 0x1e31165d6dc07d45}, + }, + { + {0x3df3f3bfd54018f2, 0xca762a746d00043e, 0x25022728a3503107, 0xd5efa7f874457bc}, + {0x613e721107b4b48d, 0xf10823eec3d12df3, 0xeb54dfa62698b875, 0x243340259e551904}, + {0x1ce630ba8530b2a4, 0x6f5eddfa4f7ddda2, 0xdffb5a531052c7b4, 0x3c6b192f75dff4c1}, + {0x8d8f971036624659, 0xebd0ccfe39e0803e, 0xebdcb61a65d66931, 0x21868796aae7a40b}, + {0x22e12b186fa512c7, 0x4968f02a800e1ecc, 0x4725f2ec01f4b71e, 0x28e74c6a4f22fcb9}, + }, + { + {0xeffca0f81d56aa11, 0xcb0ae88503b5be82, 0x69b43848fe8e74c1, 0xf0b271c54f3b2a3}, + {0x23db18e63a2414b1, 0x7eba0c1ea4e2d784, 0x72108a3064e1a124, 0x138c36a9897505ac}, + {0xb93afa2c44d2b18f, 0x616aef5e3ec452fe, 0xcb15eebb579916f7, 0xed9d9c3d23aaa60}, + {0x19c722ddc6d11a6c, 0x933aa7e601881608, 0x3d680c98391faed1, 0x2809e56840f1eca3}, + {0x682adeb5d9a53026, 0xcdb02ab94f3e9259, 0xed7adc874c00a2d4, 0x1764188e52d76c52}, + }, + { + {0x2cb2173bfd2a8b7d, 0x742418360f62a8f4, 0xffa5daf7a2f06510, 0x2622bec30f05eda4}, + {0x956300c0a931ef90, 0x3e8dcd122d9b3016, 0xd77959f2fba021a4, 0x51f68f4d9b5836a}, + {0xcca7550f4e2663fb, 0x3a7115aac8cd273a, 0xfa9108f48b6ec0f7, 0x2eb9ac59d63b2756}, + {0x25c658fd552f8699, 0x24c4b27a4de55c10, 0xf2a39825d38a8469, 0x261dc2c828f9be1c}, + {0xf33c05063dced35a, 0xb0dada5d213d36ea, 0xe1a0c81f1f6ca22f, 0x3b5ea3d73588bcf5}, + }, + { + {0x5938e55ad487efbc, 0x65ff0bdaa2002589, 0x24f12d149cfb0ad8, 0x2d7f7be151666e78}, + {0x832fab7224860b2d, 0xc9f4cdbadd955fa2, 0x4aedceb5506c2655, 0x1c44fa130dd1ecc7}, + {0x7d034b1f6a58ddaf, 0xf897b22ef62bf04f, 0xd973ac696faf14aa, 0x31548d27d817dbcc}, + {0xf89844128d9c6ae6, 0xfc4cfe0229c7aab1, 0xac2b0c7d97647680, 0x1e1d5254aa0782f9}, + {0xe8c1dd74ba3631f0, 0xd81c8d077b5a6f56, 0xf3294e721e883318, 0x380d3a1eab70459b}, + }, + { + {0xaba511448d72ecf, 0xbf82f1fdf1687a8e, 0x6313bb88e45ffa56, 0x2ae425e1e1234cff}, + {0xf4a6807d301a531f, 0x96429863d70e0604, 0x15bdd9eae828ddc7, 0x31f0f80173fe31d7}, + {0x3a6d20e8dea8c483, 0x2adca6c88e7509ef, 0x48b1d6d05be6c961, 0x35053945aa6e5402}, + {0xdc5f96bd86658107, 0x5aee32dc2a32affb, 0xe200cec62dc0d495, 0x1055b57944bf554b}, + {0xe1ca0c53b24b06d, 0x528de276ea0c8c5e, 0x1c7ffa0b483f3002, 0x1c72f58595847427}, + }, + { + {0x26a28a08b5b246ea, 0xba3b8d9f4f4b0f41, 0x99c9ed2c1fcf4a3e, 0x58070c1e7b659c5}, + {0x7aa8e9a2d203b7f4, 0x9acb8ddb590fc9a0, 0xd7cf3e5554e162c, 0x17769ee1912d75e1}, + {0x6c6901252870a99d, 0x9a4108b035e55928, 0x297dab35f2c77cae, 0x31f2978ace0f7e2d}, + {0xfcf1119abff1e989, 0xe8502332327be648, 0xa8918572496177c5, 0x1710468c2227c8d6}, + {0xdd2bf9131735dd76, 0xe43ec3b817349505, 0x61ec884ee479524b, 0x377c72d607beacc5}, + }, + { + {0xa9bef84e0b68b0e8, 0x2c4c8f2ab7b0c9fc, 0xee234cad52493f69, 0x1c5bd50dc4a1fced}, + {0x57f989e88a97334c, 0xf99d4d667c1b859a, 0x64164c1e8e48da1b, 0x36b841653e8612c5}, + {0xb55c8effbf87f8d8, 0xe15c71abf8372eb, 0xc606d853488806ff, 0x2c6be0beffd5a9b3}, + {0x97235a2b7f573c80, 0x8f5053ff091130d7, 0x201611ece80cd2e6, 0x22498e90ad20fd7b}, + {0xb25923ea87f4f825, 0x1faf60a8b1d87720, 0x1c480f9378722c18, 0x187ba4d5f603542d}, + }, + { + {0x2553e37a713a8650, 0x4af5a87c8bb53cde, 0x9470f8df7dc4e62a, 0x1147db739156a158}, + {0x7a58fe90b257b6b7, 0x8ee9df6553d968a9, 0x85057b2342c19359, 0x3ca66ad9e8533b29}, + {0xebe091f37f855e8b, 0x78312923a64e1e08, 0xf968ab79c1cb96b, 0x84c6a2f87e5877d}, + {0xd3393bcf45ec7f72, 0xeebaad3d085cc500, 0x8dfb7b13fe964753, 0x29e0048c6a967c5}, + {0x6ee6f52f14c5c52b, 0x51eda970b620a200, 0xe1239122e1ee6ed3, 0x20241311a411c6dd}, + }, + { + {0x3a632070a61738d0, 0x58360c4de1248c90, 0x2007e0611a3ddc78, 0x318e43c7104b5d29}, + {0xe11a8859f0b07f43, 0x22423a78bf5d6ce7, 0xfe8417dfe2f81f05, 0x2a9cf2284ea93e6}, + {0x3c682a7371dae56a, 0xb537b6fc7564fea3, 0x4c8c6573f55fa435, 0x152489488b5a1639}, + {0x3cf49703bdb0de0, 0xf828bf910f380e10, 0x8fb14d900fd140d1, 0x3f6cf44c3e3ff6db}, + {0x7b70aeec460c3296, 0x2afdb7b9dd091761, 0xe5b3b021d8f70e09, 0x1f75fbbd77a4b405}, + }, + { + {0xb824cf8de5beaed8, 0x70a7fe173b87433b, 0x1a8efeec667f72e4, 0x39565d2fad0c609a}, + {0x5cd0203a1d4f951, 0xdb78389b84917080, 0x6c4c97504ab70cd5, 0x29cc98e95cf64495}, + {0x6bc75c72ecd52b50, 0x33afc1a9068b1413, 0x33daf830e0a55f27, 0x71875230561158e}, + {0xb19ed2b87a280098, 0x1e9ed62c5d6a622e, 0xf1c47cd609238e2b, 0x88c1888884476d}, + {0x69ea31042e6e347f, 0x9bb2a44f8642afdb, 0xeccc2d81df513162, 0x3af58f661fb1f19c}, + }, + { + {0x46713a78770b8c85, 0xb3ccf0a4b425690e, 0xc65beb7710375cf8, 0x1c83ac2e75d29e4e}, + {0x8df4d89a09fbc390, 0x4d57e4b593fc2239, 0x94b4e16defc746d7, 0x1e00fdaba6801cc9}, + {0x62d3e199fefcf465, 0xddfca365e5282190, 0xadd48dd560275162, 0x250a1b6745f9c2a6}, + {0x935e7ff4c5ad3690, 0x931629e4dcf656, 0xad870e5416ca92d0, 0x2d2002e4c1a7fb42}, + {0x3020c37bbe98a69f, 0x3bbbef2df0bb0743, 0x735468317fea682d, 0x3bb75622e8ae0e5}, + }, + { + {0x6d101c64f48442cb, 0x9c4d0d7cabbe37d0, 0x6e457716d0cc5c54, 0x131685a66db0333d}, + {0x48bcf6f7121dc6fa, 0x44ea62ad25ddb6aa, 0x8636e258625c8e02, 0x171b08836f73a4a4}, + {0x7b5d53163078c6db, 0x79f022d48797b027, 0x8a6611711def9ec3, 0x281eb0327e36241a}, + {0xe807c130c139b23f, 0x8bd55fb76af83b50, 0x2917722317575e1b, 0x8f90e5cd2c3173a}, + {0x4759babec3357d26, 0x265b8a66badcbb36, 0x44df217c22db1fd1, 0x23c7ef2b68b42cf3}, + }, + { + {0xb6a7c51b7ecb6bc, 0x4d1ae5944bfbeed8, 0x864b9db1caabff7e, 0x39f90ff79f187276}, + {0xd1969a2901b910c2, 0x67af6508acaf97a2, 0x8380c23a59ae6c60, 0x271d877b5644c4a3}, + {0xe17e8fd5a391261a, 0xab17b0e6a4632c50, 0x1c3e97e07f259c9c, 0x2d07bd641a6586e2}, + {0x138aae9b3cd42fb3, 0x81f64f590fb78cb4, 0x885724f615f7f233, 0xa63fee53381d1b6}, + {0x2ec005773e160199, 0x475ef3383e134dd2, 0xce774f49e51de44a, 0x36ef885cefb664f8}, + }, + { + {0x37420d26e384e4a8, 0x1742df50ce970b26, 0x99f3ea60e2297d13, 0x291cc0cacac121bb}, + {0x59992f7b95d59d06, 0xbfbbbce9ffae7ef8, 0x230d4b9bb86868f8, 0x135612cee5c3cbf5}, + {0x6ab6b33ab48fd8b4, 0x2c46df90b0bdae8c, 0x31e33e7cf970f45a, 0x36c4a50b91a1475a}, + {0xaad1c48efff98a5d, 0x7a478e439cc52346, 0xb77125717607cc5d, 0x24c45ff83f2e80a8}, + {0x5103153d6fdd5dfd, 0x45b61844136521c6, 0x41c397561d8772fd, 0x1ed1ee06b89dbf2e}, + }, + { + {0x6c5059eebd2c5991, 0x3d6cf236df839e48, 0xd92711e12b52886b, 0x29829fb71567bb3a}, + {0x771a7702e2a54d3a, 0x29b8e99e7644939b, 0x3d453254475ea815, 0x2e5f8163d03b6cb5}, + {0x263df2c33bcdbc46, 0xfed7cba7787b1a36, 0xc315fa3c16682da4, 0x2ab983af9d9b6f25}, + {0x8a0353e693c8e2c, 0xbe92370d0d219261, 0x723aa4237242dd57, 0x25361783d1e56fc3}, + {0x7e7de67d78a9ff19, 0x83c2d2fd23156a32, 0xe65e5d243aa459b6, 0x35813f92ed31f777}, + }, + { + {0x4819c016f5a5c698, 0x4f72e64273a5868e, 0x61751f954f65b95d, 0x379db14ab6232b32}, + {0x5d8d95a7f9270b96, 0x61541332ec3b7a2b, 0xbf5b05056d41baab, 0xcaf69513fccef00}, + {0x966ebe56652901fd, 0x3d01e1815a5244ad, 0xd62a7487593ee708, 0x5f1ef41b294e025}, + {0xda81a0814d58ed14, 0xe5824bb0a3739516, 0xe559c39f79e50e7f, 0x3cf706e11c52afd4}, + {0xb07502481fd9ac00, 0xbe85d565f578f9e9, 0x25e2168d537c5428, 0x1f8caff53a89afab}, + }, + { + {0x67ef0684d24ef4d6, 0xe479b8723faeeb8a, 0xed152c7174bce1c6, 0x2c3879d3206619b}, + {0xc0d0b18f192aac4d, 0x8ff92db980036473, 0x39a88f384fb77d28, 0x9fe5e9d746e308b}, + {0xf10d5629175358d0, 0xa258ea27ec17d224, 0x3730ea6667ba6289, 0x1f8bfc64890f7e59}, + {0x5f8c12d96d37065d, 0x4d7ee138862aa83, 0x4a18488a63ce6118, 0x1930781a4f270e4}, + {0xbd4453cefd9ebc0c, 0x14827cfda7ed7ee8, 0x3dd6c45400957559, 0x33c9719ccdaab5b6}, + }, + { + {0xed0c855c5de359df, 0x6871e8f1798b7bf5, 0x3803b19eb2c1f511, 0x1b88826bc36516df}, + {0xecec6a0bd180a9c0, 0x954e9adfdd68e064, 0x323c890828d78811, 0x2c89829ba7ac7fe7}, + {0x623862b5c28aed0f, 0x544fea8657153f5f, 0x41139508c925a0b2, 0x10d5e06354bae812}, + {0xeae3b52c47a3ad31, 0xa40c52de4949ba9d, 0x239515052b2d0bb6, 0xc68f2ca20bfa5a4}, + {0x86da286806879c23, 0x2bc62129dce2d327, 0x8f8f1b3f3a607809, 0x257de258bba457f3}, + }, + { + {0xe55015708a8bf114, 0x8f7b7799abb7e89f, 0xcb8fa2a6bf9b602d, 0x1dd3b45e4f2bd1e9}, + {0xa48bd0f7b831b6af, 0xbe6ed2ae7e9b5ea6, 0xecdd091614986315, 0x1bcc64e2d4434539}, + {0xee95991ac731a5d7, 0xb643176046b51d45, 0xf396998dc25f72a3, 0x1474b46564931dc3}, + {0xe8973ad2df550e5e, 0x8561e0de83378bad, 0x90495ddc20bf8d64, 0x2c8ee5b7e87d23ea}, + {0xf15e8598d3360040, 0xd9237d9f5bd4da94, 0x2f32ec74a0b7cb8f, 0x2bfa790791857d69}, + }, + { + {0x51ed3818b8a671e0, 0x93f8de29901b0101, 0xdd6948f429d84a64, 0x339864f118ba5599}, + {0x8070718964c6881, 0x664a56735cd1d096, 0x966ebb68ce0c59be, 0xdb44ab4420ed185}, + {0x390fdea200fe8c8d, 0xb9ddf1781fc7dcfc, 0x6ccc8d97ea91a52b, 0xaf86429842ad1ea}, + {0x6fbc15b9f8ee61d5, 0x485407282205ba19, 0x9f2b3a9eb0762424, 0x1167e61f6e4bd42e}, + {0x9b2e606d2a12a53f, 0xfe4ee2337eadcc76, 0x97152598ff76e36b, 0x275e80f05a7648b6}, + }, + { + {0xc3cc461cc12d86e3, 0x48b15302057c1d0e, 0xef7a34bbb6748beb, 0x286c7795696d139}, + {0x337d4ce46c81b278, 0x2e5feb77948c70d3, 0xd82b4f43ac0ebab0, 0x23a5e817dfdebe91}, + {0x2ce1459a01867e26, 0x224b53d8806aa3a5, 0x1bba8ab295cb47f5, 0x6cbbeb19cc3e900}, + {0x1774396945cf1d1b, 0x325ec3d335425b6b, 0xdaf58659cd291e5, 0x3f8cfcb73cb1aff7}, + {0x31812080ad76a765, 0x76b57d46db21d506, 0xa9f0b894c076a2b, 0x6328153e24ddb21}, + }, + { + {0x635e53a6c9b16d33, 0x39a4746bf0a3364b, 0x61555f31318c6ae0, 0x3b775cd07e4fa0ba}, + {0x2cc47754e893144e, 0x76f56441be34ac0c, 0x580502c5981f6c05, 0x3f1912d87eb51724}, + {0x4ead108af1a4e97c, 0x14ed7a0fc16f0e1a, 0x88a0cf37b2ee10aa, 0x13aa67b47ce7c7fd}, + {0xf54922d903cdce93, 0x825eb6a0321c91fa, 0x6d71f23e5b2a77ae, 0x31d82d03cd7ef1f8}, + {0xf6c8ba6acea0c3a8, 0x3dcdacfe5ace7aa0, 0xbbbff1c714c8bbcb, 0x26b4c61ca5f05c8e}, + }, + { + {0xc2bddbeee6db7663, 0x5de993fdf4bee2bc, 0xc5598a002460bb6a, 0x195ed57ac7350182}, + {0xa3c22c35da970f5e, 0xca1c98fb8ebbea38, 0x1fac0f5c50dfc365, 0x1aef8ca61af69bd9}, + {0x26e8837fb91809f1, 0xf9688f1eec8f7e7e, 0x610d6fea8d7fdb89, 0x3d0a1bd4d427b4ac}, + {0x4805ec51b5a8b95, 0x35841575c48b553f, 0xefc86563cec776dc, 0x2840e92680329f35}, + {0x88aadc874b15e054, 0xf4c407659f438e86, 0xc78f11dc3ac39010, 0xe83c809dce62ea5}, + }, + { + {0xa0d5b4ce25ad95e3, 0x4eb48fba265577ca, 0xec34d547e740b067, 0xf87455a1a87a825}, + {0x7171a3dbff618247, 0x8f77af4f143160e8, 0x639543558218623e, 0x1ad8547be9074db4}, + {0xa0dbdf918c38f312, 0x62d083dc471500fb, 0x5358448cc9aad1d1, 0x5825571f70873cd}, + {0xb9c01a42ad74f7f3, 0x96425e46aa40f166, 0xbc305b6f8c2ca3c1, 0x38885a0e462a0d16}, + {0x1f3b4561c10caa2, 0xe7f7e2edd641ea35, 0xd946c46002ec9b24, 0x22dc4744611dfaf}, + }, + { + {0x89d2596131b9d801, 0x6d61479c7e6f6d9, 0xf5aad5649f5a1c79, 0x225393c033553d15}, + {0x5b0fdd7cbea91565, 0x95e46f19a0dffebc, 0x91d50f19a3a46071, 0x2c03ec2d9ea3aaaf}, + {0xdecba3c94506fd1b, 0xa07f4c4397072961, 0xc072d04541ab3761, 0x250beb5d4be1732e}, + {0x9ce4550f36a82208, 0xad906f79c2991285, 0x82adb87da0fe9206, 0x34aff80145dc173b}, + {0xb84407732055b44d, 0xf9c85a0309677606, 0x1816b1a6361d2c99, 0x302b805797745fa1}, + }, + { + {0xbbfbaa3655132a2f, 0x85de63edc71b8169, 0x231b387734b227a0, 0x791e6d7e390ab58}, + {0x846a348eee728261, 0x91e35881244dcaed, 0x8755e3179f39f84, 0x11c757c8adbbcee2}, + {0xdc5b85ce4ff2e16, 0xe6680a9d77d56b79, 0x2e1d8a190b81a71b, 0x110440e7f341ccbf}, + {0xc5714f4e64e4f5b5, 0x9073123174ba32aa, 0xd1aafcb808fb13a9, 0x2b0bf27c449467b4}, + {0x674d2c9c2a9f6c33, 0xd64a81fc8872e544, 0x54da3af1c7ea91f3, 0x22bb7d2c8479681d}, + }, + { + {0x5ea26e9a08f957a5, 0x531b4a8427d261c2, 0x92a9d9e3c38cfcf0, 0x2006044428827241}, + {0xf0834849c1fecda7, 0xfab565ee5f9319d, 0x3a3b976275b87643, 0x2bc18d1039d22ce7}, + {0x7ad9bd18d3ef9d11, 0x136c2bdc157de581, 0xf1999edaa1f99ec6, 0x3bdb875af3652fea}, + {0xb06ff1fa4faa6be7, 0x7b65a2d09d62e6fe, 0xd52851aa16d4a33d, 0x3b7e6a651e5f1100}, + {0x70b297d3bd617bde, 0x42dfd73b30a28150, 0xbcbc0b930ad9480c, 0x14452569cf1b7495}, + }, + { + {0xb997f89dc4f23510, 0x86aeec894d2eb890, 0x40b5eb4203777c22, 0x3f6900dd45610c9}, + {0xbed1fbbc558ae3b9, 0x7b9919fc76fb8f31, 0xa8155c8d8f223d05, 0x7be199f23efc89b}, + {0x124bd2f29dfdfc99, 0xa3cd06dc334c28dc, 0x8321717bb314584c, 0x7a90593068a94cf}, + {0x6d262cbbd1c3c7a3, 0xfa55dbcbb37ab4e4, 0xdfb0541244749109, 0x1b42310efbbc8ae1}, + {0x159b02d7b19c8807, 0xa3155c41a3100f0b, 0x649691f59c73a27d, 0xb1c6cf5eaa1a3da}, + }, + { + {0x56a321c5d5620a4e, 0xd704e017be94ce48, 0xbb7e58300ff6e106, 0x231353460278eda6}, + {0x7f24d9a9e896902, 0x379dfae44f3dd605, 0xa756baa38400f59f, 0x1ca15e781769cff3}, + {0x3b1d025a762cebf4, 0x9be99c300caf395, 0x1ec3a4ee83fc2b9c, 0x1db9c130790aa77c}, + {0x92f350103a625f89, 0x7f7abde4baa7fe7c, 0xdb4ce7149975b21a, 0x37619aef93207815}, + {0x2df14ae96e32f360, 0x8154a50068c1d6d7, 0x3696523ff84dccbd, 0x3d71103fe9b7d2cc}, + }, + { + {0xdc8f123847c2f6f0, 0x772b9f5f133bb07a, 0xf48472df2de5637d, 0xb30587972382d91}, + {0xd32076031e6caf, 0x7a70c0a191315b1, 0xc72d68ebbd493f22, 0x26a6b863263ca385}, + {0xd1ad7a8f3f52bc58, 0x7fd97d9102a5e717, 0xdc4dea9fba06a94f, 0x24292fae82eb3182}, + {0x9c8f6b9aed0c14a, 0x7ce6499a8da0ffc5, 0x4c575abbd55a091, 0x2ffffd706225c6b5}, + {0x51ff57474553fd13, 0xbcd2c2f63e851309, 0xad42d629fbc07620, 0x37cb8a314456dcb3}, + }, + { + {0x9e725f4a1ea322f0, 0x51275d226f5fc65d, 0xcc96b5ceb521cae0, 0x31697ac9e08fd09a}, + {0xfbbfc3ed25936e24, 0x885d8e71956e9fbf, 0xb8e0d819be1b2b0c, 0x2a27ec07450706e5}, + {0xb86f23d85d56ff2, 0x25630952048f156b, 0x96949d2297030e85, 0x28ed6be9457a4c1d}, + {0x85cefc2d5a4254e4, 0x93335e124a410406, 0xe2caa252d7d83ee, 0x206bb8d1b294acc2}, + {0xaf3c9df6a0ed5396, 0xce5b0093a6e41bfb, 0xdae7d2b6669cdd65, 0x91670d7e0c906e}, + }, + { + {0x848e19c09bf3ab82, 0xd37733a864fbf5b1, 0x5834568186cadc57, 0x3d8894b3840c836b}, + {0xcb24e184ea8d715, 0xdde18b32791992e1, 0xc754f597613dec6e, 0x124ddceb631af8ac}, + {0x200fede77fe9ccaa, 0x4120a35be4499eb2, 0x6bcb74340da3069e, 0x18d40006660a4d9}, + {0x8ccd91c1dc2b219e, 0x1dc15dbbeee5b7cc, 0x30e961143289ebc0, 0x33aebd15476f6d}, + {0xd4c03228e1165ff1, 0xe755127566374ca5, 0x5eb5e5f7835f51b9, 0x11d1f3f590664116}, + }, + { + {0x1c2a43421f2b006a, 0x6258ea61fff6649b, 0x5a847a0bdf1ff16b, 0x2038498881736f80}, + {0xe603ee6ce8b0bbc6, 0x620a0a604d315efa, 0x40378c0521e6518d, 0x2d4d8c63bccec23}, + {0xa77ca49f7f8b90ff, 0xcb7652bf1a0cf5ea, 0x3d911a1c6e5c74c3, 0x1a8c15f40c9e99d6}, + {0x293a2d7589738448, 0xea4c1d5f407e77d5, 0xee7f4d7f7d8d69f0, 0x6d9a037bd4006b5}, + {0x7e0382dbce83b459, 0x8210fa8a33a15c2c, 0x4da8c81848a7e20f, 0x35c902f371d587a5}, + }, + { + {0x3d331566c2c6c483, 0xc66d7c43cf6c6899, 0x7c1c36147e850129, 0x18396a316e009c03}, + {0x16d27bc62b29f952, 0x65a7c24e59dc8b05, 0x5c0acd2a0f886241, 0x15e74885451d7b84}, + {0xe3a5b84fbaedfd4b, 0xfd3304cb4b735b85, 0x8d8df8b6031ccd91, 0x603d2627ed921bc}, + {0x194cd2aa6240d213, 0xa3d4d947c6027d50, 0x7355e133684d2417, 0x3a4ad2ca80689906}, + {0x754062c7dfe10fb, 0x15be7881422ab514, 0xbd3cb5e4447b5b04, 0x267919778e6db957}, + }, + { + {0x9e687a0099aafbe4, 0x8716f500deb883a4, 0xc7c44b3a4227e0f9, 0x36dfbee5ac583fec}, + {0xb9c5848f3b063542, 0xbd7beb77de16d02e, 0x6ed1369422f1597f, 0x35cd85390d4f063e}, + {0x50a256d280092fdc, 0xd2c2b4dbbb258e39, 0x9c6679aa1c4480db, 0x383efabe992c0d62}, + {0xb8fadb8a950482a8, 0x6279eecfb927c631, 0xf8b75e3cffc23fbd, 0x239433b63ac65264}, + {0xaf95feec451ffd03, 0x7ad4f5520a280f0a, 0xfb6d86aa8efee6c6, 0x5ad99e8a107bd86}, + }, + { + {0xd47e6d75a1e72978, 0xec21efdeed48fc4c, 0x3f95628431615152, 0x321e3149a1bd5bda}, + {0x366a1936303c4a03, 0xda1980c0a597dd0f, 0x2fddc599df0832d5, 0x10090314b014c0af}, + {0x9af98513b8fa3e32, 0x76a99773a39804d6, 0x49ed6650bc0128d4, 0x34fce51deddd27d8}, + {0x29ccc4a9b0c2b010, 0x8a8f514b705229fe, 0xc1e6d12b311256f4, 0x3291611fbb2fab1e}, + {0xcb4ebbb08bdb9c9d, 0x744ebe7f914218fb, 0xe77c5babcec8a686, 0x2d42a41428a90175}, + }, + { + {0x8ec3d97ab5616a9e, 0xe8014e7c1141e6ff, 0xa8daca3054309538, 0x1c08ef18d73c76fc}, + {0xcf92950eb4f3789b, 0xaaa450f22a280bf6, 0xc9e4a80c9f2cd996, 0x27f4ac96508752f6}, + {0x7bbd2ed16a76edc6, 0xd8e2186c7de847db, 0x2aa88a2b65118dd0, 0x1c55b5f615dc28ea}, + {0x7ccf57f28acc118a, 0xf5d3c6eb14e65154, 0xdc079fcf442a0f54, 0x11993cb931932e5a}, + {0xf76b4a8906e70667, 0xda7f02e1bf4e36df, 0xaab6b7f1de20dd0f, 0x19fc46ff2ddb173c}, + }, + { + {0x3a3d2dc8cc132eee, 0xf357bef4e1d3a63c, 0xd48a3a0eb2bc1415, 0x2bc75acfaee9db1}, + {0x5fbb66b806674243, 0xf73af3e558a86209, 0x5d30fbb40ede547c, 0x501e03ee293fd1d}, + {0xe90568a8237171ac, 0x650fc27c4da7f2e3, 0x546a3b7012993072, 0x87e3d6d0e54850d}, + {0xd5dfc1afce8127cb, 0xc6874ecb5b959056, 0x17d19ee832e735c7, 0xbf09138a8fe4ccb}, + {0x489c20a8f79b4f58, 0xaa9a7c84d23aedd3, 0xb66eddf614963ee3, 0x2dbf9ab7c2343a43}, + }, + { + {0x3dfd42b46f1e6946, 0x58f29edf399435ba, 0x2521d4287bc79d64, 0x1781fbca8872f93c}, + {0x6d6aed7cb045289f, 0x44132433ac541a78, 0x660c1badd4c7e0de, 0x30330b4022cfe5fa}, + {0x31b90687198ee938, 0xf9b1217c09a47868, 0x1df6bdd931eb2b30, 0x151f40cfa7ce6982}, + {0x9049df43bd2b446c, 0xc117a3d9f6656367, 0xfd356803d03495d8, 0x200e3c9d4c1b8eb8}, + {0x90d2cc13778a0928, 0x9b7d207f836f7d68, 0xac2d328e8bc0cdb3, 0xc70770d5c26e2ae}, + }, + }, + mdsMatrix: [][]*fp.Fp{ + { + {0x32f4f94379d14f6, 0x666eef381fb1d4b0, 0xd760525c85a9299a, 0x70288de13f861f}, + {0x2ab57684465d1ca, 0xf12514d37806396c, 0x825085389a26a582, 0x308efdddaf47d944}, + {0x1b2098a19e203e93, 0x914dcdea2a56e245, 0xc64ed9aa2aef8379, 0xb176f95c389478e}, + {0xf895153087f5dca3, 0xa53543f74c7e98f, 0xf5a0b430a14b8c2d, 0x6ae54007a872b0}, + {0xfd0c32f86be981dc, 0xf60dbc5c1bd0b583, 0xd4f3f8f9a2a4537c, 0x1d71b70d52f42936}, + }, + { + {0x8f85e752c76f7c9c, 0x8297f4f031b02763, 0x30e4ea62df5067b7, 0x2821d0423006dcae}, + {0x5cece392cc5d403f, 0x123da1ba8becd2de, 0x193510960c81a54f, 0x1be17f43c42fe5c0}, + {0x65fc36e3c120e5dd, 0x51a4797b81835701, 0x3123b2b88ae51832, 0x19f174900d86138a}, + {0x6d0db66a74936d4b, 0x1b8aa34d8d4554ad, 0x8605b5c1a219423d, 0x3055d8d876253885}, + {0x9b8b22118b0179db, 0xe14da53ccd481770, 0x109e7ae5ae61278d, 0x13cd85bd55c2f52e}, + }, + { + {0xd03df46130dd77b4, 0xe694d8c7d8fd4ef4, 0xf71d2a65470713aa, 0x255c475344778d2c}, + {0x78597119a27f97bb, 0x1b1fb7c15ccb3746, 0xb86d8ab32d6a6edf, 0xb1e00f75148f670}, + {0x875597b15bf7ed8d, 0x73fa4e676bb9cc5f, 0x96babdc32ae359e, 0x31e6d9f5ccaa763e}, + {0xf27e0f92236fd303, 0x6e607a16f84adab, 0x4cc8addf91894557, 0x1fb0a70aa0f1061c}, + {0xfd2a420b19b31725, 0xddc5361119d53b6e, 0x3d58af3f6737f156, 0x1350a7bb521c58a6}, + }, + { + {0xf88f2f863cb9d6fb, 0x5078f8e89e8f9ff9, 0xc5583fcea6176010, 0x25e363acdb694459}, + {0x2ece0c297d2f49a2, 0x9ccc88a13c91abae, 0x4138c965288c3d87, 0x437768eb72dfb4f}, + {0x9fab22e085f93fe5, 0x63ca08a361b7fb0d, 0x7e9790bf5bd5837a, 0x6080ada873c8216}, + {0x32d3b34d8c43a402, 0x2c7e5748fb940669, 0xc0a36e42a28c6f80, 0x24ac3e6b181bb185}, + {0x470f7d02d1dae46, 0x8cf3cde540035d00, 0xe3c0216f8d5d807b, 0x3e3e8312ef71fa39}, + }, + { + {0x6682f4469913559f, 0x3b053e58dc4560d6, 0xf84c58444b5bdccf, 0xc3230d834c17967}, + {0xbff2a45de17e9da7, 0x6309bfdc8e152f51, 0xb9ae2f9af1f30a1b, 0x27a8797c59f97b06}, + {0xd787c4dd405d1b3f, 0x7da8effab83f1842, 0xb3f8303ad313dac2, 0x3a1a7a3002e72833}, + {0x327b7f748a0695fa, 0x7dde58a92f496b95, 0x8a02b6088016449c, 0x1cef42b151422c3d}, + {0xb22ffb451127fa1a, 0x3c17ca7183462744, 0x4de2e19b12854d65, 0x20938ee131fc7ef0}, + }, + }, + spongeIv: [][]*fp.Fp{ + // Testnet + { + {0x63d01a5eb2171352, 0xa156f498468c138a, 0x6863ea2849c3a1a2, 0x9d3a988f1f410b1}, + {0x7102a042f3032c7a, 0xec792d3bae28c836, 0x56ca8c6f048bc984, 0x1219b5fcf34e0a1f}, + {0x2ac12e04eb8f550a, 0xa5757bca84777f2b, 0xd3c2bf917b1192ea, 0x1989968c7935c607}, + {0xe1d62db2c86caa07, 0xb8ed617d8704c6b, 0x4e71934f60359a00, 0x25459aa434d50ff}, + {0x290a6ff9dd02df5e, 0x6e4c26ecf7984888, 0x8f5fb54612793d95, 0x31404beb90f0fdc8}, + }, + // Mainnet + { + {0x1bc46288607092ee, 0x679d1013fcd27af4, 0x2302588441a00b35, 0x52aa4180a0e1d3f}, + {0xf44d99f5d1788e7c, 0xa808f4bc1c5e8caa, 0xd3fd8806f5f3de6, 0x12ad0b5be60d68f1}, + {0x6928c9d83855c9d, 0x4b93a3d0d8209f22, 0xbbaea51d0f1f12e6, 0x62815b7ee55e6a8}, + {0x1fbd2d82dcfa2d, 0x78ec7156c609e43a, 0xf1e203a769275642, 0x3e15c2753ca6c1d}, + {0x6299f39409f35a31, 0x279b391979868236, 0x87b62f1b72d1deea, 0x3b44d1afce3a530d}, + }, + }, + }, + // three + { + spongeWidth: 3, + spongeRate: 2, + fullRounds: 54, + sBox: Sept, + roundKeys: [][]*fp.Fp{ + { + {0xa7eaec68b00f442f, 0x6f59e1a835643145, 0x5e1085dc39694ee7, 0x31f43b11041ce57e}, + {0xaf9d994fe02cad85, 0xd023d4dba24251f2, 0xab2b289011b10b15, 0x136703f8461e5900}, + {0x17d4dcf1505a5b8e, 0x905301ba46f35eda, 0xbf183c861c890269, 0xcd2255c8e8bfad7}, + }, + { + {0x652519f35396e7b9, 0xf939da87dd2565f7, 0x77863388eeb1739a, 0x2ef0165a2c2e5844}, + {0x477f697921c5a46f, 0x2f5597aaf22a3c0e, 0xea51d9a2b20ef8ee, 0x27f19ea80ac259a1}, + {0x475253132eafc552, 0x691f153f119e2158, 0x3463b3d75dc73170, 0x3875a2611a0025e4}, + }, + { + {0xc1500848eb7005a6, 0x61e2acd1faf26ff8, 0xf50c67341380fa2f, 0x14e95cd68d6778e}, + {0xa82b34cad0ebd99e, 0x771d54af176024ba, 0xa343788ac43bbde2, 0x31c9ab354d21b72a}, + {0x3deb92a1d0140aab, 0xb710f83bb2ce1349, 0xf3dc159cb9171a97, 0x6c3eac66a23c368}, + }, + { + {0xd25cd659b62b584, 0x3a52d26b8092be14, 0xe36c5155d1e135b, 0x16deeee5467c7a70}, + {0x9b446f453cb50aca, 0xeadf51c8f0af7a58, 0x75da6f44c4a04ca2, 0xccc39a8549cb487}, + {0xe09191801b0fdabc, 0xa7452c89066d4bd0, 0x5244883ddc1fd9cf, 0x3862cc172ab37d2f}, + }, + { + {0x6a87a9921ce9aabf, 0x5d701ed9a030bc04, 0xf99642aa2a835ec8, 0x28319fcffc61a144}, + {0xafb8a54d87a15b37, 0x31e93428debef477, 0xd328f47b48852d58, 0x1e9fb7a3f8c8e39f}, + {0xa58f9aa995fcab1, 0x5fb0135046864286, 0x6ad292753e09ec37, 0x24cb4d2ff2e77907}, + }, + { + {0xbebb7c8e57280d90, 0xa2575331fa3f83b, 0x1bdaa15abc6032e4, 0x137f4d26f7fc2b89}, + {0x8ea04d93f2a3faba, 0x76d83e0976143e11, 0xde45171e6c479b69, 0x3ec500ad89afdcfe}, + {0x9741b7a395379855, 0x916b939a142e1e68, 0x4fda77496b815109, 0x19d993fa47fbc1a7}, + }, + { + {0x31d6e313b491fe95, 0x19f07f1a489cb20a, 0x517ac8eb07d91f83, 0x16bd2c0e204bb5dd}, + {0x42170b694f7b1926, 0xdde594e9f6060540, 0xbdb7c66abef575a5, 0x26c2c710d9aea3c9}, + {0xccfb5e566332e76d, 0x4e73df588d423339, 0xa4ede3fda7178916, 0x28fc0255accddbf0}, + }, + { + {0x2fc2f7a5cf4eeb76, 0x709a30d94daa56c0, 0x67a5dd9c696533dc, 0x3ace056f839007b7}, + {0x7769ae0082cae71b, 0xdaa4d4c08c74011a, 0x919a01423e32424d, 0x22467d425c99d5c9}, + {0x6bcd3613ace4871c, 0xb0bc217531069def, 0x55348199fa2b487b, 0x2385b602228e77ee}, + }, + { + {0x7022e34179f7fd32, 0xd7d122a3a91838e2, 0x20e0714f41741103, 0x55ca30203c35d65}, + {0xeac64a4e27a532ac, 0xfad717669ae09d08, 0x16088f7d30d724f1, 0x37bb5a0c062e6400}, + {0x7c34a314bcba4635, 0xbfdd1e4cda8ce53, 0x7b9809bd9828ebbb, 0xbe17455fb915f02}, + }, + { + {0x3eedf4d1439104cc, 0x6944849f8d44d187, 0x4dbe80e8f415dfdc, 0x1df9173c6d047e75}, + {0xbe0b090e46076c2e, 0xdc964a5825b49df4, 0xc8c690008b31f4cc, 0x2a7eea60cbe9e9c2}, + {0x7e3ea7d6debb93ed, 0x697818afff9c8ff8, 0xbd716ed0d057327c, 0xb4a53cd8838ca03}, + }, + { + {0x9249570785f595ac, 0xa8baedefd054d755, 0x4e349f30983cb2d1, 0x20e038ae5219f06f}, + {0x1e6b0d84b6b0bd2b, 0x28036e399a182d83, 0x9b4db5cdc8f5900f, 0xba7d843e40009}, + {0xc1862aa768e1a9de, 0x134ee89ea258d84b, 0xa344c6a98af5c8e1, 0x35868f24584f89c0}, + }, + { + {0x6562561d6d2bd2eb, 0xe906eab7bfb25ce1, 0xdc3286360790ca24, 0x95cf9864fa2e99f}, + {0x8df04360bfee0f49, 0xf36da4b0797f28ab, 0x973b5df087ce6868, 0x31b4ebf5790f547a}, + {0x5236c69070d6a6cd, 0xe3483908bed7cd3a, 0x230cf521e8f636d5, 0x1369fed0b1ebdd4e}, + }, + { + {0x6b84b4d8a249ce56, 0xf8f9e37aee88a381, 0x547e20f39ea3ee67, 0x1a521535f4c4609a}, + {0xece3e35b95cf0b40, 0xc3f355a2343a9bba, 0x352dca283e1dc20, 0x18533c495c159ea5}, + {0x5c080eb0e667f655, 0xae7eedb84aaa82cf, 0xc40800efbbfb36e2, 0x23f8f08e412d848e}, + }, + { + {0xe47de2b666816c07, 0xfd084e96b59c227a, 0xffee4cb4adefb5b9, 0x27873596008bf329}, + {0x74c07063640d932f, 0xdcafa7d16923f8c6, 0x69cc607697b5fa58, 0x3fe8dcd350f158a0}, + {0x4685e7e0534a4487, 0x3e0a5a82c1308413, 0xe8f4882500745f38, 0x15d7152e439e3e39}, + }, + { + {0x1b6a574d8750bc73, 0x106eecce46abf1e6, 0xaac26d11ddaa2fa6, 0x38e31bc0f50b77a8}, + {0x46f4e9b5d03cc39d, 0xcc3f83cbed376830, 0x9b08a2cd1eb3c25c, 0x1b205334b2958429}, + {0xd58f58d5f1219de9, 0x1cfaa7547a262198, 0xcded38f37a2a880d, 0x177392b21a898be2}, + }, + { + {0xabc2d6caf40fda5a, 0xeb350f697f26ad45, 0x3a8945142b944356, 0x646f6d15a42f200}, + {0xff43256a693e8ab0, 0x2d305df7c836dcae, 0xccde78bd165aba3, 0x784cf8c1e09fd03}, + {0x11c0a75dfb1d6922, 0xa7dc5f890e8b9385, 0xaf784b2ec0758e11, 0xb79376b50d40562}, + }, + { + {0x4cfa43b93f239b43, 0x8465e6265d898268, 0x1288bcdb6fff50f4, 0x819462af6ba8c78}, + {0xba07b8ffdba328b0, 0x4215ac492cce28b3, 0x9730ec3e2f2188f3, 0x10bc9871d3004f71}, + {0x5a31626caca7283f, 0x40424e694cc63e9a, 0xcceb1adc2a52c6b9, 0x2836d9e7ccb5b686}, + }, + { + {0xf2191ab8935e3139, 0x6263e421438839a9, 0xf36d5611a925964c, 0x3ad254981c5584f}, + {0x77f3cbe4b7ec0506, 0x14cfd27cad91e7f6, 0xd66382bc65d30343, 0x11eb1499a7eb9296}, + {0x8306372b9fccfce6, 0xff3f90b389214f3f, 0x589837150e5e7261, 0x330673584db884bd}, + }, + { + {0xbf438550dc08ca8c, 0xa67d5b92e6b2d9f4, 0x45f1b4851f11355e, 0x3197089756209bf0}, + {0xa7bb2e56a3383876, 0xa1b85198d1a992d9, 0x807a2bb7e34327c6, 0x1a7be86ebc9ceb25}, + {0xb67db6d33a48b0df, 0x20bcebe6769fcc54, 0x2c5defebf8a107df, 0x3c0e75597f21e444}, + }, + { + {0x3ee09fdbfc3969f8, 0xfa1d3b39ae852fe9, 0xf9a75fb275dc4bf3, 0x2a38ad56c662e4c3}, + {0x436111724d967633, 0x7bc3452ae208f145, 0xfa8b9c79a56e7177, 0x3328b53b61a96c1a}, + {0x7dc685041c4a8de8, 0xcc8d3bf1000d5962, 0x53f0f1b8456b9659, 0xe5633a4ee33b43f}, + }, + { + {0x50e48fb72f31229f, 0xa5b753a3355553ad, 0x1c81ccd682c6dbf0, 0x6c795d332f94020}, + {0xf0fdbce25dad3d31, 0x9c588e128b3cebf0, 0x278767bad1a401ec, 0x12fd7107dacf168b}, + {0x98f200455814ae5c, 0x47f8009a5ae445bd, 0x487393e3ebc8077f, 0x3d579e85ebce0cba}, + }, + { + {0xe8df711446a2a238, 0xde4cc56b9510c04c, 0xb69991b66d096631, 0x1ab962f474f31f94}, + {0x994397076df00b58, 0x655b22de2fc1d376, 0x8c4152fcacaf0b18, 0x20051bcd8c1c3f37}, + {0xd66fe84e8d8d5bcb, 0xba022f54bb73200, 0xdaf17b9ad85c1d89, 0xd939c085418afd2}, + }, + { + {0xd5e63b74c211bc, 0xb12fc9c1def2e171, 0x44eaf0fd6faad3ea, 0x242c8eaf5e3f8025}, + {0xbf97706088f0ff2e, 0x1d8dad8a65750bd0, 0xc29b958d06fc399f, 0x134e81757cb8421e}, + {0x90be439afe7faf2, 0xc4b4762c8cc16bea, 0x1e477be4c4f40c9b, 0x23b4d50dc7ec40d7}, + }, + { + {0x333f64ebf7d2e7a8, 0x870b1f5dbdb11bdf, 0x74c9542dd65f4221, 0x128bb297ac5b8087}, + {0x74cdc264c1c32632, 0xcdbd7f0678ca09f9, 0xeb378a38bded711e, 0x1c4c18ced367bb10}, + {0x436cf961456330a9, 0x5261fdb10401ba02, 0x5aa07cfe8724969b, 0x17d4aa22d7539f30}, + }, + { + {0x22577a304a9a99c0, 0x26990766bceeaf3e, 0xf44a18d2965b75e6, 0x2b9ccb511447556b}, + {0xb4816bee4c57ea14, 0x657c7ff22284eddf, 0x80327f4b561a57a, 0x185d288b2163e408}, + {0x2521ae71bb3e92cd, 0xcfa6a3908f9422a4, 0xc5566b5d0cba3b6a, 0x19186ee34b32adf1}, + }, + { + {0x6ababe0d83a14804, 0x48a2976613fe9c87, 0x8fd28b1e6637a35f, 0x36be57a5b7dc101}, + {0x9409b310f8dedbd5, 0xdcb6ff2dd7ade6e8, 0x58ef424bfb1e96cf, 0x59c25a9e8435caa}, + {0x6017336865718144, 0x3b735147994d3174, 0x556dacb8916ce5fb, 0x6db68d040cf3894}, + }, + { + {0xfb28daa548eae196, 0xdee9f1fb48ad3a18, 0x8aeb7ea74f7458e0, 0x2f9a904f8eca76f4}, + {0x78ab93c53d27c0a9, 0x7cbd38a19659d91e, 0x6190fc4c6fcea287, 0x392493ffebdcf4db}, + {0xc288a18be7c7b29a, 0x293635495be4702a, 0x8eabeaa050c4e742, 0x3ee20e43c9a7e3a9}, + }, + { + {0xb247c20bce94d2fb, 0x7b37f102aba6dc41, 0x4e4cd6f2dfd06908, 0x2a4b7450c10e8656}, + {0xb8530701f1190812, 0x8852c8a7dd78c157, 0xef99612848a09ee6, 0x18cac72301419e17}, + {0x3bf72719696125f9, 0xa9153cf6b92ed66c, 0x5dee1004fa68e8ad, 0x2b0ab9d9c7146b8d}, + }, + { + {0x536e86c644632835, 0xfb528949c3d10378, 0x93cef66ee69cc174, 0xef7cc63c029b540}, + {0x3f71db10b88e45e1, 0x6a1cdfba155d75ba, 0x3ae6893f9c00830, 0x1f4aa1edaeea25af}, + {0x6c911d68b8bae9c7, 0xb562eb9132f9adcf, 0xb99552efd2922e09, 0x1aee619f6e53e5d1}, + }, + { + {0xc3e7eba538b57ce4, 0xe31fc856b301a0ed, 0x907bed9fd07a7f39, 0x2d8b156182efe6c2}, + {0x3c46848a7286379b, 0x8c1ce4abf2bdac01, 0xfe59adadfa57ab2d, 0x118d842df28ba098}, + {0x40346673db347d50, 0x9e9e286fbc221bac, 0x629f295d0d56a062, 0x2c7473af62ed3627}, + }, + { + {0x752c0e54b9084c5e, 0x9876503df35123f2, 0x4033dd4b36b302eb, 0x1f2f3ed1fdf6db7b}, + {0xc1aac2892f6ad5a0, 0xa4d2c62a12460d75, 0xfdfc27280cba16d8, 0x32e7b499b5afa89f}, + {0xa93b9c721205117, 0x29f32892dd66377a, 0x5db34e58446659b5, 0x35b9a957235ce56c}, + }, + { + {0x27dd8772ea8dd6fb, 0x7657580893377a80, 0x98116540d5d734fc, 0x1784ef3dbedaa7f1}, + {0x7ea4b4453558ad1e, 0xe79ae8a84479841f, 0x1448d360ba9dceaf, 0x29004bf2b27c1cc}, + {0x9be743f9caccf63, 0xf852240a936f7e9e, 0xb1cd6029e13842dd, 0x255bdfce8905f3d5}, + }, + { + {0x7415ee9f67631e70, 0x545553ffaf7d2592, 0xde51ae9194c9a7b2, 0x304409b176b5751d}, + {0x9c447ba5504d7b34, 0xfb288ee73506db89, 0x4cb32cefbc235f79, 0x3f2084c1c1605185}, + {0xdd24109730f8173c, 0x58b00f316d07a773, 0x1e86bdb19d121999, 0x3c46e8c04c88a74f}, + }, + { + {0x9ff193f33610856, 0x7cff32dc29fafc7f, 0xab1176764a90b2b5, 0x37a314e9261a12bc}, + {0xea6753fdcff09509, 0x4222dd5e1a66381d, 0x6056412c14d4667e, 0x30f19d0141776609}, + {0x383a756cdd6bbf4a, 0x4b314310043c1039, 0x7aa6b018a79ad7a4, 0x2d78d62918aa8e15}, + }, + { + {0x2c202fafd61e9da3, 0x89be41afc9c1f1fe, 0x15b6d718ea74a2d, 0x1c1c7eb84e510588}, + {0x342bbc7354bde7a5, 0xc995adfbe2005f6b, 0x85a618fbe9ccea3c, 0x3d61c03132b831b7}, + {0x84f0053a596c462a, 0x3725a512ef2e7da, 0x9866bda3e8d65025, 0x16307f53c31b9b2d}, + }, + { + {0xe11a11d7ad7c2941, 0xa196efe53885dac4, 0x401c98e5702a4b4d, 0x2627aedf841d2535}, + {0x6c137315f42a3d7, 0x1b27880c4b80acc2, 0xd2463e7af19c63f8, 0x1ac361c3ae9360d0}, + {0x9ca7acb3c1e8764c, 0xa3abf95002b63ec7, 0x607aec3d66927bd, 0x350322d135e4b5b0}, + }, + { + {0x8767a56f58823fb1, 0xa17115bf335777f7, 0x2d2d011c09bc4b6, 0x23f5c30c8bec1802}, + {0x469e5aee1e354cff, 0x19b662c5ee659a15, 0x8222b7d81ef2e3d0, 0x25dbe21f1dc14bbb}, + {0xcf3036e9bef51413, 0x2ec597011f15b75d, 0x1b6f15cf41987ffb, 0x243e4331eaa8ca3f}, + }, + { + {0x7e12d7264aa9d64a, 0x986866249a40df19, 0x224d9731f988d510, 0x3da1029b04d0699}, + {0x63ce9c82f26c2122, 0xd07b42737417e607, 0xdffe6c18b3e32c4e, 0xcb558a55e33635b}, + {0xa9e72e1bbb1e1ac6, 0x7c0eac490aa84fe, 0xc716b352d91ef297, 0x17c0df062139a3b0}, + }, + { + {0xb6e0e5acafd75f1b, 0xe79ccc9d178be022, 0xa62fb84a4594821, 0x118ff23cec0e9ab7}, + {0xdaeb6bb9649cc9ed, 0x2b1c328f5bb8662f, 0x5512487ef834c9ff, 0x10a6d8b760d8381f}, + {0x55bcd8a0925661ee, 0x92289bf6cb46afe5, 0xa2b1c38630374b57, 0x1a382c83ffa7d479}, + }, + { + {0x5b9ed41d83b22227, 0x861a12cf34e20309, 0x722187ecc9fb01cd, 0x3d7bb8d8fbbf19aa}, + {0x56b2351caaa77660, 0x5649f8afb77f8250, 0x179b134befc40c2a, 0x117b5ac7fab8a73b}, + {0xbb53d76efa39fb63, 0x3821ad8ab6648b10, 0x860e686568c98df, 0x181510039e8bf016}, + }, + { + {0xabcab07505b93cf, 0x4088c208ddc38a79, 0x60aa91fcf3d30a95, 0x1cca89ba50887f72}, + {0x756ea77ac464fb2f, 0xb54ae17c6bba044a, 0x3350ae0df3e90873, 0x186b9034baedae26}, + {0x813cc8de3ccd6501, 0x612bffa93d7579f9, 0x5ad42ea9bc5bbd6c, 0x123ed625db167d32}, + }, + { + {0x2db34a3c43a01e76, 0x93bf90bd39919618, 0xb62aafc5a062e6ec, 0x30e33d44bc2851c0}, + {0x74dcd4e07d98a23b, 0xb390d88ce8c1c12d, 0xc60d4855592f4f12, 0x3d3808ea888bc3ef}, + {0x6b6125132d3b6c9b, 0xefb93b37d8c98901, 0x5396ab9879f061f3, 0x26814970d99a4859}, + }, + { + {0x65a39dff4c093ac6, 0xdb8b03741b7d38b3, 0x34e5285eb2732099, 0xcffcab13b9c402}, + {0xba151ecf346e77e5, 0xdc944d4cedf21de6, 0xbf6157bdc8bf2df3, 0x39a726986b4d3042}, + {0x44150981f7bb214f, 0xdaf82667aa9df080, 0x4cb0e4251cbd837c, 0x96407a7f4c8919d}, + }, + { + {0xab327a1874a4376d, 0x2ac8b215b83ec21, 0x72ccc1310e756e19, 0x337f64158d29681d}, + {0xfdd547b12cd1c47c, 0xeda570d77efb35ef, 0xee673a9c5c5c6c24, 0x1069938e1c2d5fb8}, + {0xe18e30b72b41cebd, 0x9530ddc35a81e36e, 0xcb076c0372dd1f10, 0x1a6810a2f1aee9a3}, + }, + { + {0xf42b4184e45ef9b0, 0x621c9c9f4b7805bb, 0xe64a4966c57c625e, 0x331dfaac4fca1afe}, + {0x5745585e5aa8e18, 0x48138c500616daa7, 0x740880dd14d57c7b, 0x621e4237f79bc67}, + {0x7752004d293d5b5d, 0x32176da95d737cf5, 0xe14bb9ef4281cf03, 0x56e679688dec9b0}, + }, + { + {0xcf96c57a6c6dced2, 0x9d0641008bc1e8e6, 0xaf7c8a61f00aea43, 0x3de7cc921f006f35}, + {0xe5a284274906c87c, 0x3f57a5c227ad9ef7, 0x8ca3d4e109a701b9, 0x23fa54fa0717813}, + {0xa418bb283bcf6e4c, 0xfe2037c5295b505d, 0xcaa0956e946f4a29, 0x2a042a0cc94e6eb7}, + }, + { + {0xd8df14778b795fec, 0x16c27f664e2ea362, 0xe24b2f6edd5eaebe, 0x14c903e18d6d1fc3}, + {0x89586ac5b4450805, 0xadc6ee91f14ae921, 0xc6bc4c3b0f873a03, 0x351fccf49d14543a}, + {0xd3601422d37aaa9e, 0x988c203077dd68e9, 0x1cae7a1d3150e958, 0x1292d11437a1acd4}, + }, + { + {0xe53e955d71efa6c, 0x8fe1b41936d8c2e, 0xc1115be6796700ba, 0x16f2577444f333ac}, + {0xb46fdc6c76b91715, 0xba7c98748d26f41a, 0x8a767b731b64d9a2, 0x380f78e27ff89d8f}, + {0xfd9976c4488e5f16, 0xbeaf3cb1cf0cfc03, 0xf2bc02883a339b2a, 0x3a669a9fec53277f}, + }, + { + {0x7489c5648c85dee1, 0x7f9d020bd71f0bc3, 0xcf347020818fd255, 0x34ce3d2873ef623b}, + {0x82891abb666f3ff4, 0x370d13492155070d, 0x26c0426048d99ec2, 0x89cceef0d956cc}, + {0xf161875b3c921a95, 0xe0ee4bd7518d961a, 0xcd3614b6acaf6d93, 0x27ef7c723667b755}, + }, + { + {0x13fb2dcf933fd4d, 0x103f7deb9f64a5aa, 0x26d375314a7a8189, 0x1fb433f9d0d1a1af}, + {0xa49a8d2583ef3bdd, 0x9a7a627ea2417df1, 0x93277db6c1298ce4, 0x224efdd22b53fe03}, + {0xd9ef2ab6918b48ed, 0xab7f9a26705488c0, 0xc179467a22565381, 0x3c8192acf2659bbf}, + }, + { + {0x90c3c01685741695, 0x8fc7d42cbdf62efb, 0x8ca74bdebec3a42b, 0x2d07192135436805}, + {0x597f91232510722, 0xb6ff30a1505c4ea8, 0xdd22fd456a942afe, 0x1cb7fdcfaa9bdd05}, + {0xdcf520384f1ddaf0, 0xeb0ee12c33953a63, 0x9a3a10c7e3aa6f41, 0x1471506df8d986b4}, + }, + { + {0xcd605e2791e6a5e5, 0x1c27ce94b83f068f, 0xb172e53c549a3c12, 0x21f264ce80eef855}, + {0xfe4a5caf09cd178f, 0xd76b6393a8b8597f, 0x828a31309599f1fa, 0x1d7eb56ca9c920f6}, + {0x589bdbc5eb3cc1fc, 0xa5ab6823129a3ed3, 0x1f5b9bd5aca5d3ec, 0x64aae35f2e4b6bc}, + }, + { + {0x365002f75230793, 0x2b8d834bd6a4c78f, 0x7f445a46d203a93d, 0x265c579246ab3106}, + {0x4983fb4db3ca5acd, 0x770c07654eeefaab, 0x54456b57fa1fd5af, 0xb92cdbcf718c353}, + {0x1ac57ac76f928fe, 0x816c4d52b670680, 0x39b8598cba83c07d, 0x29af1b8a7d9ed796}, + }, + { + {0x715eb17f6f71404f, 0xd081dca0cad01695, 0xdeefdf16929d4947, 0x3d7f767198a2e29b}, + {0xebfb13feb0205761, 0x73e014ef38a3d8cb, 0x113bd31d16c16db7, 0x288eacb7eaa4d63c}, + {0x5d22751f1f2c937d, 0x50cc30867fe04f68, 0x70917ec415d4ac2c, 0x58c8b7c2b87e78b}, + }, + }, + mdsMatrix: [][]*fp.Fp{ + { + {0x19ebb0733ab608d5, 0xba29ddd056f8255c, 0x90b26832e301952d, 0xd393e38c7a5d0ab}, + {0x1370915e16c94656, 0xa9d4f14bbd2ea831, 0xbe629fe93a27e612, 0x21571a7cc32e18af}, + {0xb34a71b4f799ea19, 0x9685275173ff9b6b, 0xc2aa354b7f11d698, 0x15691c24c0a9f088}, + }, + { + {0xae932a9d486aface, 0xbef0293e7653db35, 0x279408c4d244c0d1, 0x39dd8040ea0c8d80}, + {0x9d32fbdbaf9bbe27, 0x999e1c5168806efa, 0x7d5f270b3cb077a8, 0xb4ac0738805f8de}, + {0xcfc1e61e0bcf9d5f, 0x12346d0d47576a9, 0xdbd1b0da710c7b5, 0x1db48905ceecc479}, + }, + { + {0x89dde65da2c627b, 0x873534c4aaf1243a, 0xa4f76bf3e5b626c5, 0x22a75f7cd3cad9d3}, + {0xb58ea56557361c3b, 0xd6cbb2cb0bc99acb, 0x5fee1fb5b71b86dd, 0x11d87bbca8e20fbe}, + {0x1d511fe638baa5c8, 0x7b6c7932776e1032, 0x45b27ee070531360, 0x19eb7c902ac90c5}, + }, + }, + spongeIv: [][]*fp.Fp{ + // Testnet + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + // Mainnet + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + }, + }, +} + +func (ctx *Context) Init(pType Permutation, networkId NetworkType) *Context { + if ctx == nil { + return nil + } + if pType != ThreeW && pType != FiveW && pType != Three { + return nil + } + if networkId != TestNet && networkId != MainNet && networkId != NullNet { + return nil + } + + ctx.pType = pType + ctx.spongeWidth = contexts[pType].spongeWidth + ctx.spongeRate = contexts[pType].spongeRate + ctx.fullRounds = contexts[pType].fullRounds + ctx.sBox = contexts[pType].sBox + ctx.roundKeys = contexts[pType].roundKeys + ctx.mdsMatrix = contexts[pType].mdsMatrix + ctx.spongeIv = contexts[pType].spongeIv + ctx.state = make([]*fp.Fp, contexts[pType].spongeWidth) + if networkId != NullNet { + iv := contexts[pType].spongeIv[networkId] + for i := range iv { + ctx.state[i] = new(fp.Fp).Set(iv[i]) + } + } else { + for i := range ctx.state { + ctx.state[i] = new(fp.Fp).SetZero() + } + } + ctx.absorbed = 0 + return ctx +} + +func (ctx *Context) Update(fields []*fp.Fp) { + for _, f := range fields { + if ctx.absorbed == ctx.spongeRate { + ctx.pType.Permute(ctx) + ctx.absorbed = 0 + } + ctx.state[ctx.absorbed].Add(ctx.state[ctx.absorbed], f) + ctx.absorbed++ + } +} + +func (ctx *Context) Digest() *fq.Fq { + ctx.pType.Permute(ctx) + res := ctx.state[0].ToRaw() + return new(fq.Fq).SetRaw(&res) +} diff --git a/pkg/crypto/signatures/schnorr/mina/poseidon_hash_test.go b/pkg/crypto/signatures/schnorr/mina/poseidon_hash_test.go new file mode 100755 index 000000000..1ae8f417d --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/poseidon_hash_test.go @@ -0,0 +1,122 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fq" +) + +func TestPoseidonHash(t *testing.T) { + // Reference https://github.com/o1-labs/proof-systems/blob/master/oracle/tests/test_vectors/3w.json + testVectors := []struct { + input []*fp.Fp + output *fq.Fq + }{ + { + input: []*fp.Fp{}, + output: hexToFq("1b3251b6912d82edc78bbb0a5c88f0c6fde1781bc3e654123fa6862a4c63e617"), + }, + { + input: []*fp.Fp{ + hexToFp("df698e389c6f1987ffe186d806f8163738f5bf22e8be02572cce99dc6a4ab030"), + }, + output: hexToFq("f9b1b6c5f8c98017c6b35ac74bc689b6533d6dbbee1fd868831b637a43ea720c"), + }, + { + input: []*fp.Fp{ + hexToFp("56b648a5a85619814900a6b40375676803fe16fb1ad2d1fb79115eb1b52ac026"), + hexToFp("f26a8a03d9c9bbd9c6b2a1324d2a3f4d894bafe25a7e4ad1a498705f4026ff2f"), + }, + output: hexToFq("7a556e93bcfbd27b55867f533cd1df293a7def60dd929a086fdd4e70393b0918"), + }, + { + input: []*fp.Fp{ + hexToFp("075c41fa23e4690694df5ded43624fd60ab7ee6ec6dd48f44dc71bc206cecb26"), + hexToFp("a4e2beebb09bd02ad42bbccc11051e8262b6ef50445d8382b253e91ab1557a0d"), + hexToFp("7dfc23a1242d9c0d6eb16e924cfba342bb2fccf36b8cbaf296851f2e6c469639"), + }, + output: hexToFq("f94b39a919aab06f43f4a4b5a3e965b719a4dbd2b9cd26d2bba4197b10286b35"), + }, + { + input: []*fp.Fp{ + hexToFp("a1a659b14e80d47318c6fcdbbd388de4272d5c2815eb458cf4f196d52403b639"), + hexToFp("5e33065d1801131b64d13038ff9693a7ef6283f24ec8c19438d112ff59d50f04"), + hexToFp("38a8f4d0a9b6d0facdc4e825f6a2ba2b85401d5de119bf9f2bcb908235683e06"), + hexToFp("3456d0313a30d7ccb23bd71ed6aa70ab234dad683d8187b677aef73f42f4f52e"), + }, + output: hexToFq("cc1ccfa964fd6ef9ff1994beb53cfce9ebe1212847ce30e4c64f0777875aec34"), + }, + { + input: []*fp.Fp{ + hexToFp("bccfee48dc76bb991c97bd531cf489f4ee37a66a15f5cfac31bdd4f159d4a905"), + hexToFp("2d106fb21a262f85fd400a995c6d74bad48d8adab2554046871c215e585b072b"), + hexToFp("8300e93ee8587956534d0756bb2aa575e5878c670cff5c8e3e55c62632333c06"), + hexToFp("879c32da31566f6d16afdefff94cba5260fec1057e97f19fc9a61dc2c54a6417"), + hexToFp("9c0aa6e5501cfb2d08aeaea5b3cddac2c9bee85d13324118b44bafb63a59611e"), + }, + output: hexToFq("cf7b9c2128f0e2c0fed4e1eca8d5954b629640c2458d24ba238c1bd3ccbc8e12"), + }, + } + for _, tv := range testVectors { + ctx := new(Context).Init(ThreeW, NetworkType(NullNet)) + ctx.Update(tv.input) + res := ctx.Digest() + require.True(t, res.Equal(tv.output)) + } + testVectors = []struct { + input []*fp.Fp + output *fq.Fq + }{ + { + input: []*fp.Fp{ + hexToFp("0f48c65bd25f85f3e4ea4efebeb75b797bd743603be04b4ead845698b76bd331"), + hexToFp("0f48c65bd25f85f3e4ea4efebeb75b797bd743603be04b4ead845698b76bd331"), + hexToFp("f34b505e1a05ecfb327d8d664ff6272ddf5cc1f69618bb6a4407e9533067e703"), + hexToFp("0f48c65bd25f85f3e4ea4efebeb75b797bd743603be04b4ead845698b76bd331"), + hexToFp("ac7cb9c568955737eca56f855954f394cc6b05ac9b698ba3d974f029177cb427"), + hexToFp("010141eca06991fe68dcbd799d93037522dc6c4dead1d77202e8c2ea8f5b1005"), + hexToFp("0300000000000000010000000000000090010000204e0000021ce8d0d2e64012"), + hexToFp("9b030903692b6b7b030000000000000000000000000000000000800100000000"), + hexToFp("000000a800000000000000000000000000000000000000000000000000000000"), + }, + output: &fq.Fq{ + 1348483115953159504, + 14115862092770957043, + 15858311826851986539, + 1644043871107534594, + }, + }, + } + for _, tv := range testVectors { + ctx := new(Context).Init(ThreeW, NetworkType(MainNet)) + ctx.Update(tv.input) + res := ctx.Digest() + require.True(t, res.Equal(tv.output)) + } +} + +func hexToFp(s string) *fp.Fp { + var buffer [32]byte + input, _ := hex.DecodeString(s) + copy(buffer[:], input) + f, _ := new(fp.Fp).SetBytes(&buffer) + return f +} + +func hexToFq(s string) *fq.Fq { + var buffer [32]byte + input, _ := hex.DecodeString(s) + copy(buffer[:], input) + f, _ := new(fq.Fq).SetBytes(&buffer) + return f +} diff --git a/pkg/crypto/signatures/schnorr/mina/roinput.go b/pkg/crypto/signatures/schnorr/mina/roinput.go new file mode 100755 index 000000000..b2c9b92d9 --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/roinput.go @@ -0,0 +1,136 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fq" +) + +// Handles the packing of bits and fields according to Mina spec +type roinput struct { + fields []*fp.Fp + bits *BitVector +} + +var conv = map[bool]int{ + true: 1, + false: 0, +} + +func (r *roinput) Init(fields int, bytes int) *roinput { + r.fields = make([]*fp.Fp, 0, fields) + r.bits = NewBitVector(make([]byte, bytes), 0) + return r +} + +func (r *roinput) Clone() *roinput { + t := new(roinput) + t.fields = make([]*fp.Fp, len(r.fields)) + for i, f := range r.fields { + t.fields[i] = new(fp.Fp).Set(f) + } + buffer := r.bits.Bytes() + data := make([]byte, len(buffer)) + copy(data, buffer) + t.bits = NewBitVector(data, r.bits.Length()) + return t +} + +func (r *roinput) AddFp(fp *fp.Fp) { + r.fields = append(r.fields, fp) +} + +func (r *roinput) AddFq(fq *fq.Fq) { + scalar := fq.ToRaw() + // Mina handles fields as 255 bit numbers + // with each field we lose a bit + for i := 0; i < 255; i++ { + limb := i / 64 + idx := i % 64 + b := (scalar[limb] >> idx) & 1 + r.bits.Append(byte(b)) + } +} + +func (r *roinput) AddBit(b bool) { + r.bits.Append(byte(conv[b])) +} + +func (r *roinput) AddBytes(input []byte) { + for _, b := range input { + for i := 0; i < 8; i++ { + r.bits.Append(byte((b >> i) & 1)) + } + } +} + +func (r *roinput) AddUint32(x uint32) { + for i := 0; i < 32; i++ { + r.bits.Append(byte((x >> i) & 1)) + } +} + +func (r *roinput) AddUint64(x uint64) { + for i := 0; i < 64; i++ { + r.bits.Append(byte((x >> i) & 1)) + } +} + +func (r roinput) Bytes() []byte { + out := make([]byte, (r.bits.Length()+7)/8+32*len(r.fields)) + res := NewBitVector(out, 0) + // Mina handles fields as 255 bit numbers + // with each field we lose a bit + for _, f := range r.fields { + buf := f.ToRaw() + for i := 0; i < 255; i++ { + limb := i / 64 + idx := i % 64 + b := (buf[limb] >> idx) & 1 + res.Append(byte(b)) + } + } + for i := 0; i < r.bits.Length(); i++ { + res.Append(r.bits.Element(i)) + } + return out +} + +func (r roinput) Fields() []*fp.Fp { + fields := make([]*fp.Fp, 0, len(r.fields)+r.bits.Length()/256) + for _, f := range r.fields { + fields = append(fields, new(fp.Fp).Set(f)) + } + const maxChunkSize = 254 + bitsConsumed := 0 + bitIdx := 0 + + for bitsConsumed < r.bits.Length() { + var chunk [4]uint64 + + remaining := r.bits.Length() - bitsConsumed + var chunkSizeInBits int + if remaining > maxChunkSize { + chunkSizeInBits = maxChunkSize + } else { + chunkSizeInBits = remaining + } + + for i := 0; i < chunkSizeInBits; i++ { + limb := i >> 6 + idx := i & 0x3F + b := r.bits.Element(bitIdx) + chunk[limb] |= uint64(b) << idx + bitIdx++ + } + fields = append(fields, new(fp.Fp).SetRaw(&chunk)) + bitsConsumed += chunkSizeInBits + } + + return fields +} diff --git a/pkg/crypto/signatures/schnorr/mina/signature.go b/pkg/crypto/signatures/schnorr/mina/signature.go new file mode 100755 index 000000000..7e3708b8a --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/signature.go @@ -0,0 +1,49 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fp" + "github.com/onsonr/sonr/pkg/crypto/core/curves/native/pasta/fq" +) + +// Signature is a Mina compatible signature either for payment or delegation +type Signature struct { + R *fp.Fp + S *fq.Fq +} + +func (sig Signature) MarshalBinary() ([]byte, error) { + var buf [64]byte + rx := sig.R.Bytes() + s := sig.S.Bytes() + copy(buf[:32], rx[:]) + copy(buf[32:], s[:]) + return buf[:], nil +} + +func (sig *Signature) UnmarshalBinary(input []byte) error { + if len(input) != 64 { + return fmt.Errorf("invalid byte sequence") + } + var buf [32]byte + copy(buf[:], input[:32]) + rx, err := new(fp.Fp).SetBytes(&buf) + if err != nil { + return err + } + copy(buf[:], input[32:]) + s, err := new(fq.Fq).SetBytes(&buf) + if err != nil { + return err + } + sig.R = rx + sig.S = s + return nil +} diff --git a/pkg/crypto/signatures/schnorr/mina/txn.go b/pkg/crypto/signatures/schnorr/mina/txn.go new file mode 100755 index 000000000..544f7212b --- /dev/null +++ b/pkg/crypto/signatures/schnorr/mina/txn.go @@ -0,0 +1,224 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package mina + +import ( + "encoding/binary" + "encoding/json" + "fmt" + + "github.com/cosmos/btcutil/base58" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// Transaction is a Mina transaction for payments or delegations +type Transaction struct { + Fee, FeeToken uint64 + FeePayerPk *PublicKey + Nonce, ValidUntil uint32 + Memo string + Tag [3]bool + SourcePk, ReceiverPk *PublicKey + TokenId, Amount uint64 + Locked bool + NetworkId NetworkType +} + +type txnJson struct { + Common txnCommonJson + Body [2]interface{} +} + +type txnCommonJson struct { + Fee uint64 `json:"fee"` + FeeToken uint64 `json:"fee_token"` + FeePayerPk string `json:"fee_payer_pk"` + Nonce uint32 `json:"nonce"` + ValidUntil uint32 `json:"valid_until"` + Memo string `json:"memo"` + NetworkId uint8 `json:"network_id"` +} + +type txnBodyPaymentJson struct { + SourcePk string `json:"source_pk"` + ReceiverPk string `json:"receiver_pk"` + TokenId uint64 `json:"token_id"` + Amount uint64 `json:"amount"` +} + +type txnBodyDelegationJson struct { + Delegator string `json:"delegator"` + NewDelegate string `json:"new_delegate"` +} + +func (txn *Transaction) MarshalBinary() ([]byte, error) { + mapper := map[bool]byte{ + true: 1, + false: 0, + } + out := make([]byte, 175) + binary.LittleEndian.PutUint64(out, txn.Fee) + binary.LittleEndian.PutUint64(out[8:16], txn.FeeToken) + copy(out[16:48], txn.FeePayerPk.value.ToAffineCompressed()) + binary.LittleEndian.PutUint32(out[48:52], txn.Nonce) + binary.LittleEndian.PutUint32(out[52:56], txn.ValidUntil) + + out[56] = 0x01 + out[57] = byte(len(txn.Memo)) + copy(out[58:90], txn.Memo[:]) + out[90] = mapper[txn.Tag[0]] + out[91] = mapper[txn.Tag[1]] + out[92] = mapper[txn.Tag[2]] + copy(out[93:125], txn.SourcePk.value.ToAffineCompressed()) + copy(out[125:157], txn.ReceiverPk.value.ToAffineCompressed()) + binary.LittleEndian.PutUint64(out[157:165], txn.TokenId) + binary.LittleEndian.PutUint64(out[165:173], txn.Amount) + out[173] = mapper[txn.Locked] + out[174] = byte(txn.NetworkId) + return out, nil +} + +func (txn *Transaction) UnmarshalBinary(input []byte) error { + mapper := map[byte]bool{ + 1: true, + 0: false, + } + if len(input) < 175 { + return fmt.Errorf("invalid byte sequence") + } + feePayerPk := new(PublicKey) + sourcePk := new(PublicKey) + receiverPk := new(PublicKey) + err := feePayerPk.UnmarshalBinary(input[16:48]) + if err != nil { + return err + } + err = sourcePk.UnmarshalBinary(input[93:125]) + if err != nil { + return err + } + err = receiverPk.UnmarshalBinary(input[125:157]) + if err != nil { + return err + } + txn.Fee = binary.LittleEndian.Uint64(input[:8]) + txn.FeeToken = binary.LittleEndian.Uint64(input[8:16]) + txn.FeePayerPk = feePayerPk + txn.Nonce = binary.LittleEndian.Uint32(input[48:52]) + txn.ValidUntil = binary.LittleEndian.Uint32(input[52:56]) + txn.Memo = string(input[58 : 58+input[57]]) + txn.Tag[0] = mapper[input[90]] + txn.Tag[1] = mapper[input[91]] + txn.Tag[2] = mapper[input[92]] + txn.SourcePk = sourcePk + txn.ReceiverPk = receiverPk + txn.TokenId = binary.LittleEndian.Uint64(input[157:165]) + txn.Amount = binary.LittleEndian.Uint64(input[165:173]) + txn.Locked = mapper[input[173]] + txn.NetworkId = NetworkType(input[174]) + return nil +} + +func (txn *Transaction) UnmarshalJSON(input []byte) error { + var t txnJson + err := json.Unmarshal(input, &t) + if err != nil { + return err + } + strType, ok := t.Body[0].(string) + if !ok { + return fmt.Errorf("unexpected type") + } + memo, _, err := base58.CheckDecode(t.Common.Memo) + if err != nil { + return err + } + switch strType { + case "Payment": + b, ok := t.Body[1].(txnBodyPaymentJson) + if !ok { + return fmt.Errorf("unexpected type") + } + feePayerPk := new(PublicKey) + err = feePayerPk.ParseAddress(b.SourcePk) + if err != nil { + return err + } + receiverPk := new(PublicKey) + err = receiverPk.ParseAddress(b.ReceiverPk) + if err != nil { + return nil + } + txn.FeePayerPk = feePayerPk + txn.ReceiverPk = receiverPk + case "Stake_delegation": + bType, ok := t.Body[1].([2]interface{}) + if !ok { + return fmt.Errorf("unexpected type") + } + delegateType, ok := bType[0].(string) + if !ok { + return fmt.Errorf("unexpected type") + } + if delegateType == "Set_delegate" { + b, ok := bType[1].(txnBodyDelegationJson) + if !ok { + return fmt.Errorf("unexpected type") + } + feePayerPk := new(PublicKey) + err = feePayerPk.ParseAddress(b.Delegator) + if err != nil { + return err + } + receiverPk := new(PublicKey) + err = receiverPk.ParseAddress(b.NewDelegate) + if err != nil { + return err + } + txn.FeePayerPk = feePayerPk + txn.ReceiverPk = receiverPk + } else { + return fmt.Errorf("unexpected type") + } + default: + return fmt.Errorf("unexpected type") + } + txn.Memo = string(memo[2 : 2+memo[1]]) + sourcePk := new(PublicKey) + sourcePk.value = new(curves.Ep).Set(txn.FeePayerPk.value) + txn.Fee = t.Common.Fee + txn.FeeToken = t.Common.FeeToken + txn.Nonce = t.Common.Nonce + txn.ValidUntil = t.Common.ValidUntil + txn.NetworkId = NetworkType(t.Common.NetworkId) + return nil +} + +func (txn Transaction) addRoInput(input *roinput) { + input.AddFp(txn.FeePayerPk.value.X()) + input.AddFp(txn.SourcePk.value.X()) + input.AddFp(txn.ReceiverPk.value.X()) + + input.AddUint64(txn.Fee) + input.AddUint64(txn.FeeToken) + input.AddBit(txn.FeePayerPk.value.Y().IsOdd()) + input.AddUint32(txn.Nonce) + input.AddUint32(txn.ValidUntil) + memo := [34]byte{0x01, byte(len(txn.Memo))} + copy(memo[2:], txn.Memo) + input.AddBytes(memo[:]) + for _, b := range txn.Tag { + input.AddBit(b) + } + + input.AddBit(txn.SourcePk.value.Y().IsOdd()) + input.AddBit(txn.ReceiverPk.value.Y().IsOdd()) + input.AddUint64(txn.TokenId) + input.AddUint64(txn.Amount) + input.AddBit(txn.Locked) +} diff --git a/pkg/crypto/signatures/schnorr/nem/ed25519_keccak.go b/pkg/crypto/signatures/schnorr/nem/ed25519_keccak.go new file mode 100755 index 000000000..52c911c94 --- /dev/null +++ b/pkg/crypto/signatures/schnorr/nem/ed25519_keccak.go @@ -0,0 +1,320 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// This file implements the Ed25519 signature algorithm. See +// https://ed25519.cr.yp.to/. +// +// These functions are also compatible with the “Ed25519” function defined in +// RFC 8032. However, unlike RFC 8032's formulation, this package's private key +// representation includes a public key suffix to make multiple signing +// operations with the same key more efficient. This package refers to the RFC +// 8032 private key as the “seed”. +// This code is a port of the public domain, “ref10” implementation of ed25519 +// from SUPERCOP. + +package nem + +import ( + "bytes" + "crypto" + cryptorand "crypto/rand" + "fmt" + "io" + "strconv" + + "filippo.io/edwards25519" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +const ( + // PublicKeySize is the size, in bytes, of public keys as used in this package. + PublicKeySize = 32 + // PrivateKeySize is the size, in bytes, of private keys as used in this package. + PrivateKeySize = 64 + // SignatureSize is the size, in bytes, of signatures generated and verified by this package. + SignatureSize = 64 + // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. + SeedSize = 32 +) + +// PublicKey is the type of Ed25519 public keys. +type PublicKey []byte + +// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. +type PrivateKey []byte + +// Bytes returns the publicKey in byte array +func (p PublicKey) Bytes() []byte { + return p +} + +// Public returns the PublicKey corresponding to priv. +func (priv PrivateKey) Public() crypto.PublicKey { + publicKey := make([]byte, PublicKeySize) + copy(publicKey, priv[32:]) + return PublicKey(publicKey) +} + +func Keccak512(data []byte) ([]byte, error) { + k512 := sha3.NewLegacyKeccak512() + _, err := k512.Write(data) + if err != nil { + return nil, err + } + return k512.Sum(nil), nil +} + +// Seed returns the private key seed corresponding to priv. It is provided for +// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds +// in this package. +func (priv PrivateKey) Seed() []byte { + seed := make([]byte, SeedSize) + copy(seed, priv[:32]) + return seed +} + +// Sign signs the given message with priv. +// Ed25519 performs two passes over messages to be signed and therefore cannot +// handle pre-hashed messages. Thus opts.HashFunc() must return zero to +// indicate the message hasn't been hashed. This can be achieved by passing +// crypto.Hash(0) as the value for opts. +func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) { + if opts.HashFunc() != crypto.Hash(0) { + return nil, fmt.Errorf("ed25519: cannot sign hashed message") + } + sig, err := Sign(priv, message) + if err != nil { + return nil, err + } + return sig, nil +} + +// GenerateKey generates a public/private key pair using entropy from rand. +// If rand is nil, crypto/rand.Reader will be used. +func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { + if rand == nil { + rand = cryptorand.Reader + } + + seed := make([]byte, SeedSize) + if _, err := io.ReadFull(rand, seed); err != nil { + return nil, nil, err + } + + privateKey, err := NewKeyFromSeed(seed) + if err != nil { + return nil, nil, err + } + publicKey := make([]byte, PublicKeySize) + copy(publicKey, privateKey[32:]) + + return publicKey, privateKey, nil +} + +// NewKeyFromSeed calculates a private key from a seed. It will panic if +// len(seed) is not SeedSize. This function is provided for interoperability +// with RFC 8032. RFC 8032's private keys correspond to seeds in this +// package. +func NewKeyFromSeed(seed []byte) (PrivateKey, error) { + // Outline the function body so that the returned key can be stack-allocated. + privateKey := make([]byte, PrivateKeySize) + err := newKeyFromSeed(privateKey, seed) + if err != nil { + return nil, err + } + return privateKey, nil +} + +func newKeyFromSeed(privateKey, seed []byte) error { + if l := len(seed); l != SeedSize { + return fmt.Errorf("ed25519: bad seed length: " + strconv.Itoa(l)) + } + + // Weird required step to get compatibility with the NEM test vectors + // Have to reverse the bytes from the given seed + digest, err := Keccak512(internal.ReverseScalarBytes(seed)) + if err != nil { + return err + } + + sc, err := edwards25519.NewScalar().SetBytesWithClamping(digest[:32]) + if err != nil { + return err + } + + A := edwards25519.Point{} + A.ScalarBaseMult(sc) + publicKeyBytes := A.Bytes() + + copy(privateKey, seed) + copy(privateKey[32:], publicKeyBytes[:]) + return nil +} + +// Sign signs the message with privateKey and returns a signature. It will +// panic if len(privateKey) is not PrivateKeySize. +func Sign(privateKey PrivateKey, message []byte) ([]byte, error) { + // Outline the function body so that the returned signature can be + // stack-allocated. + signature := make([]byte, SignatureSize) + err := sign(signature, privateKey, message) + if err != nil { + return nil, err + } + return signature, nil +} + +func sign(signature, privateKey, message []byte) error { + if l := len(privateKey); l != PrivateKeySize { + return fmt.Errorf("ed25519: bad private key length: " + strconv.Itoa(l)) + } + + seed := privateKey[:32] + digest, err := Keccak512(internal.ReverseScalarBytes(seed)) + if err != nil { + return err + } + + // H(seed) ie. privkey + expandedSecretKey := digest[:32] + sc, err := edwards25519.NewScalar().SetBytesWithClamping(expandedSecretKey) + if err != nil { + return err + } + + // r = H(H(seed) + msg) + hEngine := sha3.NewLegacyKeccak512() + _, err = hEngine.Write(digest[32:]) + if err != nil { + return err + } + + _, err = hEngine.Write(message) + if err != nil { + return err + } + + var hOut1 [64]byte + hEngine.Sum(hOut1[:0]) + + // hash output -> scalar + // Take 64 byte output from keccak512 so need to set bytes as long + r, err := edwards25519.NewScalar().SetUniformBytes(hOut1[:]) + if err != nil { + return err + } + + // R = r*G + R := edwards25519.Point{} + R.ScalarBaseMult(r) + RBytes := R.Bytes() + + // s = H(R + pubkey + msg) + hEngine.Reset() + _, err = hEngine.Write(RBytes) + if err != nil { + return err + } + + _, err = hEngine.Write(privateKey[32:]) + if err != nil { + return err + } + + _, err = hEngine.Write(message) + if err != nil { + return err + } + + var hOut2 [64]byte + hEngine.Sum(hOut2[:0]) + + // hash output -> scalar + // Take 64 byte output from keccak512 so need to set bytes as long + h, err := edwards25519.NewScalar().SetUniformBytes(hOut2[:]) + if err != nil { + return err + } + + // s = (r + h * privKey) + s := edwards25519.NewScalar().MultiplyAdd(h, sc, r) + + copy(signature[:], RBytes) + copy(signature[32:], s.Bytes()) + + return nil +} + +// Verify reports whether sig is a valid signature of message by publicKey. It +// will panic if len(publicKey) is not PublicKeySize. +// Previously publicKey is of type PublicKey +func Verify(publicKey PublicKey, message, sig []byte) (bool, error) { + if l := len(publicKey); l != PublicKeySize { + return false, fmt.Errorf("ed25519: bad public key length: " + strconv.Itoa(l)) + } + + if len(sig) != SignatureSize || sig[63]&224 != 0 { + return false, fmt.Errorf("ed25519: bad signature size: " + strconv.Itoa(len(sig))) + } + + RBytes := sig[:32] + sBytes := sig[32:] + + var publicKeyBytes [32]byte + copy(publicKeyBytes[:], publicKey) + + A := edwards25519.Point{} + _, err := A.SetBytes(publicKeyBytes[:]) + if err != nil { + return false, err + } + + negA := edwards25519.Point{} + negA.Negate(&A) + + // h = H(R + pubkey + msg) + hEngine := sha3.NewLegacyKeccak512() + _, err = hEngine.Write(RBytes) + if err != nil { + return false, err + } + + _, err = hEngine.Write(publicKeyBytes[:]) + if err != nil { + return false, err + } + + _, err = hEngine.Write(message) + if err != nil { + return false, err + } + + var hOut1 [64]byte + hEngine.Sum(hOut1[:0]) + + // hash output -> scalar + // Take 64 byte output from keccak512 so need to set bytes as long + h, err := edwards25519.NewScalar().SetUniformBytes(hOut1[:]) + if err != nil { + return false, err + } + + // s was generated in sign so can set as canonical + s, err := edwards25519.NewScalar().SetCanonicalBytes(sBytes) + if err != nil { + return false, err + } + + // R' = s*G - h*Pubkey = h*negPubkey + s*G + RPrime := edwards25519.Point{} + RPrime.VarTimeDoubleScalarBaseMult(h, &negA, s) + RPrimeBytes := RPrime.Bytes() + + // Check R == R' + return bytes.Equal(RBytes, RPrimeBytes), nil +} diff --git a/pkg/crypto/signatures/schnorr/nem/ed25519_keccak_test.go b/pkg/crypto/signatures/schnorr/nem/ed25519_keccak_test.go new file mode 100755 index 000000000..39e0d6dad --- /dev/null +++ b/pkg/crypto/signatures/schnorr/nem/ed25519_keccak_test.go @@ -0,0 +1,190 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package nem + +import ( + "bytes" + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" +) + +type KeyPair struct { + Privkey string `json:"privateKey"` + Pubkey string `json:"publicKey"` +} + +type TestSig struct { + Privkey string `json:"privateKey"` + Pubkey string `json:"publicKey"` + Data string `json:"data"` + Length int `json:"length"` + Sig string `json:"signature"` +} + +// NOTE: NEM provides no test vectors for Keccak512, but has test vectors for Keccak256 +// We use Keccak256 and 512 in the exact same manner, so ensuring this test passes +// gives decent confidence in our Keccak512 use as well +func TestKeccak256SanityCheck(t *testing.T) { + data := "A6151D4904E18EC288243028CEDA30556E6C42096AF7150D6A7232CA5DBA52BD2192E23DAA5FA2BEA3D4BD95EFA2389CD193FCD3376E70A5C097B32C1C62C80AF9D710211545F7CDDDF63747420281D64529477C61E721273CFD78F8890ABB4070E97BAA52AC8FF61C26D195FC54C077DEF7A3F6F79B36E046C1A83CE9674BA1983EC2FB58947DE616DD797D6499B0385D5E8A213DB9AD5078A8E0C940FF0CB6BF92357EA5609F778C3D1FB1E7E36C35DB873361E2BE5C125EA7148EFF4A035B0CCE880A41190B2E22924AD9D1B82433D9C023924F2311315F07B88BFD42850047BF3BE785C4CE11C09D7E02065D30F6324365F93C5E7E423A07D754EB314B5FE9DB4614275BE4BE26AF017ABDC9C338D01368226FE9AF1FB1F815E7317BDBB30A0F36DC69" + toMatch := "4E9E79AB7434F6C7401FB3305D55052EE829B9E46D5D05D43B59FEFB32E9A619" + toMatchBytes, err := hex.DecodeString(toMatch) + require.NoError(t, err) + dataBytes, err := hex.DecodeString(data) + require.NoError(t, err) + k256 := sha3.NewLegacyKeccak256() + _, err = k256.Write(dataBytes) + require.NoError(t, err) + var hashed []byte + hashed = k256.Sum(hashed) + require.Equal(t, hashed, toMatchBytes) +} + +// Test that the pubkey can get derived correctly from privkey +func TestPrivToPubkey(t *testing.T) { + testVectors := GetPrivToPubkeyTestCases() + + for _, pair := range testVectors { + privkeyBytes, err := hex.DecodeString(pair.Privkey) + require.NoError(t, err) + pubkeyBytes, err := hex.DecodeString(pair.Pubkey) + require.NoError(t, err) + + privKeyCalced, err := NewKeyFromSeed(privkeyBytes) + require.NoError(t, err) + + pubKeyCalced := privKeyCalced.Public().(PublicKey) + + require.Equal(t, pubKeyCalced.Bytes(), pubkeyBytes) + } +} + +// Test that we can: +// Get pubkey from privkey +// Obtain the correct signature +// Verify the test vector provided signature +func TestSigs(t *testing.T) { + testVectors := GetSigTestCases() + + for _, ts := range testVectors { + // Test priv -> pubkey again + privkeyBytes, err := hex.DecodeString(ts.Privkey) + require.NoError(t, err) + pubkeyBytes, err := hex.DecodeString(ts.Pubkey) + require.NoError(t, err) + + privKeyCalced, err := NewKeyFromSeed(privkeyBytes) + require.NoError(t, err) + + pubKeyCalced := privKeyCalced.Public().(PublicKey) + + require.True(t, bytes.Equal(pubKeyCalced.Bytes(), pubkeyBytes)) + + dataBytes, err := hex.DecodeString(ts.Data) + require.NoError(t, err) + sigBytes, err := hex.DecodeString(ts.Sig) + require.NoError(t, err) + + // Test sign + sigCalced, err := Sign(privKeyCalced, dataBytes) + require.NoError(t, err) + + require.True(t, bytes.Equal(sigCalced, sigBytes)) + + // Test verify + verified, err := Verify(pubKeyCalced, dataBytes, sigBytes) + require.NoError(t, err) + + require.True(t, verified) + } +} + +// NOTE: Test cases were obtained from NEM +// See link: https://github.com/symbol/test-vectors +// Pulled 5 test vectors for each test case, at time of writing confirmed that all 10000 vectors passed +func GetPrivToPubkeyTestCases() []KeyPair { + var toReturn []KeyPair + + kp1 := KeyPair{ + Privkey: "575DBB3062267EFF57C970A336EBBC8FBCFE12C5BD3ED7BC11EB0481D7704CED", + Pubkey: "C5F54BA980FCBB657DBAAA42700539B207873E134D2375EFEAB5F1AB52F87844", + } + + kp2 := KeyPair{ + Privkey: "5B0E3FA5D3B49A79022D7C1E121BA1CBBF4DB5821F47AB8C708EF88DEFC29BFE", + Pubkey: "96EB2A145211B1B7AB5F0D4B14F8ABC8D695C7AEE31A3CFC2D4881313C68EEA3", + } + + kp3 := KeyPair{ + Privkey: "738BA9BB9110AEA8F15CAA353ACA5653B4BDFCA1DB9F34D0EFED2CE1325AEEDA", + Pubkey: "2D8425E4CA2D8926346C7A7CA39826ACD881A8639E81BD68820409C6E30D142A", + } + + kp4 := KeyPair{ + Privkey: "E8BF9BC0F35C12D8C8BF94DD3A8B5B4034F1063948E3CC5304E55E31AA4B95A6", + Pubkey: "4FEED486777ED38E44C489C7C4E93A830E4C4A907FA19A174E630EF0F6ED0409", + } + + kp5 := KeyPair{ + Privkey: "C325EA529674396DB5675939E7988883D59A5FC17A28CA977E3BA85370232A83", + Pubkey: "83EE32E4E145024D29BCA54F71FA335A98B3E68283F1A3099C4D4AE113B53E54", + } + + toReturn = append(toReturn, kp1, kp2, kp3, kp4, kp5) + + return toReturn +} + +func GetSigTestCases() []TestSig { + var toReturn []TestSig + + t1 := TestSig{ + Privkey: "ABF4CF55A2B3F742D7543D9CC17F50447B969E6E06F5EA9195D428AB12B7318D", + Pubkey: "8A558C728C21C126181E5E654B404A45B4F0137CE88177435A69978CC6BEC1F4", + Data: "8CE03CD60514233B86789729102EA09E867FC6D964DEA8C2018EF7D0A2E0E24BF7E348E917116690B9", + Length: 41, + Sig: "D9CEC0CC0E3465FAB229F8E1D6DB68AB9CC99A18CB0435F70DEB6100948576CD5C0AA1FEB550BDD8693EF81EB10A556A622DB1F9301986827B96716A7134230C", + } + + t2 := TestSig{ + Privkey: "6AA6DAD25D3ACB3385D5643293133936CDDDD7F7E11818771DB1FF2F9D3F9215", + Pubkey: "BBC8CBB43DDA3ECF70A555981A351A064493F09658FFFE884C6FAB2A69C845C6", + Data: "E4A92208A6FC52282B620699191EE6FB9CF04DAF48B48FD542C5E43DAA9897763A199AAA4B6F10546109F47AC3564FADE0", + Length: 49, + Sig: "98BCA58B075D1748F1C3A7AE18F9341BC18E90D1BEB8499E8A654C65D8A0B4FBD2E084661088D1E5069187A2811996AE31F59463668EF0F8CB0AC46A726E7902", + } + + t3 := TestSig{ + Privkey: "8E32BC030A4C53DE782EC75BA7D5E25E64A2A072A56E5170B77A4924EF3C32A9", + Pubkey: "72D0E65F1EDE79C4AF0BA7EC14204E10F0F7EA09F2BC43259CD60EA8C3A087E2", + Data: "13ED795344C4448A3B256F23665336645A853C5C44DBFF6DB1B9224B5303B6447FBF8240A2249C55", + Length: 40, + Sig: "EF257D6E73706BB04878875C58AA385385BF439F7040EA8297F7798A0EA30C1C5EFF5DDC05443F801849C68E98111AE65D088E726D1D9B7EECA2EB93B677860C", + } + + t4 := TestSig{ + Privkey: "C83CE30FCB5B81A51BA58FF827CCBC0142D61C13E2ED39E78E876605DA16D8D7", + Pubkey: "3EC8923F9EA5EA14F8AAA7E7C2784653ED8C7DE44E352EF9FC1DEE81FC3FA1A3", + Data: "A2704638434E9F7340F22D08019C4C8E3DBEE0DF8DD4454A1D70844DE11694F4C8CA67FDCB08FED0CEC9ABB2112B5E5F89", + Length: 49, + Sig: "0C684E71B35FED4D92B222FC60561DB34E0D8AFE44BDD958AAF4EE965911BEF5991236F3E1BCED59FC44030693BCAC37F34D29E5AE946669DC326E706E81B804", + } + + t5 := TestSig{ + Privkey: "2DA2A0AAE0F37235957B51D15843EDDE348A559692D8FA87B94848459899FC27", + Pubkey: "D73D0B14A9754EEC825FCB25EF1CFA9AE3B1370074EDA53FC64C22334A26C254", + Data: "D2488E854DBCDFDB2C9D16C8C0B2FDBC0ABB6BAC991BFE2B14D359A6BC99D66C00FD60D731AE06D0", + Length: 40, + Sig: "6F17F7B21EF9D6907A7AB104559F77D5A2532B557D95EDFFD6D88C073D87AC00FC838FC0D05282A0280368092A4BD67E95C20F3E14580BE28D8B351968C65E03", + } + + toReturn = append(toReturn, t1, t2, t3, t4, t5) + + return toReturn +} diff --git a/pkg/crypto/subtle/hkdf.go b/pkg/crypto/subtle/hkdf.go new file mode 100644 index 000000000..f8d146f8d --- /dev/null +++ b/pkg/crypto/subtle/hkdf.go @@ -0,0 +1,55 @@ +package subtle + +import ( + "errors" + "fmt" + "io" + + "golang.org/x/crypto/hkdf" +) + +const ( + // Minimum tag size in bytes. This provides minimum 80-bit security strength. + minTagSizeInBytes = uint32(10) +) + +var errHKDFInvalidInput = errors.New("HKDF: invalid input") + +// validateHKDFParams validates parameters of HKDF constructor. +func validateHKDFParams(hash string, _ uint32, tagSize uint32) error { + // validate tag size + digestSize, err := GetHashDigestSize(hash) + if err != nil { + return err + } + if tagSize > 255*digestSize { + return fmt.Errorf("tag size too big") + } + if tagSize < minTagSizeInBytes { + return fmt.Errorf("tag size too small") + } + return nil +} + +// ComputeHKDF extracts a pseudorandom key. +func ComputeHKDF(hashAlg string, key []byte, salt []byte, info []byte, tagSize uint32) ([]byte, error) { + keySize := uint32(len(key)) + if err := validateHKDFParams(hashAlg, keySize, tagSize); err != nil { + return nil, fmt.Errorf("hkdf: %s", err) + } + hashFunc := GetHashFunc(hashAlg) + if hashFunc == nil { + return nil, fmt.Errorf("hkdf: invalid hash algorithm") + } + if len(salt) == 0 { + salt = make([]byte, hashFunc().Size()) + } + + result := make([]byte, tagSize) + kdf := hkdf.New(hashFunc, key, salt, info) + n, err := io.ReadFull(kdf, result) + if n != len(result) || err != nil { + return nil, fmt.Errorf("compute of hkdf failed") + } + return result, nil +} diff --git a/pkg/crypto/subtle/random/random.go b/pkg/crypto/subtle/random/random.go new file mode 100644 index 000000000..9bfc537a3 --- /dev/null +++ b/pkg/crypto/subtle/random/random.go @@ -0,0 +1,22 @@ +package random + +import ( + "crypto/rand" + "encoding/binary" +) + +// GetRandomBytes randomly generates n bytes. +func GetRandomBytes(n uint32) []byte { + buf := make([]byte, n) + _, err := rand.Read(buf) + if err != nil { + panic(err) // out of randomness, should never happen + } + return buf +} + +// GetRandomUint32 randomly generates an unsigned 32-bit integer. +func GetRandomUint32() uint32 { + b := GetRandomBytes(4) + return binary.BigEndian.Uint32(b) +} diff --git a/pkg/crypto/subtle/subtle.go b/pkg/crypto/subtle/subtle.go new file mode 100644 index 000000000..88754fbe8 --- /dev/null +++ b/pkg/crypto/subtle/subtle.go @@ -0,0 +1,130 @@ +package subtle + +import ( + "crypto/elliptic" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "errors" + "hash" + "math/big" +) + +var errNilHashFunc = errors.New("nil hash function") + +// hashDigestSize maps hash algorithms to their digest size in bytes. +var hashDigestSize = map[string]uint32{ + "SHA1": uint32(20), + "SHA224": uint32(28), + "SHA256": uint32(32), + "SHA384": uint32(48), + "SHA512": uint32(64), +} + +// GetHashDigestSize returns the digest size of the specified hash algorithm. +func GetHashDigestSize(hash string) (uint32, error) { + digestSize, ok := hashDigestSize[hash] + if !ok { + return 0, errors.New("invalid hash algorithm") + } + return digestSize, nil +} + +// TODO(ckl): Perhaps return an explicit error instead of ""/nil for the +// following functions. + +// ConvertHashName converts different forms of a hash name to the +// hash name that tink recognizes. +func ConvertHashName(name string) string { + switch name { + case "SHA-224": + return "SHA224" + case "SHA-256": + return "SHA256" + case "SHA-384": + return "SHA384" + case "SHA-512": + return "SHA512" + case "SHA-1": + return "SHA1" + default: + return "" + } +} + +// ConvertCurveName converts different forms of a curve name to the +// name that tink recognizes. +func ConvertCurveName(name string) string { + switch name { + case "secp256r1", "P-256": + return "NIST_P256" + case "secp384r1", "P-384": + return "NIST_P384" + case "secp521r1", "P-521": + return "NIST_P521" + default: + return "" + } +} + +// GetHashFunc returns the corresponding hash function of the given hash name. +func GetHashFunc(hash string) func() hash.Hash { + switch hash { + case "SHA1": + return sha1.New + case "SHA224": + return sha256.New224 + case "SHA256": + return sha256.New + case "SHA384": + return sha512.New384 + case "SHA512": + return sha512.New + default: + return nil + } +} + +// GetCurve returns the curve object that corresponds to the given curve type. +// It returns null if the curve type is not supported. +func GetCurve(curve string) elliptic.Curve { + switch curve { + case "NIST_P256": + return elliptic.P256() + case "NIST_P384": + return elliptic.P384() + case "NIST_P521": + return elliptic.P521() + default: + return nil + } +} + +// ComputeHash calculates a hash of the given data using the given hash function. +func ComputeHash(hashFunc func() hash.Hash, data []byte) ([]byte, error) { + if hashFunc == nil { + return nil, errNilHashFunc + } + h := hashFunc() + + _, err := h.Write(data) + if err != nil { + return nil, err + } + + return h.Sum(nil), nil +} + +// NewBigIntFromHex returns a big integer from a hex string. +func NewBigIntFromHex(s string) (*big.Int, error) { + if len(s)%2 == 1 { + s = "0" + s + } + b, err := hex.DecodeString(s) + if err != nil { + return nil, err + } + ret := new(big.Int).SetBytes(b) + return ret, nil +} diff --git a/pkg/crypto/subtle/x25519.go b/pkg/crypto/subtle/x25519.go new file mode 100644 index 000000000..7a869c552 --- /dev/null +++ b/pkg/crypto/subtle/x25519.go @@ -0,0 +1,25 @@ +package subtle + +import ( + "crypto/rand" + + "golang.org/x/crypto/curve25519" +) + +// GeneratePrivateKeyX25519 generates a new 32-byte private key. +func GeneratePrivateKeyX25519() ([]byte, error) { + privKey := make([]byte, curve25519.ScalarSize) + _, err := rand.Read(privKey) + return privKey, err +} + +// ComputeSharedSecretX25519 returns the 32-byte shared key, i.e. +// privKey * pubValue on the curve. +func ComputeSharedSecretX25519(privKey, pubValue []byte) ([]byte, error) { + return curve25519.X25519(privKey, pubValue) +} + +// PublicFromPrivateX25519 computes privKey's corresponding public key. +func PublicFromPrivateX25519(privKey []byte) ([]byte, error) { + return ComputeSharedSecretX25519(privKey, curve25519.Basepoint) +} diff --git a/pkg/crypto/tecdsa/dklsv1/README.md b/pkg/crypto/tecdsa/dklsv1/README.md new file mode 100755 index 000000000..738ec9dbd --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/README.md @@ -0,0 +1,13 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## Secure Two-party Threshold ECDSA from ECDSA Assumptions + +Package dkls implements the 2-of-2 threshold ECDSA signing algorithm of +[Secure Two-party Threshold ECDSA from ECDSA Assumptions](https://eprint.iacr.org/2018/499). diff --git a/pkg/crypto/tecdsa/dklsv1/boilerplate.go b/pkg/crypto/tecdsa/dklsv1/boilerplate.go new file mode 100755 index 000000000..d2df3aa0f --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/boilerplate.go @@ -0,0 +1,416 @@ +package dklsv1 + +import ( + "hash" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/protocol" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/refresh" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/sign" +) + +// AliceDkg DKLS DKG implementation that satisfies the protocol iterator interface. +type AliceDkg struct { + protoStepper + *dkg.Alice +} + +// BobDkg DKLS DKG implementation that satisfies the protocol iterator interface. +type BobDkg struct { + protoStepper + *dkg.Bob +} + +// AliceSign DKLS sign implementation that satisfies the protocol iterator interface. +type AliceSign struct { + protoStepper + *sign.Alice +} + +// BobSign DKLS sign implementation that satisfies the protocol iterator interface. +type BobSign struct { + protoStepper + *sign.Bob +} + +// AliceRefresh DKLS refresh implementation that satisfies the protocol iterator interface. +type AliceRefresh struct { + protoStepper + *refresh.Alice +} + +// BobRefresh DKLS refresh implementation that satisfies the protocol iterator interface. +type BobRefresh struct { + protoStepper + *refresh.Bob +} + +var ( + // Static type assertions + _ protocol.Iterator = &AliceDkg{} + _ protocol.Iterator = &BobDkg{} + _ protocol.Iterator = &AliceSign{} + _ protocol.Iterator = &BobSign{} + _ protocol.Iterator = &AliceRefresh{} + _ protocol.Iterator = &BobRefresh{} +) + +// NewAliceDkg creates a new protocol that can compute a DKG as Alice +func NewAliceDkg(curve *curves.Curve, version uint) *AliceDkg { + a := &AliceDkg{Alice: dkg.NewAlice(curve)} + a.steps = []func(*protocol.Message) (*protocol.Message, error){ + func(input *protocol.Message) (*protocol.Message, error) { + bobSeed, err := decodeDkgRound2Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + roundOutput, err := a.Round2CommitToProof(bobSeed) + if err != nil { + return nil, err + } + return encodeDkgRound2Output(roundOutput, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + proof, err := decodeDkgRound4Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + aliceProof, err := a.Round4VerifyAndReveal(proof) + if err != nil { + return nil, err + } + return encodeDkgRound4Output(aliceProof, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + proof, err := decodeDkgRound6Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + choices, err := a.Round6DkgRound2Ot(proof) + if err != nil { + return nil, err + } + return encodeDkgRound6Output(choices, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + challenge, err := decodeDkgRound8Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + responses, err := a.Round8DkgRound4Ot(challenge) + if err != nil { + return nil, err + } + return encodeDkgRound8Output(responses, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + opening, err := decodeDkgRound10Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + if err := a.Round10DkgRound6Ot(opening); err != nil { + return nil, err + } + return nil, nil + }, + } + return a +} + +// Result Returns an encoded version of Alice as sequence of bytes that can be used to initialize an AliceSign protocol. +func (a *AliceDkg) Result(version uint) (*protocol.Message, error) { + // Sanity check + if !a.complete() { + return nil, nil + } + if a.Alice == nil { + return nil, protocol.ErrNotInitialized + } + + result := a.Output() + return EncodeAliceDkgOutput(result, version) +} + +// NewBobDkg Creates a new protocol that can compute a DKG as Bob. +func NewBobDkg(curve *curves.Curve, version uint) *BobDkg { + b := &BobDkg{Bob: dkg.NewBob(curve)} + b.steps = []func(message *protocol.Message) (*protocol.Message, error){ + func(*protocol.Message) (*protocol.Message, error) { + commitment, err := b.Round1GenerateRandomSeed() + if err != nil { + return nil, err + } + return encodeDkgRound1Output(commitment, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + round3Input, err := decodeDkgRound3Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + bobProof, err := b.Round3SchnorrProve(round3Input) + if err != nil { + return nil, err + } + return encodeDkgRound3Output(bobProof, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + proof, err := decodeDkgRound5Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + bobProof, err := b.Round5DecommitmentAndStartOt(proof) + if err != nil { + return nil, err + } + return encodeDkgRound5Output(bobProof, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + choices, err := decodeDkgRound7Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + challenge, err := b.Round7DkgRound3Ot(choices) + if err != nil { + return nil, err + } + return encodeDkgRound7Output(challenge, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + responses, err := decodeDkgRound9Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + opening, err := b.Round9DkgRound5Ot(responses) + if err != nil { + return nil, err + } + return encodeDkgRound9Output(opening, version) + }, + } + return b +} + +// Result returns an encoded version of Bob as sequence of bytes that can be used to initialize an BobSign protocol. +func (b *BobDkg) Result(version uint) (*protocol.Message, error) { + // Sanity check + if !b.complete() { + return nil, nil + } + if b.Bob == nil { + return nil, protocol.ErrNotInitialized + } + + result := b.Output() + return EncodeBobDkgOutput(result, version) +} + +// NewAliceSign creates a new protocol that can compute a signature as Alice. +// Requires dkg state that was produced at the end of DKG.Output(). +func NewAliceSign(curve *curves.Curve, hash hash.Hash, message []byte, dkgResultMessage *protocol.Message, version uint) (*AliceSign, error) { + dkgResult, err := DecodeAliceDkgResult(dkgResultMessage) + if err != nil { + return nil, errors.WithStack(err) + } + a := &AliceSign{Alice: sign.NewAlice(curve, hash, dkgResult)} + a.steps = []func(message *protocol.Message) (*protocol.Message, error){ + func(*protocol.Message) (*protocol.Message, error) { + aliceCommitment, err := a.Round1GenerateRandomSeed() + if err != nil { + return nil, err + } + return encodeSignRound1Output(aliceCommitment, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + round2Output, err := decodeSignRound3Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + round3Output, err := a.Round3Sign(message, round2Output) + if err != nil { + return nil, errors.WithStack(err) + } + return encodeSignRound3Output(round3Output, version) + }, + } + return a, nil +} + +// NewBobSign creates a new protocol that can compute a signature as Bob. +// Requires dkg state that was produced at the end of DKG.Output(). +func NewBobSign(curve *curves.Curve, hash hash.Hash, message []byte, dkgResultMessage *protocol.Message, version uint) (*BobSign, error) { + dkgResult, err := DecodeBobDkgResult(dkgResultMessage) + if err != nil { + return nil, errors.WithStack(err) + } + b := &BobSign{Bob: sign.NewBob(curve, hash, dkgResult)} + b.steps = []func(message *protocol.Message) (*protocol.Message, error){ + func(input *protocol.Message) (*protocol.Message, error) { + commitment, err := decodeSignRound2Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + round2Output, err := b.Round2Initialize(commitment) + if err != nil { + return nil, errors.WithStack(err) + } + return encodeSignRound2Output(round2Output, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + round4Input, err := decodeSignRound4Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + + if err = b.Round4Final(message, round4Input); err != nil { + return nil, errors.WithStack(err) + } + return nil, nil + }, + } + return b, nil +} + +// Result always returns an error. +// Alice does not compute a signature in the DKLS protocol; only Bob computes the signature. +func (a *AliceSign) Result(_ uint) (*protocol.Message, error) { + return nil, errors.New("dkls.Alice does not produce a signature") +} + +// Result returns the signature that Bob computed as a *core.EcdsaSignature if the signing protocol completed successfully. +func (b *BobSign) Result(version uint) (*protocol.Message, error) { + // We can't produce a signature until the protocol completes + if !b.complete() { + return nil, nil + } + if b.Bob == nil { + // Object wasn't created with NewXSign() + return nil, protocol.ErrNotInitialized + } + return encodeSignature(b.Bob.Signature, version) +} + +// NewAliceRefresh creates a new protocol that can compute a key refresh as Alice +func NewAliceRefresh(curve *curves.Curve, dkgResultMessage *protocol.Message, version uint) (*AliceRefresh, error) { + dkgResult, err := DecodeAliceDkgResult(dkgResultMessage) + if err != nil { + return nil, errors.WithStack(err) + } + + a := &AliceRefresh{Alice: refresh.NewAlice(curve, dkgResult)} + a.steps = []func(*protocol.Message) (*protocol.Message, error){ + func(_ *protocol.Message) (*protocol.Message, error) { + aliceSeed := a.Round1RefreshGenerateSeed() + return encodeRefreshRound1Output(aliceSeed, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + round3Input, err := decodeRefreshRound3Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + round3Output, err := a.Round3RefreshMultiplyRound2Ot(round3Input) + if err != nil { + return nil, err + } + return encodeRefreshRound3Output(round3Output, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + round5Input, err := decodeRefreshRound5Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + round5Output, err := a.Round5RefreshRound4Ot(round5Input) + if err != nil { + return nil, err + } + return encodeRefreshRound5Output(round5Output, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + round7Input, err := decodeRefreshRound7Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + if err := a.Round7DkgRound6Ot(round7Input); err != nil { + return nil, err + } + return nil, nil + }, + } + return a, nil +} + +// Result Returns an encoded version of Alice as sequence of bytes that can be used to initialize an AliceSign protocol. +func (a *AliceRefresh) Result(version uint) (*protocol.Message, error) { + // Sanity check + if !a.complete() { + return nil, nil + } + if a.Alice == nil { + return nil, protocol.ErrNotInitialized + } + + result := a.Output() + return EncodeAliceDkgOutput(result, version) +} + +// NewBobRefresh Creates a new protocol that can compute a refresh as Bob. +func NewBobRefresh(curve *curves.Curve, dkgResultMessage *protocol.Message, version uint) (*BobRefresh, error) { + dkgResult, err := DecodeBobDkgResult(dkgResultMessage) + if err != nil { + return nil, errors.WithStack(err) + } + + b := &BobRefresh{Bob: refresh.NewBob(curve, dkgResult)} + b.steps = []func(message *protocol.Message) (*protocol.Message, error){ + func(input *protocol.Message) (*protocol.Message, error) { + round2Input, err := decodeRefreshRound2Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + round2Output, err := b.Round2RefreshProduceSeedAndMultiplyAndStartOT(round2Input) + if err != nil { + return nil, err + } + return encodeRefreshRound2Output(round2Output, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + round4Input, err := decodeRefreshRound4Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + round4Output, err := b.Round4RefreshRound3Ot(round4Input) + if err != nil { + return nil, err + } + return encodeRefreshRound4Output(round4Output, version) + }, + func(input *protocol.Message) (*protocol.Message, error) { + round6Input, err := decodeRefreshRound6Input(input) + if err != nil { + return nil, errors.WithStack(err) + } + round6Output, err := b.Round6RefreshRound5Ot(round6Input) + if err != nil { + return nil, err + } + return encodeRefreshRound6Output(round6Output, version) + }, + } + return b, nil +} + +// Result returns an encoded version of Bob as sequence of bytes that can be used to initialize an BobSign protocol. +func (b *BobRefresh) Result(version uint) (*protocol.Message, error) { + // Sanity check + if !b.complete() { + return nil, nil + } + if b.Bob == nil { + return nil, protocol.ErrNotInitialized + } + + result := b.Output() + return EncodeBobDkgOutput(result, version) +} diff --git a/pkg/crypto/tecdsa/dklsv1/dealer/dealer.go b/pkg/crypto/tecdsa/dklsv1/dealer/dealer.go new file mode 100755 index 000000000..9111396b2 --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/dealer/dealer.go @@ -0,0 +1,83 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package dealer implements key generation via a trusted dealer for the protocol [DKLs18](https://eprint.iacr.org/2018/499.pdf). +// The trusted dealer produces the same output as the corresponding DKG protocol and can be used for signing without +// additional modifications. +// Note that running actual DKG is ALWAYS recommended over a trusted dealer. +package dealer + +import ( + "crypto/rand" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" +) + +// GenerationAndDeal produces private key material for alice and bob which they can later use in signing. +// Running actual DKG is ALWAYS recommended over using this function, as this function breaks the security guarantees of DKG. +// only use this function if you have a very good reason to. +func GenerateAndDeal(curve *curves.Curve) (*dkg.AliceOutput, *dkg.BobOutput, error) { + aliceSecretShare, bobSecretShare, publicKey := produceKeyShares(curve) + aliceOTOutput, bobOTOutput, err := produceOTResults(curve) + if err != nil { + return nil, nil, errors.Wrap(err, "couldn't produce OT results") + } + alice := &dkg.AliceOutput{ + PublicKey: publicKey, + SecretKeyShare: aliceSecretShare, + SeedOtResult: aliceOTOutput, + } + bob := &dkg.BobOutput{ + PublicKey: publicKey, + SecretKeyShare: bobSecretShare, + SeedOtResult: bobOTOutput, + } + return alice, bob, nil +} + +func produceKeyShares(curve *curves.Curve) (aliceSecretShare curves.Scalar, bobSecretShare curves.Scalar, publicKey curves.Point) { + aliceSecretShare = curve.Scalar.Random(rand.Reader) + bobSecretShare = curve.Scalar.Random(rand.Reader) + publicKey = curve.ScalarBaseMult(aliceSecretShare.Mul(bobSecretShare)) + return aliceSecretShare, bobSecretShare, publicKey +} + +func produceOTResults(curve *curves.Curve) (*simplest.ReceiverOutput, *simplest.SenderOutput, error) { + oneTimePadEncryptionKeys := make([]simplest.OneTimePadEncryptionKeys, kos.Kappa) + oneTimePadDecryptionKey := make([]simplest.OneTimePadDecryptionKey, kos.Kappa) + + // we'll need a receiver because in its constructor random bits will be selected. + receiver, err := simplest.NewReceiver(curve, kos.Kappa, [simplest.DigestSize]byte{}) + if err != nil { + return nil, nil, errors.Wrap(err, "couldn't initialize a receiver") + } + packedRandomChoiceBits, randomChoiceBits := receiver.Output.PackedRandomChoiceBits, receiver.Output.RandomChoiceBits + + for i := 0; i < kos.Kappa; i++ { + if _, err := rand.Read(oneTimePadEncryptionKeys[i][0][:]); err != nil { + return nil, nil, errors.WithStack(err) + } + if _, err := rand.Read(oneTimePadEncryptionKeys[i][1][:]); err != nil { + return nil, nil, errors.WithStack(err) + } + oneTimePadDecryptionKey[i] = oneTimePadEncryptionKeys[i][randomChoiceBits[i]] + } + + senderOutput := &simplest.SenderOutput{ + OneTimePadEncryptionKeys: oneTimePadEncryptionKeys, + } + receiverOutput := &simplest.ReceiverOutput{ + PackedRandomChoiceBits: packedRandomChoiceBits, + RandomChoiceBits: randomChoiceBits, + OneTimePadDecryptionKey: oneTimePadDecryptionKey, + } + return receiverOutput, senderOutput, nil +} diff --git a/pkg/crypto/tecdsa/dklsv1/dealer/dealer_test.go b/pkg/crypto/tecdsa/dklsv1/dealer/dealer_test.go new file mode 100755 index 000000000..e680edffb --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/dealer/dealer_test.go @@ -0,0 +1,49 @@ +package dealer_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dealer" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/sign" +) + +func Test_DealerCanGenerateKeysThatSign(t *testing.T) { + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + aliceOutput, bobOutput, err := dealer.GenerateAndDeal(curve) + require.NoError(t, err) + + alice := sign.NewAlice(curve, sha3.New256(), aliceOutput) + bob := sign.NewBob(curve, sha3.New256(), bobOutput) + + message := []byte("A message.") + seed, err := alice.Round1GenerateRandomSeed() + require.NoError(t, err) + round3Output, err := bob.Round2Initialize(seed) + require.NoError(t, err) + round4Output, err := alice.Round3Sign(message, round3Output) + require.NoError(t, err) + err = bob.Round4Final(message, round4Output) + require.NoError(t, err, "curve: %s", curve.Name) + } +} + +func Test_DealerGeneratesDifferentResultsEachTime(t *testing.T) { + curve := curves.K256() + aliceOutput1, bobOutput1, err := dealer.GenerateAndDeal(curve) + require.NoError(t, err) + aliceOutput2, bobOutput2, err := dealer.GenerateAndDeal(curve) + require.NoError(t, err) + + require.NotEqual(t, aliceOutput1.SecretKeyShare, aliceOutput2.SecretKeyShare) + require.NotEqual(t, bobOutput1.SecretKeyShare, bobOutput2.SecretKeyShare) + require.NotEqualValues(t, aliceOutput1.SeedOtResult.RandomChoiceBits, aliceOutput2.SeedOtResult.RandomChoiceBits) + require.NotEqualValues(t, bobOutput1.SeedOtResult.OneTimePadEncryptionKeys, bobOutput2.SeedOtResult.OneTimePadEncryptionKeys) +} diff --git a/pkg/crypto/tecdsa/dklsv1/dkg/dkg.go b/pkg/crypto/tecdsa/dklsv1/dkg/dkg.go new file mode 100755 index 000000000..21b6da307 --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/dkg/dkg.go @@ -0,0 +1,272 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package dkg implements the Distributed Key Generation (DKG) protocol of [DKLs18](https://eprint.iacr.org/2018/499.pdf). +// The DKG protocol is defined in "Protocol 2" page 7, of the paper. The Zero Knowledge Proof ideal functionalities are +// realized using schnorr proofs. Moreover, the seed OT is realized using the Verified Simplest OT protocol. +package dkg + +import ( + "crypto/rand" + + "github.com/gtank/merlin" + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" + "github.com/onsonr/sonr/pkg/crypto/zkp/schnorr" +) + +// AliceOutput is the result of running DKG for Alice. It contains both the public and secret values that are needed +// for signing. +type AliceOutput struct { + // PublicKey is the joint public key of Alice and Bob. + // This value is public. + PublicKey curves.Point + + // SecretKeyShare is Alice's secret key for the joint public key. + // This output must be kept secret. If it is lost, the users will lose access and cannot create signatures. + SecretKeyShare curves.Scalar + + // SeedOtResult are the outputs that the receiver will obtain as a result of running the "random" OT protocol. + // This output must be kept secret. Although, if it is lost the users can run another OT protocol and obtain + // new values to replace it. + SeedOtResult *simplest.ReceiverOutput +} + +// BobOutput is the result of running DKG for Bob. It contains both the public and secret values that are needed +// for signing. +type BobOutput struct { + // PublicKey is the joint public key of Alice and Bob. + // This value is public. + PublicKey curves.Point + + // SecretKeyShare is Bob's secret key for the joint public key. + // This output must be kept secret. If it is lost, the users will lose access and cannot create signatures. + SecretKeyShare curves.Scalar + + // SeedOtResult are the outputs that the sender will obtain as a result of running the "random" OT protocol. + // This output must be kept secret. Although, if it is lost the users can run another OT protocol and obtain + // new values to replace it. + SeedOtResult *simplest.SenderOutput +} + +// Alice struct encoding Alice's state during one execution of the overall signing algorithm. +// At the end of the joint computation, Alice will NOT obtain the signature. +type Alice struct { + // prover is a schnorr prover for Alice's portion of public key. + prover *schnorr.Prover + + // proof is alice's proof to her portion of the public key. It is stored as an intermediate value, during commitment phase. + proof *schnorr.Proof + + // receiver is the base OT receiver. + receiver *simplest.Receiver + + // secretKeyShare is Alice's secret key for the joint public key. + secretKeyShare curves.Scalar + + // publicKey is the joint public key of Alice and Bob. + publicKey curves.Point + + curve *curves.Curve + + transcript *merlin.Transcript +} + +// Bob struct encoding Bob's state during one execution of the overall signing algorithm. +// At the end of the joint computation, Bob will obtain the signature. +type Bob struct { + // prover is a schnorr prover for Bob's portion of public key. + prover *schnorr.Prover // this is a "schnorr statement" for pkB. + + // sender is the base OT sender. + sender *simplest.Sender + + // secretKeyShare is Bob's secret key for the joint public key. + secretKeyShare curves.Scalar + + // publicKey is the joint public key of Alice and Bob. + publicKey curves.Point + + // schnorr proof commitment to Alice's schnorr proof. + aliceCommitment schnorr.Commitment + // 32-byte transcript salt which will be used for Alice's schnorr proof + aliceSalt [simplest.DigestSize]byte + + curve *curves.Curve + + transcript *merlin.Transcript +} + +// Round2Output contains the output of the 2nd round of DKG. +type Round2Output struct { + // Seed is the random value used to derive the joint unique session id. + Seed [simplest.DigestSize]byte + + // Commitment is the commitment to the ZKP to Alice's secret key share. + Commitment schnorr.Commitment +} + +// NewAlice creates a party that can participate in 2-of-2 DKG and threshold signature. +func NewAlice(curve *curves.Curve) *Alice { + return &Alice{ + curve: curve, + transcript: merlin.NewTranscript("Coinbase_DKLs_DKG"), + } +} + +// NewBob creates a party that can participate in 2-of-2 DKG and threshold signature. This party +// is the receiver of the signature at the end. +func NewBob(curve *curves.Curve) *Bob { + return &Bob{ + curve: curve, + transcript: merlin.NewTranscript("Coinbase_DKLs_DKG"), + } +} + +// Round1GenerateRandomSeed Bob flips random coins, and sends these to Alice +// in this round, Bob flips 32 random bytes and sends them to Alice. +// note that this is not _explicitly_ given as part of the protocol in https://eprint.iacr.org/2018/499.pdf, Protocol 1). +// rather, it is part of our generation of a unique session identifier, for use in subsequent schnorr proofs / seed OT / etc. +// we do it by having each party sample 32 bytes, then by appending _both_ as salts. secure if either party is honest +func (bob *Bob) Round1GenerateRandomSeed() ([simplest.DigestSize]byte, error) { + bobSeed := [simplest.DigestSize]byte{} + if _, err := rand.Read(bobSeed[:]); err != nil { + return [simplest.DigestSize]byte{}, errors.Wrap(err, "generating random bytes in bob DKG round 1 generate") + } + bob.transcript.AppendMessage([]byte("session_id_bob"), bobSeed[:]) // note: bob appends first here + return bobSeed, nil +} + +// Round2CommitToProof steps 1) and 2) of protocol 2 on page 7. +func (alice *Alice) Round2CommitToProof(bobSeed [simplest.DigestSize]byte) (*Round2Output, error) { + aliceSeed := [simplest.DigestSize]byte{} + if _, err := rand.Read(aliceSeed[:]); err != nil { + return nil, errors.Wrap(err, "generating random bytes in bob DKG round 1 generate") + } + alice.transcript.AppendMessage([]byte("session_id_bob"), bobSeed[:]) + alice.transcript.AppendMessage([]byte("session_id_alice"), aliceSeed[:]) + + var err error + uniqueSessionId := [simplest.DigestSize]byte{} // note: will use and re-use this below for sub-session IDs. + copy(uniqueSessionId[:], alice.transcript.ExtractBytes([]byte("salt for simplest OT"), simplest.DigestSize)) + alice.receiver, err = simplest.NewReceiver(alice.curve, kos.Kappa, uniqueSessionId) + if err != nil { + return nil, errors.Wrap(err, "alice constructing new seed OT receiver in Alice DKG round 1") + } + + alice.secretKeyShare = alice.curve.Scalar.Random(rand.Reader) + copy(uniqueSessionId[:], alice.transcript.ExtractBytes([]byte("salt for alice schnorr"), simplest.DigestSize)) + alice.prover = schnorr.NewProver(alice.curve, nil, uniqueSessionId[:]) + var commitment schnorr.Commitment + alice.proof, commitment, err = alice.prover.ProveCommit(alice.secretKeyShare) // will mutate `pkA` + if err != nil { + return nil, errors.Wrap(err, "prove + commit in alice DKG Commit round 1") + } + return &Round2Output{ + Commitment: commitment, + Seed: aliceSeed, + }, nil +} + +// Round3SchnorrProve receives Bob's Commitment and returns schnorr statment + proof. +// Steps 1 and 3 of protocol 2 on page 7. +func (bob *Bob) Round3SchnorrProve(round2Output *Round2Output) (*schnorr.Proof, error) { + bob.transcript.AppendMessage([]byte("session_id_alice"), round2Output.Seed[:]) + + bob.aliceCommitment = round2Output.Commitment // store it, so that we can check when alice decommits + + var err error + uniqueSessionId := [simplest.DigestSize]byte{} // note: will use and re-use this below for sub-session IDs. + copy(uniqueSessionId[:], bob.transcript.ExtractBytes([]byte("salt for simplest OT"), simplest.DigestSize)) + bob.sender, err = simplest.NewSender(bob.curve, kos.Kappa, uniqueSessionId) + if err != nil { + return nil, errors.Wrap(err, "bob constructing new OT sender in DKG round 2") + } + // extract alice's salt in the right order; we won't use this until she reveals her proof and we verify it below + copy(bob.aliceSalt[:], bob.transcript.ExtractBytes([]byte("salt for alice schnorr"), simplest.DigestSize)) + bob.secretKeyShare = bob.curve.Scalar.Random(rand.Reader) + copy(uniqueSessionId[:], bob.transcript.ExtractBytes([]byte("salt for bob schnorr"), simplest.DigestSize)) + bob.prover = schnorr.NewProver(bob.curve, nil, uniqueSessionId[:]) + proof, err := bob.prover.Prove(bob.secretKeyShare) + if err != nil { + return nil, errors.Wrap(err, "bob schnorr proving in DKG round 2") + } + return proof, err +} + +// Round4VerifyAndReveal step 4 of protocol 2 on page 7. +func (alice *Alice) Round4VerifyAndReveal(proof *schnorr.Proof) (*schnorr.Proof, error) { + var err error + uniqueSessionId := [simplest.DigestSize]byte{} + copy(uniqueSessionId[:], alice.transcript.ExtractBytes([]byte("salt for bob schnorr"), simplest.DigestSize)) + if err = schnorr.Verify(proof, alice.curve, nil, uniqueSessionId[:]); err != nil { + return nil, errors.Wrap(err, "alice's verification of Bob's schnorr proof failed in DKG round 3") + } + alice.publicKey = proof.Statement.Mul(alice.secretKeyShare) + return alice.proof, nil +} + +// Round5DecommitmentAndStartOt step 5 of protocol 2 on page 7. +func (bob *Bob) Round5DecommitmentAndStartOt(proof *schnorr.Proof) (*schnorr.Proof, error) { + var err error + if err = schnorr.DecommitVerify(proof, bob.aliceCommitment, bob.curve, nil, bob.aliceSalt[:]); err != nil { + return nil, errors.Wrap(err, "decommit + verify failed in bob's DKG round 4") + } + bob.publicKey = proof.Statement.Mul(bob.secretKeyShare) + seedOTRound1Output, err := bob.sender.Round1ComputeAndZkpToPublicKey() + if err != nil { + return nil, errors.Wrap(err, "bob computing round 1 of seed OT within DKG round 4") + } + return seedOTRound1Output, nil +} + +// Round6DkgRound2Ot is a thin wrapper around the 2nd round of seed OT protocol. +func (alice *Alice) Round6DkgRound2Ot(proof *schnorr.Proof) ([]simplest.ReceiversMaskedChoices, error) { + return alice.receiver.Round2VerifySchnorrAndPadTransfer(proof) +} + +// Round7DkgRound3Ot is a thin wrapper around the 3rd round of seed OT protocol. +func (bob *Bob) Round7DkgRound3Ot(compressedReceiversMaskedChoice []simplest.ReceiversMaskedChoices) ([]simplest.OtChallenge, error) { + return bob.sender.Round3PadTransfer(compressedReceiversMaskedChoice) +} + +// Round8DkgRound4Ot is a thin wrapper around the 4th round of seed OT protocol. +func (alice *Alice) Round8DkgRound4Ot(challenge []simplest.OtChallenge) ([]simplest.OtChallengeResponse, error) { + return alice.receiver.Round4RespondToChallenge(challenge) +} + +// Round9DkgRound5Ot is a thin wrapper around the 5th round of seed OT protocol. +func (bob *Bob) Round9DkgRound5Ot(challengeResponses []simplest.OtChallengeResponse) ([]simplest.ChallengeOpening, error) { + return bob.sender.Round5Verify(challengeResponses) +} + +// Round10DkgRound6Ot is a thin wrapper around the 6th round of seed OT protocol. +func (alice *Alice) Round10DkgRound6Ot(challengeOpenings []simplest.ChallengeOpening) error { + return alice.receiver.Round6Verify(challengeOpenings) +} + +// Output returns the output of the DKG operation. Must be called after step 9. Calling it before that step +// has undefined behaviour. +func (alice *Alice) Output() *AliceOutput { + return &AliceOutput{ + PublicKey: alice.publicKey, + SecretKeyShare: alice.secretKeyShare, + SeedOtResult: alice.receiver.Output, + } +} + +// Output returns the output of the DKG operation. Must be called after step 9. Calling it before that step +// has undefined behaviour. +func (bob *Bob) Output() *BobOutput { + return &BobOutput{ + PublicKey: bob.publicKey, + SecretKeyShare: bob.secretKeyShare, + SeedOtResult: bob.sender.Output, + } +} diff --git a/pkg/crypto/tecdsa/dklsv1/dkg/dkg_test.go b/pkg/crypto/tecdsa/dklsv1/dkg/dkg_test.go new file mode 100755 index 000000000..329f97761 --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/dkg/dkg_test.go @@ -0,0 +1,104 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package dkg + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" +) + +func TestDkg(t *testing.T) { + t.Parallel() + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + boundCurve := curve + t.Run(fmt.Sprintf("testing dkg for curve %s", boundCurve.Name), func(tt *testing.T) { + tt.Parallel() + alice := NewAlice(boundCurve) + bob := NewBob(boundCurve) + + seed, err := bob.Round1GenerateRandomSeed() + require.NoError(tt, err) + round3Output, err := alice.Round2CommitToProof(seed) + require.NoError(tt, err) + proof, err := bob.Round3SchnorrProve(round3Output) + require.NoError(tt, err) + proof, err = alice.Round4VerifyAndReveal(proof) + require.NoError(tt, err) + proof, err = bob.Round5DecommitmentAndStartOt(proof) + require.NoError(tt, err) + compressedReceiversMaskedChoice, err := alice.Round6DkgRound2Ot(proof) + require.NoError(tt, err) + challenge, err := bob.Round7DkgRound3Ot(compressedReceiversMaskedChoice) + require.NoError(tt, err) + challengeResponse, err := alice.Round8DkgRound4Ot(challenge) + require.NoError(tt, err) + challengeOpenings, err := bob.Round9DkgRound5Ot(challengeResponse) + require.NoError(tt, err) + err = alice.Round10DkgRound6Ot(challengeOpenings) + require.NoError(tt, err) + // Verify correctness of the OT subprotocol after has completed + for i := 0; i < kos.Kappa; i++ { + if alice.receiver.Output.OneTimePadDecryptionKey[i] != bob.sender.Output.OneTimePadEncryptionKeys[i][alice.receiver.Output.RandomChoiceBits[i]] { + tt.Errorf("oblivious transfer is incorrect at index i=%v", i) + } + } + + pkA := boundCurve.ScalarBaseMult(alice.Output().SecretKeyShare) + pkB := boundCurve.ScalarBaseMult(bob.Output().SecretKeyShare) + + computedPublicKeyA := pkA.Mul(bob.Output().SecretKeyShare) + require.True(tt, computedPublicKeyA.Equal(alice.Output().PublicKey)) + require.True(tt, computedPublicKeyA.Equal(bob.Output().PublicKey)) + + computedPublicKeyB := pkB.Mul(alice.Output().SecretKeyShare) + require.True(tt, computedPublicKeyB.Equal(alice.Output().PublicKey)) + require.True(tt, computedPublicKeyB.Equal(bob.Output().PublicKey)) + }) + } +} + +func BenchmarkDkg(b *testing.B) { + if testing.Short() { + b.SkipNow() + } + curve := curves.K256() + + for n := 0; n < b.N; n++ { + alice := NewAlice(curve) + bob := NewBob(curve) + + seed, err := bob.Round1GenerateRandomSeed() + require.NoError(b, err) + round3Output, err := alice.Round2CommitToProof(seed) + require.NoError(b, err) + proof, err := bob.Round3SchnorrProve(round3Output) + require.NoError(b, err) + proof, err = alice.Round4VerifyAndReveal(proof) + require.NoError(b, err) + proof, err = bob.Round5DecommitmentAndStartOt(proof) + require.NoError(b, err) + compressedReceiversMaskedChoice, err := alice.Round6DkgRound2Ot(proof) + require.NoError(b, err) + challenge, err := bob.Round7DkgRound3Ot(compressedReceiversMaskedChoice) + require.NoError(b, err) + challengeResponse, err := alice.Round8DkgRound4Ot(challenge) + require.NoError(b, err) + challengeOpenings, err := bob.Round9DkgRound5Ot(challengeResponse) + require.NoError(b, err) + err = alice.Round10DkgRound6Ot(challengeOpenings) + require.NoError(b, err) + } +} diff --git a/pkg/crypto/tecdsa/dklsv1/dkgserializers.go b/pkg/crypto/tecdsa/dklsv1/dkgserializers.go new file mode 100755 index 000000000..47a795c03 --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/dkgserializers.go @@ -0,0 +1,315 @@ +package dklsv1 + +import ( + "bytes" + "encoding/gob" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/protocol" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" + "github.com/onsonr/sonr/pkg/crypto/zkp/schnorr" +) + +const payloadKey = "direct" + +func newDkgProtocolMessage(payload []byte, round string, version uint) *protocol.Message { + return &protocol.Message{ + Protocol: protocol.Dkls18Dkg, + Version: version, + Payloads: map[string][]byte{payloadKey: payload}, + Metadata: map[string]string{"round": round}, + } +} + +func registerTypes() { + gob.Register(&curves.ScalarK256{}) + gob.Register(&curves.PointK256{}) + gob.Register(&curves.ScalarP256{}) + gob.Register(&curves.PointP256{}) +} + +func encodeDkgRound1Output(commitment [32]byte, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + registerTypes() + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(&commitment); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "1", version), nil +} + +func decodeDkgRound2Input(m *protocol.Message) ([32]byte, error) { + if m.Version != protocol.Version1 { + return [32]byte{}, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := [32]byte{} + if err := dec.Decode(&decoded); err != nil { + return [32]byte{}, errors.WithStack(err) + } + return decoded, nil +} + +func encodeDkgRound2Output(output *dkg.Round2Output, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(output); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "2", version), nil +} + +func decodeDkgRound3Input(m *protocol.Message) (*dkg.Round2Output, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(dkg.Round2Output) + if err := dec.Decode(decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeDkgRound3Output(proof *schnorr.Proof, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(proof); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "3", version), nil +} + +func decodeDkgRound4Input(m *protocol.Message) (*schnorr.Proof, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(schnorr.Proof) + if err := dec.Decode(decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeDkgRound4Output(proof *schnorr.Proof, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(proof); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "4", version), nil +} + +func decodeDkgRound5Input(m *protocol.Message) (*schnorr.Proof, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(schnorr.Proof) + if err := dec.Decode(decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeDkgRound5Output(proof *schnorr.Proof, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(proof); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "5", version), nil +} + +func decodeDkgRound6Input(m *protocol.Message) (*schnorr.Proof, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(schnorr.Proof) + if err := dec.Decode(decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeDkgRound6Output(choices []simplest.ReceiversMaskedChoices, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(choices); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "6", version), nil +} + +func decodeDkgRound7Input(m *protocol.Message) ([]simplest.ReceiversMaskedChoices, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := []simplest.ReceiversMaskedChoices{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeDkgRound7Output(challenge []simplest.OtChallenge, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(challenge); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "7", version), nil +} + +func decodeDkgRound8Input(m *protocol.Message) ([]simplest.OtChallenge, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := []simplest.OtChallenge{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeDkgRound8Output(responses []simplest.OtChallengeResponse, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(responses); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "8", version), nil +} + +func decodeDkgRound9Input(m *protocol.Message) ([]simplest.OtChallengeResponse, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := []simplest.OtChallengeResponse{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeDkgRound9Output(opening []simplest.ChallengeOpening, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(opening); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "9", version), nil +} + +func decodeDkgRound10Input(m *protocol.Message) ([]simplest.ChallengeOpening, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := []simplest.ChallengeOpening{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +// EncodeAliceDkgOutput serializes Alice DKG output based on the protocol version. +func EncodeAliceDkgOutput(result *dkg.AliceOutput, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + registerTypes() + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(result); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "alice-output", version), nil +} + +// DecodeAliceDkgResult deserializes Alice DKG output. +func DecodeAliceDkgResult(m *protocol.Message) (*dkg.AliceOutput, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + registerTypes() + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(dkg.AliceOutput) + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +// EncodeBobDkgOutput serializes Bob DKG output based on the protocol version. +func EncodeBobDkgOutput(result *dkg.BobOutput, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + registerTypes() + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(result); err != nil { + return nil, errors.WithStack(err) + } + return newDkgProtocolMessage(buf.Bytes(), "bob-output", version), nil +} + +// DecodeBobDkgResult deserializes Bob DKG output. +func DecodeBobDkgResult(m *protocol.Message) (*dkg.BobOutput, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(dkg.BobOutput) + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} diff --git a/pkg/crypto/tecdsa/dklsv1/protocol.go b/pkg/crypto/tecdsa/dklsv1/protocol.go new file mode 100755 index 000000000..29e85bc0c --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/protocol.go @@ -0,0 +1,33 @@ +// package dklsv1 provides a wrapper around the [DKLs18](https://eprint.iacr.org/2018/499.pdf) sign and dkg and provides +// serialization, serialization, and versioning for the serialized data. +package dklsv1 + +import ( + "github.com/onsonr/sonr/pkg/crypto/core/protocol" +) + +// Basic protocol interface implementation that calls the next step func in a pre-defined list +type protoStepper struct { + steps []func(input *protocol.Message) (*protocol.Message, error) + step int +} + +// Next runs the next step in the protocol and reports errors or increments the step index +func (p *protoStepper) Next(input *protocol.Message) (*protocol.Message, error) { + if p.complete() { + return nil, protocol.ErrProtocolFinished + } + + // Run the current protocol step and report any errors + output, err := p.steps[p.step](input) + if err != nil { + return nil, err + } + + // Increment the step index and report success + p.step++ + return output, nil +} + +// Reports true if the step index exceeds the number of steps +func (p *protoStepper) complete() bool { return p.step >= len(p.steps) /**/ } diff --git a/pkg/crypto/tecdsa/dklsv1/protocol_test.go b/pkg/crypto/tecdsa/dklsv1/protocol_test.go new file mode 100755 index 000000000..231a1648d --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/protocol_test.go @@ -0,0 +1,419 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package dklsv1 + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/protocol" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" +) + +// For DKG bob starts first. For refresh and sign, Alice starts first. +func runIteratedProtocol(firstParty protocol.Iterator, secondParty protocol.Iterator) (error, error) { + var ( + message *protocol.Message + aErr error + bErr error + ) + + for aErr != protocol.ErrProtocolFinished || bErr != protocol.ErrProtocolFinished { + // Crank each protocol forward one iteration + message, bErr = firstParty.Next(message) + if bErr != nil && bErr != protocol.ErrProtocolFinished { + return nil, bErr + } + + message, aErr = secondParty.Next(message) + if aErr != nil && aErr != protocol.ErrProtocolFinished { + return aErr, nil + } + } + return aErr, bErr +} + +// Running steps in sequence ensures that no hidden read/write dependency exist in the read/write interfaces. +func TestDkgProto(t *testing.T) { + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + alice := NewAliceDkg(curve, protocol.Version1) + bob := NewBobDkg(curve, protocol.Version1) + aErr, bErr := runIteratedProtocol(bob, alice) + + t.Run("both alice/bob complete simultaneously", func(t *testing.T) { + require.ErrorIs(t, aErr, protocol.ErrProtocolFinished) + require.ErrorIs(t, bErr, protocol.ErrProtocolFinished) + }) + + for i := 0; i < kos.Kappa; i++ { + if alice.Alice.Output().SeedOtResult.OneTimePadDecryptionKey[i] != bob.Bob.Output().SeedOtResult.OneTimePadEncryptionKeys[i][alice.Alice.Output().SeedOtResult.RandomChoiceBits[i]] { + t.Errorf("oblivious transfer is incorrect at index i=%v", i) + } + } + + t.Run("Both parties produces identical composite pubkey", func(t *testing.T) { + require.True(t, alice.Alice.Output().PublicKey.Equal(bob.Bob.Output().PublicKey)) + }) + + var aliceResult *dkg.AliceOutput + var bobResult *dkg.BobOutput + t.Run("alice produces valid result", func(t *testing.T) { + // Get the result + r, err := alice.Result(protocol.Version1) + + // Test + require.NoError(t, err) + require.NotNil(t, r) + aliceResult, err = DecodeAliceDkgResult(r) + require.NoError(t, err) + }) + t.Run("bob produces valid result", func(t *testing.T) { + // Get the result + r, err := bob.Result(protocol.Version1) + + // Test + require.NoError(t, err) + require.NotNil(t, r) + bobResult, err = DecodeBobDkgResult(r) + require.NoError(t, err) + }) + + t.Run("alice/bob agree on pubkey", func(t *testing.T) { + require.Equal(t, aliceResult.PublicKey, bobResult.PublicKey) + }) + } +} + +// +// // DKG > Refresh > Sign +// func TestRefreshProto(t *testing.T) { +// t.Parallel() +// curveInstances := []*curves.Curve{ +// curves.K256(), +// curves.P256(), +// } +// for _, curve := range curveInstances { +// boundCurve := curve +// t.Run(fmt.Sprintf("testing refresh for curve %s", boundCurve.Name), func(tt *testing.T) { +// tt.Parallel() +// // DKG +// aliceDkg := NewAliceDkg(boundCurve, protocol.Version1) +// bobDkg := NewBobDkg(boundCurve, protocol.Version1) +// +// aDkgErr, bDkgErr := runIteratedProtocol(bobDkg, aliceDkg) +// require.ErrorIs(tt, aDkgErr, protocol.ErrProtocolFinished) +// require.ErrorIs(tt, bDkgErr, protocol.ErrProtocolFinished) +// +// aliceDkgResultMessage, err := aliceDkg.Result(protocol.Version1) +// require.NoError(tt, err) +// bobDkgResultMessage, err := bobDkg.Result(protocol.Version1) +// require.NoError(tt, err) +// +// // Refresh +// aliceRefreshResultMessage, bobRefreshResultMessage := refreshV1(t, boundCurve, aliceDkgResultMessage, bobDkgResultMessage) +// +// // sign +// signV1(t, boundCurve, aliceRefreshResultMessage, bobRefreshResultMessage) +// }) +// } +// } + +// DKG > Output > NewDklsSign > Sign > Output +func TestDkgSignProto(t *testing.T) { + // Setup + curve := curves.K256() + + aliceDkg := NewAliceDkg(curve, protocol.Version1) + bobDkg := NewBobDkg(curve, protocol.Version1) + + // DKG + aErr, bErr := runIteratedProtocol(bobDkg, aliceDkg) + require.ErrorIs(t, aErr, protocol.ErrProtocolFinished) + require.ErrorIs(t, bErr, protocol.ErrProtocolFinished) + + // Output + aliceDkgResultMessage, err := aliceDkg.Result(protocol.Version1) + require.NoError(t, err) + + bobDkgResultMessage, err := bobDkg.Result(protocol.Version1) + require.NoError(t, err) + + // New DklsSign + msg := []byte("As soon as you trust yourself, you will know how to live.") + aliceSign, err := NewAliceSign(curve, sha3.New256(), msg, aliceDkgResultMessage, protocol.Version1) + require.NoError(t, err) + bobSign, err := NewBobSign(curve, sha3.New256(), msg, bobDkgResultMessage, protocol.Version1) + require.NoError(t, err) + + // Sign + t.Run("sign", func(t *testing.T) { + aErr, bErr = runIteratedProtocol(aliceSign, bobSign) + require.ErrorIs(t, aErr, protocol.ErrProtocolFinished) + require.ErrorIs(t, bErr, protocol.ErrProtocolFinished) + }) + // Don't continue to verifying results if sign didn't run to completion. + require.ErrorIs(t, aErr, protocol.ErrProtocolFinished) + require.ErrorIs(t, bErr, protocol.ErrProtocolFinished) + + // Output + var result *curves.EcdsaSignature + t.Run("bob produces result of correct type", func(t *testing.T) { + resultMessage, err := bobSign.Result(protocol.Version1) + require.NoError(t, err) + result, err = DecodeSignature(resultMessage) + require.NoError(t, err) + }) + require.NotNil(t, result) + + t.Run("valid signature", func(t *testing.T) { + hash := sha3.New256() + _, err = hash.Write(msg) + require.NoError(t, err) + digest := hash.Sum(nil) + unCompressedAffinePublicKey := aliceDkg.Output().PublicKey.ToAffineUncompressed() + require.Equal(t, 65, len(unCompressedAffinePublicKey)) + x := new(big.Int).SetBytes(unCompressedAffinePublicKey[1:33]) + y := new(big.Int).SetBytes(unCompressedAffinePublicKey[33:]) + ecCurve, err := curve.ToEllipticCurve() + require.NoError(t, err) + publicKey := &curves.EcPoint{ + Curve: ecCurve, + X: x, + Y: y, + } + require.True(t, + curves.VerifyEcdsa(publicKey, + digest[:], + result, + ), + "signature failed verification", + ) + }) +} + +// +// // Decode > NewDklsSign > Sign > Output +// // NOTE: this cold-start test ensures backwards compatibility with durable, +// // encoding DKG state that may exist within production systems like test +// // Breaking changes must consider downstream production impacts. +// func TestSignColdStart(t *testing.T) { +// // Decode alice/bob state from file +// aliceDkg, err := os.ReadFile("testdata/alice-dkls-v1-dkg.bin") +// require.NoError(t, err) +// bobDkg, err := os.ReadFile("testdata/bob-dkls-v1-dkg.bin") +// require.NoError(t, err) +// +// // The choice of json marshaling is arbitrary, the binary could have been marshaled in other forms as well +// // The purpose here is to obtain an instance of `protocol.Message` +// +// aliceDkgMessage := &protocol.Message{} +// err = json.Unmarshal(aliceDkg, aliceDkgMessage) +// require.NoError(t, err) +// +// bobDkgMessage := &protocol.Message{} +// err = json.Unmarshal(bobDkg, bobDkgMessage) +// require.NoError(t, err) +// +// signV1(t, curves.K256(), aliceDkgMessage, bobDkgMessage) +// } +// +// func TestEncodeDecode(t *testing.T) { +// curve := curves.K256() +// +// alice := NewAliceDkg(curve, protocol.Version1) +// bob := NewBobDkg(curve, protocol.Version1) +// _, _ = runIteratedProtocol(bob, alice) +// +// var aliceBytes []byte +// var bobBytes []byte +// t.Run("Encode Alice/Bob", func(t *testing.T) { +// aliceDkgMessage, err := EncodeAliceDkgOutput(alice.Alice.Output(), protocol.Version1) +// require.NoError(t, err) +// aliceBytes, err = json.Marshal(aliceDkgMessage) +// require.NoError(t, err) +// +// bobDkgMessage, err := EncodeBobDkgOutput(bob.Bob.Output(), protocol.Version1) +// require.NoError(t, err) +// bobBytes, err = json.Marshal(bobDkgMessage) +// require.NoError(t, err) +// }) +// require.NotEmpty(t, aliceBytes) +// require.NotEmpty(t, bobBytes) +// +// t.Run("Decode Alice", func(t *testing.T) { +// decodedAliceMessage := &protocol.Message{} +// err := json.Unmarshal(aliceBytes, decodedAliceMessage) +// require.NoError(t, err) +// require.NotNil(t, decodedAliceMessage) +// decodedAlice, err := DecodeAliceDkgResult(decodedAliceMessage) +// require.NoError(t, err) +// +// require.True(t, alice.Output().PublicKey.Equal(decodedAlice.PublicKey)) +// require.Equal(t, alice.Output().SecretKeyShare, decodedAlice.SecretKeyShare) +// }) +// +// t.Run("Decode Bob", func(t *testing.T) { +// decodedBobMessage := &protocol.Message{} +// err := json.Unmarshal(bobBytes, decodedBobMessage) +// require.NoError(t, err) +// require.NotNil(t, decodedBobMessage) +// decodedBob, err := DecodeBobDkgResult(decodedBobMessage) +// require.NoError(t, err) +// +// require.True(t, bob.Output().PublicKey.Equal(decodedBob.PublicKey)) +// require.Equal(t, bob.Output().SecretKeyShare, decodedBob.SecretKeyShare) +// }) +// } +// +// func signV1(t *testing.T, curve *curves.Curve, aliceDkgResultMessage *protocol.Message, bobDkgResultMessage *protocol.Message) { +// t.Helper() +// // New DklsSign +// msg := []byte("As soon as you trust yourself, you will know how to live.") +// aliceSign, err := NewAliceSign(curve, sha3.New256(), msg, aliceDkgResultMessage, protocol.Version1) +// require.NoError(t, err) +// bobSign, err := NewBobSign(curve, sha3.New256(), msg, bobDkgResultMessage, protocol.Version1) +// require.NoError(t, err) +// +// // Sign +// var aErr error +// var bErr error +// t.Run("sign", func(t *testing.T) { +// aErr, bErr = runIteratedProtocol(aliceSign, bobSign) +// require.ErrorIs(t, aErr, protocol.ErrProtocolFinished) +// require.ErrorIs(t, bErr, protocol.ErrProtocolFinished) +// }) +// // Don't continue to verifying results if sign didn't run to completion. +// require.ErrorIs(t, aErr, protocol.ErrProtocolFinished) +// require.ErrorIs(t, bErr, protocol.ErrProtocolFinished) +// +// // Output +// var result *curves.EcdsaSignature +// t.Run("bob produces result of correct type", func(t *testing.T) { +// resultMessage, err := bobSign.Result(protocol.Version1) +// require.NoError(t, err) +// result, err = DecodeSignature(resultMessage) +// require.NoError(t, err) +// }) +// require.NotNil(t, result) +// +// aliceDkg, err := DecodeAliceDkgResult(aliceDkgResultMessage) +// require.NoError(t, err) +// +// t.Run("valid signature", func(t *testing.T) { +// hash := sha3.New256() +// _, err = hash.Write(msg) +// require.NoError(t, err) +// digest := hash.Sum(nil) +// unCompressedAffinePublicKey := aliceDkg.PublicKey.ToAffineUncompressed() +// require.Equal(t, 65, len(unCompressedAffinePublicKey)) +// x := new(big.Int).SetBytes(unCompressedAffinePublicKey[1:33]) +// y := new(big.Int).SetBytes(unCompressedAffinePublicKey[33:]) +// ecCurve, err := curve.ToEllipticCurve() +// require.NoError(t, err) +// publicKey := &curves.EcPoint{ +// Curve: ecCurve, +// X: x, +// Y: y, +// } +// require.True(t, +// curves.VerifyEcdsa(publicKey, +// digest[:], +// result, +// ), +// "signature failed verification", +// ) +// }) +// } +// +// func refreshV1(t *testing.T, curve *curves.Curve, aliceDkgResultMessage, bobDkgResultMessage *protocol.Message) (aliceRefreshResultMessage, bobRefreshResultMessage *protocol.Message) { +// t.Helper() +// aliceRefresh, err := NewAliceRefresh(curve, aliceDkgResultMessage, protocol.Version1) +// require.NoError(t, err) +// bobRefresh, err := NewBobRefresh(curve, bobDkgResultMessage, protocol.Version1) +// require.NoError(t, err) +// +// aErr, bErr := runIteratedProtocol(aliceRefresh, bobRefresh) +// require.ErrorIs(t, aErr, protocol.ErrProtocolFinished) +// require.ErrorIs(t, bErr, protocol.ErrProtocolFinished) +// +// aliceRefreshResultMessage, err = aliceRefresh.Result(protocol.Version1) +// require.NoError(t, err) +// require.NotNil(t, aliceRefreshResultMessage) +// _, err = DecodeAliceRefreshResult(aliceRefreshResultMessage) +// require.NoError(t, err) +// +// bobRefreshResultMessage, err = bobRefresh.Result(protocol.Version1) +// require.NoError(t, err) +// require.NotNil(t, bobRefreshResultMessage) +// _, err = DecodeBobRefreshResult(bobRefreshResultMessage) +// require.NoError(t, err) +// +// return aliceRefreshResultMessage, bobRefreshResultMessage +// } +// +// func BenchmarkDKGProto(b *testing.B) { +// curveInstances := []*curves.Curve{ +// curves.K256(), +// curves.P256(), +// } +// for _, curve := range curveInstances { +// alice := NewAliceDkg(curve, protocol.Version1) +// bob := NewBobDkg(curve, protocol.Version1) +// aErr, bErr := runIteratedProtocol(bob, alice) +// +// b.Run("both alice/bob complete simultaneously", func(t *testing.B) { +// require.ErrorIs(t, aErr, protocol.ErrProtocolFinished) +// require.ErrorIs(t, bErr, protocol.ErrProtocolFinished) +// }) +// +// for i := 0; i < kos.Kappa; i++ { +// if alice.Alice.Output().SeedOtResult.OneTimePadDecryptionKey[i] != bob.Bob.Output().SeedOtResult.OneTimePadEncryptionKeys[i][alice.Alice.Output().SeedOtResult.RandomChoiceBits[i]] { +// b.Errorf("oblivious transfer is incorrect at index i=%v", i) +// } +// } +// +// b.Run("Both parties produces identical composite pubkey", func(t *testing.B) { +// require.True(t, alice.Alice.Output().PublicKey.Equal(bob.Bob.Output().PublicKey)) +// }) +// +// var aliceResult *dkg.AliceOutput +// var bobResult *dkg.BobOutput +// b.Run("alice produces valid result", func(t *testing.B) { +// // Get the result +// r, err := alice.Result(protocol.Version1) +// +// // Test +// require.NoError(t, err) +// require.NotNil(t, r) +// aliceResult, err = DecodeAliceDkgResult(r) +// require.NoError(t, err) +// }) +// b.Run("bob produces valid result", func(t *testing.B) { +// // Get the result +// r, err := bob.Result(protocol.Version1) +// +// // Test +// require.NoError(t, err) +// require.NotNil(t, r) +// bobResult, err = DecodeBobDkgResult(r) +// require.NoError(t, err) +// }) +// +// b.Run("alice/bob agree on pubkey", func(t *testing.B) { +// require.Equal(t, aliceResult.PublicKey, bobResult.PublicKey) +// }) +// } +// } diff --git a/pkg/crypto/tecdsa/dklsv1/refresh/refresh.go b/pkg/crypto/tecdsa/dklsv1/refresh/refresh.go new file mode 100755 index 000000000..7c84b900f --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/refresh/refresh.go @@ -0,0 +1,177 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// This file implements the key refresh protocol of [DKLs18](https://eprint.iacr.org/2018/499.pdf). +// The key refresh protocol is defined as follows: +// 1. Key Share: +// 1.1. alice generates k_A <-- F_q; writes it to merlin transcript. sends it to bob. +// 1.2. bob receives k_A and writes it to merlin transcript. generates k_B <-- F_q and writes it to merlin transcript. reads k out of merlin transcript. overwrites sk_B *= k. sends k_B to Alice. +// 1.3. alice writes k_B to merlin transcript. reads k from it. overwrites sk_A *= k^{-1}. +// 2. OT: Redo OT (as it is done in the DKG) +package refresh + +import ( + "crypto/rand" + + "github.com/gtank/merlin" + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" + "github.com/onsonr/sonr/pkg/crypto/zkp/schnorr" +) + +// Alice struct encoding Alice's state during one execution of the overall signing algorithm. +// At the end of the joint computation, Alice will NOT obtain the signature. +type Alice struct { + // receiver is the base OT receiver. + receiver *simplest.Receiver + + // secretKeyShare is Alice's secret key for the joint public key. + secretKeyShare curves.Scalar + + // publicKey is the joint public key of Alice and Bob. + publicKey curves.Point + + curve *curves.Curve + + transcript *merlin.Transcript +} + +// Bob struct encoding Bob's state during one execution of the overall signing algorithm. +// At the end of the joint computation, Bob will obtain the signature. +type Bob struct { + // sender is the base OT sender. + sender *simplest.Sender + + // secretKeyShare is Bob's secret key for the joint public key. + secretKeyShare curves.Scalar + + // publicKey is the joint public key of Alice and Bob. + publicKey curves.Point + + curve *curves.Curve + + transcript *merlin.Transcript +} + +type RefreshRound2Output struct { + SeedOTRound1Output *schnorr.Proof + BobMultiplier curves.Scalar +} + +// NewAliceRefresh creates a party that can participate in 2-of-2 key refresh. +func NewAlice(curve *curves.Curve, dkgOutput *dkg.AliceOutput) *Alice { + return &Alice{ + curve: curve, + secretKeyShare: dkgOutput.SecretKeyShare, + publicKey: dkgOutput.PublicKey, + transcript: merlin.NewTranscript("Coinbase_DKLs_Refresh"), + } +} + +// NewBobRefresh creates a party that can participate in 2-of-2 key refresh. +func NewBob(curve *curves.Curve, dkgOutput *dkg.BobOutput) *Bob { + return &Bob{ + curve: curve, + secretKeyShare: dkgOutput.SecretKeyShare, + publicKey: dkgOutput.PublicKey, + transcript: merlin.NewTranscript("Coinbase_DKLs_Refresh"), + } +} + +func (alice *Alice) Round1RefreshGenerateSeed() curves.Scalar { + refreshSeed := alice.curve.Scalar.Random(rand.Reader) + alice.transcript.AppendMessage([]byte("alice refresh seed"), refreshSeed.Bytes()) + return refreshSeed +} + +func (bob *Bob) Round2RefreshProduceSeedAndMultiplyAndStartOT(aliceSeed curves.Scalar) (*RefreshRound2Output, error) { + bob.transcript.AppendMessage([]byte("alice refresh seed"), aliceSeed.Bytes()) + bobSeed := bob.curve.Scalar.Random(rand.Reader) + bob.transcript.AppendMessage([]byte("bob refresh seed"), bobSeed.Bytes()) + k, err := bob.curve.NewScalar().SetBytes( + bob.transcript.ExtractBytes([]byte("secret key share multiplier"), simplest.DigestSize), + ) + if err != nil { + return nil, errors.Wrap(err, "couldn't produce bob's secret key share multiplier") + } + bob.secretKeyShare = bob.secretKeyShare.Mul(k) + + uniqueSessionId := [simplest.DigestSize]byte{} // note: will use and re-use this below for sub-session IDs. + copy(uniqueSessionId[:], bob.transcript.ExtractBytes([]byte("salt for simplest OT"), simplest.DigestSize)) + bob.sender, err = simplest.NewSender(bob.curve, kos.Kappa, uniqueSessionId) + if err != nil { + return nil, errors.Wrap(err, "bob constructing new OT sender in refresh round 2") + } + seedOTRound1Output, err := bob.sender.Round1ComputeAndZkpToPublicKey() + if err != nil { + return nil, errors.Wrap(err, "bob computing round 1 of seed OT within refresh round 2") + } + + return &RefreshRound2Output{ + SeedOTRound1Output: seedOTRound1Output, + BobMultiplier: bobSeed, + }, nil +} + +func (alice *Alice) Round3RefreshMultiplyRound2Ot(input *RefreshRound2Output) ([]simplest.ReceiversMaskedChoices, error) { + alice.transcript.AppendMessage([]byte("bob refresh seed"), input.BobMultiplier.Bytes()) + k, err := alice.curve.NewScalar().SetBytes( + alice.transcript.ExtractBytes([]byte("secret key share multiplier"), simplest.DigestSize), + ) + if err != nil { + return nil, errors.Wrap(err, "couldn't produce bob's secret key share multiplier") + } + kInverse, err := k.Invert() + if err != nil { + return nil, errors.Wrap(err, "couldn't produce k inverse (alice's secret key share)") + } + alice.secretKeyShare = alice.secretKeyShare.Mul(kInverse) + + uniqueSessionId := [simplest.DigestSize]byte{} // note: will use and re-use this below for sub-session IDs. + copy(uniqueSessionId[:], alice.transcript.ExtractBytes([]byte("salt for simplest OT"), simplest.DigestSize)) + alice.receiver, err = simplest.NewReceiver(alice.curve, kos.Kappa, uniqueSessionId) + if err != nil { + return nil, errors.Wrap(err, "couldn't construct OT receiver") + } + + return alice.receiver.Round2VerifySchnorrAndPadTransfer(input.SeedOTRound1Output) +} + +func (bob *Bob) Round4RefreshRound3Ot(compressedReceiversMaskedChoice []simplest.ReceiversMaskedChoices) ([]simplest.OtChallenge, error) { + return bob.sender.Round3PadTransfer(compressedReceiversMaskedChoice) +} + +func (alice *Alice) Round5RefreshRound4Ot(challenge []simplest.OtChallenge) ([]simplest.OtChallengeResponse, error) { + return alice.receiver.Round4RespondToChallenge(challenge) +} + +func (bob *Bob) Round6RefreshRound5Ot(challengeResponses []simplest.OtChallengeResponse) ([]simplest.ChallengeOpening, error) { + return bob.sender.Round5Verify(challengeResponses) +} + +func (alice *Alice) Round7DkgRound6Ot(challengeOpenings []simplest.ChallengeOpening) error { + return alice.receiver.Round6Verify(challengeOpenings) +} + +func (alice *Alice) Output() *dkg.AliceOutput { + return &dkg.AliceOutput{ + PublicKey: alice.publicKey, + SecretKeyShare: alice.secretKeyShare, + SeedOtResult: alice.receiver.Output, + } +} + +func (bob *Bob) Output() *dkg.BobOutput { + return &dkg.BobOutput{ + PublicKey: bob.publicKey, + SecretKeyShare: bob.secretKeyShare, + SeedOtResult: bob.sender.Output, + } +} diff --git a/pkg/crypto/tecdsa/dklsv1/refresh/refresh_test.go b/pkg/crypto/tecdsa/dklsv1/refresh/refresh_test.go new file mode 100755 index 000000000..bd49ec71a --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/refresh/refresh_test.go @@ -0,0 +1,186 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package refresh_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/refresh" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/sign" +) + +func performDKG(t *testing.T, curve *curves.Curve) (*dkg.Alice, *dkg.Bob) { + t.Helper() + + alice := dkg.NewAlice(curve) + bob := dkg.NewBob(curve) + + seed, err := bob.Round1GenerateRandomSeed() + require.NoError(t, err) + round3Output, err := alice.Round2CommitToProof(seed) + require.NoError(t, err) + proof, err := bob.Round3SchnorrProve(round3Output) + require.NoError(t, err) + proof, err = alice.Round4VerifyAndReveal(proof) + require.NoError(t, err) + proof, err = bob.Round5DecommitmentAndStartOt(proof) + require.NoError(t, err) + compressedReceiversMaskedChoice, err := alice.Round6DkgRound2Ot(proof) + require.NoError(t, err) + challenge, err := bob.Round7DkgRound3Ot(compressedReceiversMaskedChoice) + require.NoError(t, err) + challengeResponse, err := alice.Round8DkgRound4Ot(challenge) + require.NoError(t, err) + challengeOpenings, err := bob.Round9DkgRound5Ot(challengeResponse) + require.NoError(t, err) + err = alice.Round10DkgRound6Ot(challengeOpenings) + require.NoError(t, err) + + return alice, bob +} + +func performRefresh(t *testing.T, curve *curves.Curve, aliceSecretKeyShare, bobSecretKeyShare curves.Scalar) (*refresh.Alice, *refresh.Bob) { + t.Helper() + alice := refresh.NewAlice(curve, &dkg.AliceOutput{SecretKeyShare: aliceSecretKeyShare}) + bob := refresh.NewBob(curve, &dkg.BobOutput{SecretKeyShare: bobSecretKeyShare}) + + round1Output := alice.Round1RefreshGenerateSeed() + require.False(t, round1Output.IsZero()) + round2Output, err := bob.Round2RefreshProduceSeedAndMultiplyAndStartOT(round1Output) + require.NoError(t, err) + round3Output, err := alice.Round3RefreshMultiplyRound2Ot(round2Output) + require.NoError(t, err) + round4Output, err := bob.Round4RefreshRound3Ot(round3Output) + require.NoError(t, err) + round5Output, err := alice.Round5RefreshRound4Ot(round4Output) + require.NoError(t, err) + round6Output, err := bob.Round6RefreshRound5Ot(round5Output) + require.NoError(t, err) + err = alice.Round7DkgRound6Ot(round6Output) + require.NoError(t, err) + return alice, bob +} + +func Test_RefreshLeadsToTheSamePublicKeyButDifferentPrivateMaterial(t *testing.T) { + t.Parallel() + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + boundCurve := curve + t.Run(fmt.Sprintf("testing refresh for curve %s", boundCurve.Name), func(tt *testing.T) { + tt.Parallel() + alice, bob := performDKG(tt, boundCurve) + + publicKey := alice.Output().PublicKey + require.True(tt, publicKey.Equal(bob.Output().PublicKey)) + + aliceRefreshed, bobRefreshed := performRefresh(tt, boundCurve, alice.Output().SecretKeyShare, bob.Output().SecretKeyShare) + + require.NotEqual(tt, aliceRefreshed.Output().SecretKeyShare, alice.Output().SecretKeyShare) + require.NotEqual(tt, bobRefreshed.Output().SeedOtResult, bob.Output().SecretKeyShare) + require.NotEqualValues( + tt, + aliceRefreshed.Output().SeedOtResult.OneTimePadDecryptionKey, + alice.Output().SeedOtResult.OneTimePadDecryptionKey, + ) + require.NotEqualValues( + tt, + aliceRefreshed.Output().SeedOtResult.PackedRandomChoiceBits, + alice.Output().SeedOtResult.PackedRandomChoiceBits, + ) + require.NotEqualValues( + tt, + aliceRefreshed.Output().SeedOtResult.RandomChoiceBits, + alice.Output().SeedOtResult.RandomChoiceBits, + ) + require.NotEqualValues( + tt, + bobRefreshed.Output().SeedOtResult.OneTimePadEncryptionKeys, + bob.Output().SeedOtResult.OneTimePadEncryptionKeys, + ) + + pkA := boundCurve.ScalarBaseMult(aliceRefreshed.Output().SecretKeyShare) + computedPublicKeyA := pkA.Mul(bobRefreshed.Output().SecretKeyShare) + require.True(tt, computedPublicKeyA.Equal(publicKey)) + + pkB := boundCurve.ScalarBaseMult(bobRefreshed.Output().SecretKeyShare) + computedPublicKeyB := pkB.Mul(aliceRefreshed.Output().SecretKeyShare) + require.True(tt, computedPublicKeyB.Equal(publicKey)) + }) + } +} + +func Test_RefreshOTIsCorrect(t *testing.T) { + t.Parallel() + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + boundCurve := curve + t.Run(fmt.Sprintf("testing OT correctness of key refresh for curve %s", boundCurve.Name), func(tt *testing.T) { + tt.Parallel() + alice, bob := performDKG(tt, boundCurve) + aliceRefreshed, bobRefreshed := performRefresh(tt, boundCurve, alice.Output().SecretKeyShare, bob.Output().SecretKeyShare) + for i := 0; i < kos.Kappa; i++ { + if aliceRefreshed.Output().SeedOtResult.OneTimePadDecryptionKey[i] != bobRefreshed.Output().SeedOtResult.OneTimePadEncryptionKeys[i][aliceRefreshed.Output().SeedOtResult.RandomChoiceBits[i]] { + tt.Errorf("oblivious transfer is incorrect at index i=%v", i) + } + } + }) + } +} + +func Test_CanSignAfterRefresh(t *testing.T) { + t.Parallel() + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + boundCurve := curve + t.Run(fmt.Sprintf("testing sign after refresh for curve %s", boundCurve.Name), func(tt *testing.T) { + tt.Parallel() + aliceDKG, bobDKG := performDKG(tt, boundCurve) + + publicKey := aliceDKG.Output().PublicKey + require.True(tt, publicKey.Equal(bobDKG.Output().PublicKey)) + + aliceRefreshed, bobRefreshed := performRefresh(tt, boundCurve, aliceDKG.Output().SecretKeyShare, bobDKG.Output().SecretKeyShare) + + alice := sign.NewAlice(boundCurve, sha3.New256(), &dkg.AliceOutput{ + SeedOtResult: aliceRefreshed.Output().SeedOtResult, + SecretKeyShare: aliceRefreshed.Output().SecretKeyShare, + PublicKey: publicKey, + }) + bob := sign.NewBob(boundCurve, sha3.New256(), &dkg.BobOutput{ + SeedOtResult: bobRefreshed.Output().SeedOtResult, + SecretKeyShare: bobRefreshed.Output().SecretKeyShare, + PublicKey: publicKey, + }) + + message := []byte("A message.") + seed, err := alice.Round1GenerateRandomSeed() + require.NoError(tt, err) + round3Output, err := bob.Round2Initialize(seed) + require.NoError(tt, err) + round4Output, err := alice.Round3Sign(message, round3Output) + require.NoError(tt, err) + err = bob.Round4Final(message, round4Output) + require.NoError(tt, err, "curve: %s", boundCurve.Name) + }) + } +} diff --git a/pkg/crypto/tecdsa/dklsv1/refreshserializers.go b/pkg/crypto/tecdsa/dklsv1/refreshserializers.go new file mode 100755 index 000000000..cf820d378 --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/refreshserializers.go @@ -0,0 +1,238 @@ +package dklsv1 + +import ( + "bytes" + "encoding/gob" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/protocol" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/refresh" +) + +func newRefreshProtocolMessage(payload []byte, round string, version uint) *protocol.Message { + return &protocol.Message{ + Protocol: protocol.Dkls18Refresh, + Version: version, + Payloads: map[string][]byte{payloadKey: payload}, + Metadata: map[string]string{"round": round}, + } +} + +func versionIsSupported(messageVersion uint) error { + if messageVersion < uint(protocol.Version1) { + return errors.New("only version 1 is supported.") + } + return nil +} + +func encodeRefreshRound1Output(seed curves.Scalar, version uint) (*protocol.Message, error) { + if err := versionIsSupported(version); err != nil { + return nil, errors.Wrap(err, "version error") + } + registerTypes() + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(&seed); err != nil { + return nil, errors.WithStack(err) + } + return newRefreshProtocolMessage(buf.Bytes(), "1", version), nil +} + +func decodeRefreshRound2Input(m *protocol.Message) (curves.Scalar, error) { + if err := versionIsSupported(m.Version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(curves.Scalar) + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return *decoded, nil +} + +func encodeRefreshRound2Output(output *refresh.RefreshRound2Output, version uint) (*protocol.Message, error) { + if err := versionIsSupported(version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(output); err != nil { + return nil, errors.WithStack(err) + } + return newRefreshProtocolMessage(buf.Bytes(), "2", version), nil +} + +func decodeRefreshRound3Input(m *protocol.Message) (*refresh.RefreshRound2Output, error) { + if err := versionIsSupported(m.Version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(refresh.RefreshRound2Output) + if err := dec.Decode(decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeRefreshRound3Output(choices []simplest.ReceiversMaskedChoices, version uint) (*protocol.Message, error) { + if err := versionIsSupported(version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(choices); err != nil { + return nil, errors.WithStack(err) + } + return newRefreshProtocolMessage(buf.Bytes(), "3", version), nil +} + +func decodeRefreshRound4Input(m *protocol.Message) ([]simplest.ReceiversMaskedChoices, error) { + if err := versionIsSupported(m.Version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := []simplest.ReceiversMaskedChoices{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeRefreshRound4Output(challenge []simplest.OtChallenge, version uint) (*protocol.Message, error) { + if err := versionIsSupported(version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(challenge); err != nil { + return nil, errors.WithStack(err) + } + return newRefreshProtocolMessage(buf.Bytes(), "4", version), nil +} + +func decodeRefreshRound5Input(m *protocol.Message) ([]simplest.OtChallenge, error) { + if err := versionIsSupported(m.Version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := []simplest.OtChallenge{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeRefreshRound5Output(responses []simplest.OtChallengeResponse, version uint) (*protocol.Message, error) { + if err := versionIsSupported(version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(responses); err != nil { + return nil, errors.WithStack(err) + } + return newRefreshProtocolMessage(buf.Bytes(), "5", version), nil +} + +func decodeRefreshRound6Input(m *protocol.Message) ([]simplest.OtChallengeResponse, error) { + if err := versionIsSupported(m.Version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := []simplest.OtChallengeResponse{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeRefreshRound6Output(opening []simplest.ChallengeOpening, version uint) (*protocol.Message, error) { + if err := versionIsSupported(version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(opening); err != nil { + return nil, errors.WithStack(err) + } + return newRefreshProtocolMessage(buf.Bytes(), "6", version), nil +} + +func decodeRefreshRound7Input(m *protocol.Message) ([]simplest.ChallengeOpening, error) { + if err := versionIsSupported(m.Version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := []simplest.ChallengeOpening{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +// EncodeAliceRefreshOutput serializes Alice Refresh output based on the protocol version. +func EncodeAliceRefreshOutput(result *dkg.AliceOutput, version uint) (*protocol.Message, error) { + if err := versionIsSupported(version); err != nil { + return nil, errors.Wrap(err, "version error") + } + registerTypes() + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(result); err != nil { + return nil, errors.WithStack(err) + } + return newRefreshProtocolMessage(buf.Bytes(), "alice-output", version), nil +} + +// DecodeAliceRefreshResult deserializes Alice refresh output. +func DecodeAliceRefreshResult(m *protocol.Message) (*dkg.AliceOutput, error) { + if err := versionIsSupported(m.Version); err != nil { + return nil, errors.Wrap(err, "version error") + } + registerTypes() + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(dkg.AliceOutput) + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +// EncodeBobRefreshOutput serializes Bob refresh output based on the protocol version. +func EncodeBobRefreshOutput(result *dkg.BobOutput, version uint) (*protocol.Message, error) { + if err := versionIsSupported(version); err != nil { + return nil, errors.Wrap(err, "version error") + } + registerTypes() + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(result); err != nil { + return nil, errors.WithStack(err) + } + return newRefreshProtocolMessage(buf.Bytes(), "bob-output", version), nil +} + +// DecodeBobRefreshResult deserializes Bob refhresh output. +func DecodeBobRefreshResult(m *protocol.Message) (*dkg.BobOutput, error) { + if err := versionIsSupported(m.Version); err != nil { + return nil, errors.Wrap(err, "version error") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := new(dkg.BobOutput) + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} diff --git a/pkg/crypto/tecdsa/dklsv1/sign/multiply.go b/pkg/crypto/tecdsa/dklsv1/sign/multiply.go new file mode 100755 index 000000000..e3d118151 --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/sign/multiply.go @@ -0,0 +1,267 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sign + +import ( + "crypto/rand" + "crypto/subtle" + "fmt" + "math/big" + + "github.com/gtank/merlin" + "github.com/pkg/errors" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" +) + +// This implements the Multiplication protocol of DKLs, protocol 5. https://eprint.iacr.org/2018/499.pdf +// two parties---the "sender" and "receiver", let's say---each input a scalar modulo q. +// the functionality multiplies their two scalars modulo q, and then randomly additively shares the product mod q. +// it then returns the two respective additive shares to the two parties. + +// MultiplySender is the party that plays the role of Sender in the multiplication protocol (protocol 5 of the paper). +type MultiplySender struct { + cOtSender *kos.Sender // underlying cOT sender struct, used by mult. + outputAdditiveShare curves.Scalar // ultimate output share of mult. + gadget [kos.L]curves.Scalar + curve *curves.Curve + transcript *merlin.Transcript + uniqueSessionId [simplest.DigestSize]byte +} + +// MultiplyReceiver is the party that plays the role of Sender in the multiplication protocol (protocol 5 of the paper). +type MultiplyReceiver struct { + cOtReceiver *kos.Receiver // underlying cOT receiver struct, used by mult. + outputAdditiveShare curves.Scalar // ultimate output share of mult. + omega [kos.COtBlockSizeBytes]byte // this is used as an intermediate result during the course of mult. + gadget [kos.L]curves.Scalar + curve *curves.Curve + transcript *merlin.Transcript + uniqueSessionId [simplest.DigestSize]byte +} + +func generateGadgetVector(curve *curves.Curve) ([kos.L]curves.Scalar, error) { + var err error + gadget := [kos.L]curves.Scalar{} + for i := 0; i < kos.Kappa; i++ { + gadget[i], err = curve.Scalar.SetBigInt(new(big.Int).Lsh(big.NewInt(1), uint(i))) + if err != nil { + return gadget, errors.Wrap(err, "creating gadget scalar from big int") + } + } + shake := sha3.NewCShake256(nil, []byte("Coinbase DKLs gadget vector")) + for i := kos.Kappa; i < kos.L; i++ { + var err error + bytes := [simplest.DigestSize]byte{} + if _, err = shake.Read(bytes[:]); err != nil { + return gadget, err + } + gadget[i], err = curve.Scalar.SetBytes(bytes[:]) + if err != nil { + return gadget, errors.Wrap(err, "creating gadget scalar from bytes") + } + } + return gadget, nil +} + +// NewMultiplySender generates a `MultiplySender` instance, ready to take part in multiplication as the "sender". +// You must supply it the _output_ of a seed OT, from the receiver's point of view, as well as params and a unique ID. +// That is, the mult sender must run the base OT as the receiver; note the (apparent) reversal of roles. +func NewMultiplySender(seedOtResults *simplest.ReceiverOutput, curve *curves.Curve, uniqueSessionId [simplest.DigestSize]byte) (*MultiplySender, error) { + sender := kos.NewCOtSender(seedOtResults, curve) + gadget, err := generateGadgetVector(curve) + if err != nil { + return nil, errors.Wrap(err, "error generating gadget vector in new multiply sender") + } + + transcript := merlin.NewTranscript("Coinbase_DKLs_Multiply") + transcript.AppendMessage([]byte("session_id"), uniqueSessionId[:]) + return &MultiplySender{ + cOtSender: sender, + curve: curve, + transcript: transcript, + uniqueSessionId: uniqueSessionId, + gadget: gadget, + }, nil +} + +// NewMultiplyReceiver generates a `MultiplyReceiver` instance, ready to take part in multiplication as the "receiver". +// You must supply it the _output_ of a seed OT, from the sender's point of view, as well as params and a unique ID. +// That is, the mult sender must run the base OT as the sender; note the (apparent) reversal of roles. +func NewMultiplyReceiver(seedOtResults *simplest.SenderOutput, curve *curves.Curve, uniqueSessionId [simplest.DigestSize]byte) (*MultiplyReceiver, error) { + receiver := kos.NewCOtReceiver(seedOtResults, curve) + gadget, err := generateGadgetVector(curve) + if err != nil { + return nil, errors.Wrap(err, "error generating gadget vector in new multiply receiver") + } + transcript := merlin.NewTranscript("Coinbase_DKLs_Multiply") + transcript.AppendMessage([]byte("session_id"), uniqueSessionId[:]) + return &MultiplyReceiver{ + cOtReceiver: receiver, + curve: curve, + transcript: transcript, + uniqueSessionId: uniqueSessionId, + gadget: gadget, + }, nil +} + +// MultiplyRound2Output is the output of the second round of the multiplication protocol. +type MultiplyRound2Output struct { + COTRound2Output *kos.Round2Output + R [kos.L]curves.Scalar + U curves.Scalar +} + +// Algorithm 5. in DKLs. "Encodes" Bob's secret input scalars `beta` in the right way, using the opts. +// The idea is that if Bob were to just put beta's as the choice vector, then Alice could learn a few of Bob's bits. +// using selective failure attacks. so you subtract random components of a public random vector. see paper for details. +func (receiver *MultiplyReceiver) encode(beta curves.Scalar) ([kos.COtBlockSizeBytes]byte, error) { + // passing beta by value, so that we can mutate it locally. check that this does what i want. + encoding := [kos.COtBlockSizeBytes]byte{} + bytesOfBetaMinusDotProduct := beta.Bytes() + if _, err := rand.Read(encoding[kos.KappaBytes:]); err != nil { + return encoding, errors.Wrap(err, "sampling `gamma` random bytes in multiply receiver encode") + } + for j := kos.Kappa; j < kos.L; j++ { + jthBitOfGamma := simplest.ExtractBitFromByteVector(encoding[:], j) + // constant-time computation of the dot product beta - < gR, gamma >. + // we can only `ConstantTimeCopy` byte slices (as opposed to big ints). so keep them as bytes. + option0, err := receiver.curve.Scalar.SetBytes(bytesOfBetaMinusDotProduct[:]) + if err != nil { + return encoding, errors.Wrap(err, "setting masking bits scalar from bytes") + } + option0Bytes := option0.Bytes() + option1 := option0.Sub(receiver.gadget[j]) + option1Bytes := option1.Bytes() + bytesOfBetaMinusDotProduct = option0Bytes + subtle.ConstantTimeCopy(int(jthBitOfGamma), bytesOfBetaMinusDotProduct[:], option1Bytes) + } + copy(encoding[0:kos.KappaBytes], internal.ReverseScalarBytes(bytesOfBetaMinusDotProduct[:])) + return encoding, nil +} + +// Round1Initialize Protocol 5., Multiplication, 3). Bob (receiver) encodes beta and initiates the cOT extension +func (receiver *MultiplyReceiver) Round1Initialize(beta curves.Scalar) (*kos.Round1Output, error) { + var err error + if receiver.omega, err = receiver.encode(beta); err != nil { + return nil, errors.Wrap(err, "encoding input beta in receiver round 1 initialize") + } + cOtRound1Output, err := receiver.cOtReceiver.Round1Initialize(receiver.uniqueSessionId, receiver.omega) + if err != nil { + return nil, errors.Wrap(err, "error in cOT round 1 initialize within multiply round 1 initialize") + } + // write the output of the first round to the transcript + for i := 0; i < kos.Kappa; i++ { + label := []byte(fmt.Sprintf("row %d of U", i)) + receiver.transcript.AppendMessage(label, cOtRound1Output.U[i][:]) + } + receiver.transcript.AppendMessage([]byte("wPrime"), cOtRound1Output.WPrime[:]) + receiver.transcript.AppendMessage([]byte("vPrime"), cOtRound1Output.VPrime[:]) + return cOtRound1Output, nil +} + +// Round2Multiply Protocol 5., steps 3) 5), 7). Alice _responds_ to Bob's initial cOT message, using alpha as input. +// Doesn't actually send the message yet, only stashes it and moves onto the next steps of the multiplication protocol +// specifically, Alice can then do step 5) (compute the outputs of the multiplication protocol), also stashes this. +// Finishes by taking care of 7), after that, Alice is totally done with multiplication and has stashed the outputs. +func (sender *MultiplySender) Round2Multiply(alpha curves.Scalar, round1Output *kos.Round1Output) (*MultiplyRound2Output, error) { + var err error + alphaHat := sender.curve.Scalar.Random(rand.Reader) + input := [kos.L][2]curves.Scalar{} // sender's input, namely integer "sums" in case w_j == 1. + for j := 0; j < kos.L; j++ { + input[j][0] = alpha + input[j][1] = alphaHat + } + round2Output := &MultiplyRound2Output{} + round2Output.COTRound2Output, err = sender.cOtSender.Round2Transfer(sender.uniqueSessionId, input, round1Output) + if err != nil { + return nil, errors.Wrap(err, "error in cOT within round 2 multiply") + } + // write the output of the first round to the transcript + for i := 0; i < kos.Kappa; i++ { + label := []byte(fmt.Sprintf("row %d of U", i)) + sender.transcript.AppendMessage(label, round1Output.U[i][:]) + } + sender.transcript.AppendMessage([]byte("wPrime"), round1Output.WPrime[:]) + sender.transcript.AppendMessage([]byte("vPrime"), round1Output.VPrime[:]) + // write our own output of the second round to the transcript + chiWidth := 2 + for i := 0; i < kos.Kappa; i++ { + for k := 0; k < chiWidth; k++ { + label := []byte(fmt.Sprintf("row %d of Tau", i)) + sender.transcript.AppendMessage(label, round2Output.COTRound2Output.Tau[i][k].Bytes()) + } + } + chi := make([]curves.Scalar, chiWidth) + for k := 0; k < 2; k++ { + label := []byte(fmt.Sprintf("draw challenge chi %d", k)) + randomBytes := sender.transcript.ExtractBytes(label, kos.KappaBytes) + chi[k], err = sender.curve.Scalar.SetBytes(randomBytes) + if err != nil { + return nil, errors.Wrap(err, "setting chi scalar from bytes") + } + } + sender.outputAdditiveShare = sender.curve.Scalar.Zero() + for j := 0; j < kos.L; j++ { + round2Output.R[j] = sender.curve.Scalar.Zero() + for k := 0; k < chiWidth; k++ { + round2Output.R[j] = round2Output.R[j].Add(chi[k].Mul(sender.cOtSender.OutputAdditiveShares[j][k])) + } + sender.outputAdditiveShare = sender.outputAdditiveShare.Add(sender.gadget[j].Mul(sender.cOtSender.OutputAdditiveShares[j][0])) + } + round2Output.U = chi[0].Mul(alpha).Add(chi[1].Mul(alphaHat)) + return round2Output, nil +} + +// Round3Multiply Protocol 5., Multiplication, 3) and 6). Bob finalizes the cOT extension. +// using that and Alice's multiplication message, Bob completes the multiplication protocol, including checks. +// At the end, Bob's values tB_j are populated. +func (receiver *MultiplyReceiver) Round3Multiply(round2Output *MultiplyRound2Output) error { + chiWidth := 2 + // write the output of the second round to the transcript + for i := 0; i < kos.Kappa; i++ { + for k := 0; k < chiWidth; k++ { + label := []byte(fmt.Sprintf("row %d of Tau", i)) + receiver.transcript.AppendMessage(label, round2Output.COTRound2Output.Tau[i][k].Bytes()) + } + } + if err := receiver.cOtReceiver.Round3Transfer(round2Output.COTRound2Output); err != nil { + return errors.Wrap(err, "error within cOT round 3 transfer within round 3 multiply") + } + var err error + chi := make([]curves.Scalar, chiWidth) + for k := 0; k < chiWidth; k++ { + label := []byte(fmt.Sprintf("draw challenge chi %d", k)) + randomBytes := receiver.transcript.ExtractBytes(label, kos.KappaBytes) + chi[k], err = receiver.curve.Scalar.SetBytes(randomBytes) + if err != nil { + return errors.Wrap(err, "setting chi scalar from bytes") + } + } + + receiver.outputAdditiveShare = receiver.curve.Scalar.Zero() + for j := 0; j < kos.L; j++ { + // compute the LHS of bob's step 6) for j. note that we're "adding r_j" to both sides"; so this LHS includes r_j. + // the reason to do this is so that the constant-time (i.e., independent of w_j) calculation of w_j * u can proceed more cleanly. + leftHandSideOfCheck := round2Output.R[j] + for k := 0; k < chiWidth; k++ { + leftHandSideOfCheck = leftHandSideOfCheck.Add(chi[k].Mul(receiver.cOtReceiver.OutputAdditiveShares[j][k])) + } + rightHandSideOfCheck := [simplest.DigestSize]byte{} + jthBitOfOmega := simplest.ExtractBitFromByteVector(receiver.omega[:], j) + subtle.ConstantTimeCopy(int(jthBitOfOmega), rightHandSideOfCheck[:], round2Output.U.Bytes()) + if subtle.ConstantTimeCompare(rightHandSideOfCheck[:], leftHandSideOfCheck.Bytes()) != 1 { + return fmt.Errorf("alice's values R and U failed to check in round 3 multiply") + } + receiver.outputAdditiveShare = receiver.outputAdditiveShare.Add(receiver.gadget[j].Mul(receiver.cOtReceiver.OutputAdditiveShares[j][0])) + } + return nil +} diff --git a/pkg/crypto/tecdsa/dklsv1/sign/multiply_test.go b/pkg/crypto/tecdsa/dklsv1/sign/multiply_test.go new file mode 100755 index 000000000..72f3c55cb --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/sign/multiply_test.go @@ -0,0 +1,48 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sign + +import ( + "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" + "github.com/onsonr/sonr/pkg/crypto/ot/ottest" +) + +func TestMultiply(t *testing.T) { + curve := curves.K256() + hashKeySeed := [simplest.DigestSize]byte{} + _, err := rand.Read(hashKeySeed[:]) + require.NoError(t, err) + + baseOtSenderOutput, baseOtReceiverOutput, err := ottest.RunSimplestOT(curve, kos.Kappa, hashKeySeed) + require.NoError(t, err) + + sender, err := NewMultiplySender(baseOtReceiverOutput, curve, hashKeySeed) + require.NoError(t, err) + receiver, err := NewMultiplyReceiver(baseOtSenderOutput, curve, hashKeySeed) + require.NoError(t, err) + + alpha := curve.Scalar.Random(rand.Reader) + beta := curve.Scalar.Random(rand.Reader) + + round1Output, err := receiver.Round1Initialize(beta) + require.Nil(t, err) + round2Output, err := sender.Round2Multiply(alpha, round1Output) + require.Nil(t, err) + err = receiver.Round3Multiply(round2Output) + require.Nil(t, err) + + product := alpha.Mul(beta) + sum := sender.outputAdditiveShare.Add(receiver.outputAdditiveShare) + require.Equal(t, product, sum) +} diff --git a/pkg/crypto/tecdsa/dklsv1/sign/sign.go b/pkg/crypto/tecdsa/dklsv1/sign/sign.go new file mode 100755 index 000000000..553e2829f --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/sign/sign.go @@ -0,0 +1,358 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package sign implements the 2-2 threshold signature protocol of [DKLs18](https://eprint.iacr.org/2018/499.pdf). +// The signing protocol is defined in "Protocol 4" page 9, of the paper. The Zero Knowledge Proof ideal functionalities are +// realized using schnorr proofs. +package sign + +import ( + "crypto/ecdsa" + "crypto/rand" + "fmt" + "hash" + "math/big" + + "github.com/gtank/merlin" + "github.com/pkg/errors" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" + "github.com/onsonr/sonr/pkg/crypto/zkp/schnorr" +) + +const multiplicationCount = 2 + +// Alice struct encoding Alice's state during one execution of the overall signing algorithm. +// At the end of the joint computation, Alice will not possess the signature. +type Alice struct { + hash hash.Hash // which hash function should we use to compute message (i.e, teh digest) + seedOtResults *simplest.ReceiverOutput + secretKeyShare curves.Scalar // the witness + publicKey curves.Point + curve *curves.Curve + transcript *merlin.Transcript +} + +// Bob struct encoding Bob's state during one execution of the overall signing algorithm. +// At the end of the joint computation, Bob will obtain the signature. +type Bob struct { + // Signature is the resulting digital signature and is the output of this protocol. + Signature *curves.EcdsaSignature + + hash hash.Hash // which hash function should we use to compute message + seedOtResults *simplest.SenderOutput + secretKeyShare curves.Scalar + publicKey curves.Point + transcript *merlin.Transcript + // multiplyReceivers are 2 receivers that are used to perform the two multiplications needed: + // 1. (phi + 1/kA) * (1/kB) + // 2. skA/KA * skB/kB + multiplyReceivers [multiplicationCount]*MultiplyReceiver + kB curves.Scalar + dB curves.Point + curve *curves.Curve +} + +// NewAlice creates a party that can participate in protocol runs of DKLs sign, in the role of Alice. +func NewAlice(curve *curves.Curve, hash hash.Hash, dkgOutput *dkg.AliceOutput) *Alice { + return &Alice{ + hash: hash, + seedOtResults: dkgOutput.SeedOtResult, + curve: curve, + secretKeyShare: dkgOutput.SecretKeyShare, + publicKey: dkgOutput.PublicKey, + transcript: merlin.NewTranscript("Coinbase_DKLs_Sign"), + } +} + +// NewBob creates a party that can participate in protocol runs of DKLs sign, in the role of Bob. +// This party receives the signature at the end. +func NewBob(curve *curves.Curve, hash hash.Hash, dkgOutput *dkg.BobOutput) *Bob { + return &Bob{ + hash: hash, + seedOtResults: dkgOutput.SeedOtResult, + curve: curve, + secretKeyShare: dkgOutput.SecretKeyShare, + publicKey: dkgOutput.PublicKey, + transcript: merlin.NewTranscript("Coinbase_DKLs_Sign"), + } +} + +// SignRound2Output is the output of the 3rd round of the protocol. +type SignRound2Output struct { + // KosRound1Outputs is the output of the first round of OT Extension, stored for future rounds. + KosRound1Outputs [multiplicationCount]*kos.Round1Output + + // DB is D_{B} = k_{B} . G from the paper. + DB curves.Point + + // Seed is the random value used to derive the joint unique session id. + Seed [simplest.DigestSize]byte +} + +// SignRound3Output is the output of the 3rd round of the protocol. +type SignRound3Output struct { + // MultiplyRound2Outputs is the output of the second round of multiply sub-protocol. Stored to use in future rounds. + MultiplyRound2Outputs [multiplicationCount]*MultiplyRound2Output + + // RSchnorrProof is ZKP for the value R = k_{A} . D_{B} from the paper. + RSchnorrProof *schnorr.Proof + + // RPrime is R' = k'_{A} . D_{B} from the paper. + RPrime curves.Point + + // EtaPhi is the Eta_{Phi} from the paper. + EtaPhi curves.Scalar + + // EtaSig is the Eta_{Sig} from the paper. + EtaSig curves.Scalar +} + +// Round1GenerateRandomSeed first step of the generation of the shared random salt `idExt` +// in this round, Alice flips 32 random bytes and sends them to Bob. +// Note that this is not _explicitly_ given as part of the protocol in https://eprint.iacr.org/2018/499.pdf, Protocol 1). +// Rather, it is part of our generation of `idExt`, the shared random salt which both parties must use in cOT. +// This value introduced in Protocol 9), very top of page 16. it is not indicated how it should be derived. +// We do it by having each party sample 32 bytes, then by appending _both_ as salts. Secure if either party is honest +func (alice *Alice) Round1GenerateRandomSeed() ([simplest.DigestSize]byte, error) { + aliceSeed := [simplest.DigestSize]byte{} + if _, err := rand.Read(aliceSeed[:]); err != nil { + return [simplest.DigestSize]byte{}, errors.Wrap(err, "generating random bytes in alice round 1 generate") + } + alice.transcript.AppendMessage([]byte("session_id_alice"), aliceSeed[:]) + return aliceSeed, nil +} + +// Round2Initialize Bob's initial message, which kicks off the signature process. Protocol 1, Bob's steps 1) - 3). +// Bob's work here entails beginning the Diffie–Hellman-like construction of the instance key / nonce, +// as well as preparing the inputs which he will feed into the multiplication protocol, +// and moreover actually initiating the (first respective messages of) the multiplication protocol using these inputs. +// This latter step in turn amounts to sending the initial message in a new cOT extension. +// All the resulting data gets packaged and sent to Alice. +func (bob *Bob) Round2Initialize(aliceSeed [simplest.DigestSize]byte) (*SignRound2Output, error) { + bobSeed := [simplest.DigestSize]byte{} + if _, err := rand.Read(bobSeed[:]); err != nil { + return nil, errors.Wrap(err, "flipping random coins in bob round 2 initialize") + } + bob.transcript.AppendMessage([]byte("session_id_alice"), aliceSeed[:]) + bob.transcript.AppendMessage([]byte("session_id_bob"), bobSeed[:]) + + var err error + uniqueSessionId := [simplest.DigestSize]byte{} // will use and _re-use_ this throughout, for sub-session IDs + copy(uniqueSessionId[:], bob.transcript.ExtractBytes([]byte("multiply receiver id 0"), simplest.DigestSize)) + bob.multiplyReceivers[0], err = NewMultiplyReceiver(bob.seedOtResults, bob.curve, uniqueSessionId) + if err != nil { + return nil, errors.Wrap(err, "error creating multiply receiver 0 in Bob sign round 3") + } + copy(uniqueSessionId[:], bob.transcript.ExtractBytes([]byte("multiply receiver id 1"), simplest.DigestSize)) + bob.multiplyReceivers[1], err = NewMultiplyReceiver(bob.seedOtResults, bob.curve, uniqueSessionId) + if err != nil { + return nil, errors.Wrap(err, "error creating multiply receiver 1 in Bob sign round 3") + } + round2Output := &SignRound2Output{ + Seed: bobSeed, + } + bob.kB = bob.curve.Scalar.Random(rand.Reader) + bob.dB = bob.curve.ScalarBaseMult(bob.kB) + round2Output.DB = bob.dB + kBInv := bob.curve.Scalar.One().Div(bob.kB) + + round2Output.KosRound1Outputs[0], err = bob.multiplyReceivers[0].Round1Initialize(kBInv) + if err != nil { + return nil, errors.Wrap(err, "error in multiply round 1 initialize 0 within Bob sign round 3 initialize") + } + round2Output.KosRound1Outputs[1], err = bob.multiplyReceivers[1].Round1Initialize(bob.secretKeyShare.Mul(kBInv)) + if err != nil { + return nil, errors.Wrap(err, "error in multiply round 1 initialize 1 within Bob sign round 3 initialize") + } + return round2Output, nil +} + +// Round3Sign Alice's first message. Alice is the _responder_; she is responding to Bob's initial message. +// This is Protocol 1 (p. 6), and contains Alice's steps 3) -- 8). these can all be combined into one message. +// Alice's job here is to finish computing the shared instance key / nonce, as well as multiplication input values; +// then to invoke the multiplication on these two input values (stashing the outputs in her running result struct), +// then to use the _output_ of the multiplication (which she already possesses as of the end of her computation), +// and use that to compute some final values which will help Bob compute the final signature. +func (alice *Alice) Round3Sign(message []byte, round2Output *SignRound2Output) (*SignRound3Output, error) { + alice.transcript.AppendMessage([]byte("session_id_bob"), round2Output.Seed[:]) + + multiplySenders := [multiplicationCount]*MultiplySender{} + var err error + uniqueSessionId := [simplest.DigestSize]byte{} // will use and _re-use_ this throughout, for sub-session IDs + copy(uniqueSessionId[:], alice.transcript.ExtractBytes([]byte("multiply receiver id 0"), simplest.DigestSize)) + if multiplySenders[0], err = NewMultiplySender(alice.seedOtResults, alice.curve, uniqueSessionId); err != nil { + return nil, errors.Wrap(err, "creating multiply sender 0 in Alice round 4 sign") + } + copy(uniqueSessionId[:], alice.transcript.ExtractBytes([]byte("multiply receiver id 1"), simplest.DigestSize)) + if multiplySenders[1], err = NewMultiplySender(alice.seedOtResults, alice.curve, uniqueSessionId); err != nil { + return nil, errors.Wrap(err, "creating multiply sender 1 in Alice round 4 sign") + } + round3Output := &SignRound3Output{} + kPrimeA := alice.curve.Scalar.Random(rand.Reader) + round3Output.RPrime = round2Output.DB.Mul(kPrimeA) + hashRPrimeBytes := sha3.Sum256(round3Output.RPrime.ToAffineCompressed()) + hashRPrime, err := alice.curve.Scalar.SetBytes(hashRPrimeBytes[:]) + if err != nil { + return nil, errors.Wrap(err, "setting hashRPrime scalar from bytes") + } + kA := hashRPrime.Add(kPrimeA) + copy(uniqueSessionId[:], alice.transcript.ExtractBytes([]byte("schnorr proof for R"), simplest.DigestSize)) + rSchnorrProver := schnorr.NewProver(alice.curve, round2Output.DB, uniqueSessionId[:]) + round3Output.RSchnorrProof, err = rSchnorrProver.Prove(kA) + if err != nil { + return nil, errors.Wrap(err, "generating schnorr proof for R = kA * DB in alice round 4 sign") + } + // reassign / stash the below value here just for notational clarity. + // this is _the_ key public point R in the ECDSA signature. we'll use its coordinate X in various places. + r := round3Output.RSchnorrProof.Statement + phi := alice.curve.Scalar.Random(rand.Reader) + kAInv := alice.curve.Scalar.One().Div(kA) + + if round3Output.MultiplyRound2Outputs[0], err = multiplySenders[0].Round2Multiply(phi.Add(kAInv), round2Output.KosRound1Outputs[0]); err != nil { + return nil, errors.Wrap(err, "error in round 2 multiply 0 within alice round 4 sign") + } + if round3Output.MultiplyRound2Outputs[1], err = multiplySenders[1].Round2Multiply(alice.secretKeyShare.Mul(kAInv), round2Output.KosRound1Outputs[1]); err != nil { + return nil, errors.Wrap(err, "error in round 2 multiply 1 within alice round 4 sign") + } + + one := alice.curve.Scalar.One() + gamma1 := alice.curve.ScalarBaseMult(kA.Mul(phi).Add(one)) + other := r.Mul(multiplySenders[0].outputAdditiveShare.Neg()) + gamma1 = gamma1.Add(other) + hashGamma1Bytes := sha3.Sum256(gamma1.ToAffineCompressed()) + hashGamma1, err := alice.curve.Scalar.SetBytes(hashGamma1Bytes[:]) + if err != nil { + return nil, errors.Wrap(err, "setting hashGamma1 scalar from bytes") + } + round3Output.EtaPhi = hashGamma1.Add(phi) + if _, err = alice.hash.Write(message); err != nil { + return nil, errors.Wrap(err, "writing message to hash in alice round 4 sign") + } + digest := alice.hash.Sum(nil) + hOfMAsInteger, err := alice.curve.Scalar.SetBytes(digest) + if err != nil { + return nil, errors.Wrap(err, "setting hOfMAsInteger scalar from bytes") + } + affineCompressedForm := r.ToAffineCompressed() + if len(affineCompressedForm) != 33 { + return nil, errors.New("the compressed form must be exactly 33 bytes") + } + // Discard the leading byte and parse the rest as the X coordinate. + rX, err := alice.curve.Scalar.SetBytes(affineCompressedForm[1:]) + if err != nil { + return nil, errors.Wrap(err, "setting rX scalar from bytes") + } + + sigA := hOfMAsInteger.Mul(multiplySenders[0].outputAdditiveShare).Add(rX.Mul(multiplySenders[1].outputAdditiveShare)) + gamma2 := alice.publicKey.Mul(multiplySenders[0].outputAdditiveShare) + other = alice.curve.ScalarBaseMult(multiplySenders[1].outputAdditiveShare.Neg()) + gamma2 = gamma2.Add(other) + hashGamma2Bytes := sha3.Sum256(gamma2.ToAffineCompressed()) + hashGamma2, err := alice.curve.Scalar.SetBytes(hashGamma2Bytes[:]) + if err != nil { + return nil, errors.Wrap(err, "setting hashGamma2 scalar from bytes") + } + round3Output.EtaSig = hashGamma2.Add(sigA) + return round3Output, nil +} + +// Round4Final this is Bob's last portion of the signature computation, and ultimately results in the complete signature +// corresponds to Protocol 1, Bob's steps 3) -- 10). +// Bob begins by _finishing_ the OT-based multiplication, using Alice's one and only message to him re: the mult. +// Bob then move's onto the remainder of Alice's message, which contains extraneous data used to finish the signature. +// Using this data, Bob completes the signature, which gets stored in `Bob.Sig`. Bob also verifies it. +func (bob *Bob) Round4Final(message []byte, round3Output *SignRound3Output) error { + if err := bob.multiplyReceivers[0].Round3Multiply(round3Output.MultiplyRound2Outputs[0]); err != nil { + return errors.Wrap(err, "error in round 3 multiply 0 within sign round 5") + } + if err := bob.multiplyReceivers[1].Round3Multiply(round3Output.MultiplyRound2Outputs[1]); err != nil { + return errors.Wrap(err, "error in round 3 multiply 1 within sign round 5") + } + rPrimeHashedBytes := sha3.Sum256(round3Output.RPrime.ToAffineCompressed()) + rPrimeHashed, err := bob.curve.Scalar.SetBytes(rPrimeHashedBytes[:]) + if err != nil { + return errors.Wrap(err, "setting rPrimeHashed scalar from bytes") + } + r := bob.dB.Mul(rPrimeHashed) + r = r.Add(round3Output.RPrime) + // To ensure that the correct public statement is used, we use the public statement that we have calculated + // instead of the open Alice sent us. + round3Output.RSchnorrProof.Statement = r + uniqueSessionId := [simplest.DigestSize]byte{} + copy(uniqueSessionId[:], bob.transcript.ExtractBytes([]byte("schnorr proof for R"), simplest.DigestSize)) + if err = schnorr.Verify(round3Output.RSchnorrProof, bob.curve, bob.dB, uniqueSessionId[:]); err != nil { + return errors.Wrap(err, "bob's verification of alice's schnorr proof re: r failed") + } + zero := bob.curve.Scalar.Zero() + affineCompressedForm := r.ToAffineCompressed() + if len(affineCompressedForm) != 33 { + return errors.New("the compressed form must be exactly 33 bytes") + } + rY := affineCompressedForm[0] & 0x1 // this is bit(0) of Y coordinate + rX, err := bob.curve.Scalar.SetBytes(affineCompressedForm[1:]) + if err != nil { + return errors.Wrap(err, "setting rX scalar from bytes") + } + bob.Signature = &curves.EcdsaSignature{ + R: rX.Add(zero).BigInt(), // slight trick here; add it to 0 just to mod it by q (now it's mod p!) + V: int(rY), + } + gamma1 := r.Mul(bob.multiplyReceivers[0].outputAdditiveShare) + gamma1HashedBytes := sha3.Sum256(gamma1.ToAffineCompressed()) + gamma1Hashed, err := bob.curve.Scalar.SetBytes(gamma1HashedBytes[:]) + if err != nil { + return errors.Wrap(err, "setting gamma1Hashed scalar from bytes") + } + phi := round3Output.EtaPhi.Sub(gamma1Hashed) + theta := bob.multiplyReceivers[0].outputAdditiveShare.Sub(phi.Div(bob.kB)) + if _, err = bob.hash.Write(message); err != nil { + return errors.Wrap(err, "writing message to hash in Bob sign round 5 final") + } + digestBytes := bob.hash.Sum(nil) + digest, err := bob.curve.Scalar.SetBytes(digestBytes) + if err != nil { + return errors.Wrap(err, "setting digest scalar from bytes") + } + capitalR, err := bob.curve.Scalar.SetBigInt(bob.Signature.R) + if err != nil { + return errors.Wrap(err, "setting capitalR scalar from big int") + } + sigB := digest.Mul(theta).Add(capitalR.Mul(bob.multiplyReceivers[1].outputAdditiveShare)) + gamma2 := bob.curve.ScalarBaseMult(bob.multiplyReceivers[1].outputAdditiveShare) + other := bob.publicKey.Mul(theta.Neg()) + gamma2 = gamma2.Add(other) + gamma2HashedBytes := sha3.Sum256(gamma2.ToAffineCompressed()) + gamma2Hashed, err := bob.curve.Scalar.SetBytes(gamma2HashedBytes[:]) + if err != nil { + return errors.Wrap(err, "setting gamma2Hashed scalar from bytes") + } + scalarS := sigB.Add(round3Output.EtaSig.Sub(gamma2Hashed)) + bob.Signature.S = scalarS.BigInt() + if bob.Signature.S.Bit(255) == 1 { + bob.Signature.S = scalarS.Neg().BigInt() + bob.Signature.V ^= 1 + } + // now verify the signature + unCompressedAffinePublicKey := bob.publicKey.ToAffineUncompressed() + if len(unCompressedAffinePublicKey) != 65 { + return errors.New("the uncompressed form must have exactly 65 bytes") + } + x := new(big.Int).SetBytes(unCompressedAffinePublicKey[1:33]) + y := new(big.Int).SetBytes(unCompressedAffinePublicKey[33:]) + ellipticCurve, err := bob.curve.ToEllipticCurve() + if err != nil { + return errors.Wrap(err, "invalid curve") + } + if !ecdsa.Verify(&ecdsa.PublicKey{Curve: ellipticCurve, X: x, Y: y}, digestBytes, bob.Signature.R, bob.Signature.S) { + return fmt.Errorf("final signature failed to verify") + } + return nil +} diff --git a/pkg/crypto/tecdsa/dklsv1/sign/sign_test.go b/pkg/crypto/tecdsa/dklsv1/sign/sign_test.go new file mode 100755 index 000000000..b44aa020f --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/sign/sign_test.go @@ -0,0 +1,81 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package sign + +import ( + "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/ot/base/simplest" + "github.com/onsonr/sonr/pkg/crypto/ot/extension/kos" + "github.com/onsonr/sonr/pkg/crypto/ot/ottest" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/dkg" +) + +func TestSign(t *testing.T) { + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + } + for _, curve := range curveInstances { + hashKeySeed := [simplest.DigestSize]byte{} + _, err := rand.Read(hashKeySeed[:]) + require.NoError(t, err) + + baseOtSenderOutput, baseOtReceiverOutput, err := ottest.RunSimplestOT(curve, kos.Kappa, hashKeySeed) + require.NoError(t, err) + + secretKeyShareA := curve.Scalar.Random(rand.Reader) + secretKeyShareB := curve.Scalar.Random(rand.Reader) + require.NoError(t, err) + publicKey := curve.ScalarBaseMult(secretKeyShareA.Mul(secretKeyShareB)) + alice := NewAlice(curve, sha3.New256(), &dkg.AliceOutput{SeedOtResult: baseOtReceiverOutput, SecretKeyShare: secretKeyShareA, PublicKey: publicKey}) + bob := NewBob(curve, sha3.New256(), &dkg.BobOutput{SeedOtResult: baseOtSenderOutput, SecretKeyShare: secretKeyShareB, PublicKey: publicKey}) + + message := []byte("A message.") + seed, err := alice.Round1GenerateRandomSeed() + require.NoError(t, err) + round3Output, err := bob.Round2Initialize(seed) + require.NoError(t, err) + round4Output, err := alice.Round3Sign(message, round3Output) + require.NoError(t, err) + err = bob.Round4Final(message, round4Output) + require.NoError(t, err, "curve: %s", curve.Name) + } +} + +func BenchmarkSign(b *testing.B) { + curve := curves.K256() + hashKeySeed := [simplest.DigestSize]byte{} + _, err := rand.Read(hashKeySeed[:]) + require.NoError(b, err) + + baseOtSenderOutput, baseOtReceiverOutput, err := ottest.RunSimplestOT(curve, kos.Kappa, hashKeySeed) + require.NoError(b, err) + + secretKeyShareA := curve.Scalar.Random(rand.Reader) + secretKeyShareB := curve.Scalar.Random(rand.Reader) + publicKey := curve.ScalarBaseMult(secretKeyShareA.Mul(secretKeyShareB)) + alice := NewAlice(curve, sha3.New256(), &dkg.AliceOutput{SeedOtResult: baseOtReceiverOutput, SecretKeyShare: secretKeyShareA, PublicKey: publicKey}) + bob := NewBob(curve, sha3.New256(), &dkg.BobOutput{SeedOtResult: baseOtSenderOutput, SecretKeyShare: secretKeyShareB, PublicKey: publicKey}) + + message := []byte("A message.") + for n := 0; n < b.N; n++ { + seed, err := alice.Round1GenerateRandomSeed() + require.NoError(b, err) + round3Output, err := bob.Round2Initialize(seed) + require.NoError(b, err) + round4Output, err := alice.Round3Sign(message, round3Output) + require.NoError(b, err) + err = bob.Round4Final(message, round4Output) + require.NoError(b, err) + } +} diff --git a/pkg/crypto/tecdsa/dklsv1/signserializers.go b/pkg/crypto/tecdsa/dklsv1/signserializers.go new file mode 100755 index 000000000..82d0e54bb --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/signserializers.go @@ -0,0 +1,122 @@ +package dklsv1 + +import ( + "bytes" + "encoding/gob" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/core/protocol" + "github.com/onsonr/sonr/pkg/crypto/tecdsa/dklsv1/sign" +) + +func newSignProtocolMessage(payload []byte, round string, version uint) *protocol.Message { + return &protocol.Message{ + Protocol: protocol.Dkls18Sign, + Version: version, + Payloads: map[string][]byte{payloadKey: payload}, + Metadata: map[string]string{"round": round}, + } +} + +func encodeSignRound1Output(commitment [32]byte, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(&commitment); err != nil { + return nil, errors.WithStack(err) + } + return newSignProtocolMessage(buf.Bytes(), "1", version), nil +} + +func decodeSignRound2Input(m *protocol.Message) ([32]byte, error) { + if m.Version != protocol.Version1 { + return [32]byte{}, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := [32]byte{} + if err := dec.Decode(&decoded); err != nil { + return [32]byte{}, errors.WithStack(err) + } + return decoded, nil +} + +func encodeSignRound2Output(output *sign.SignRound2Output, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(output); err != nil { + return nil, errors.WithStack(err) + } + return newSignProtocolMessage(buf.Bytes(), "2", version), nil +} + +func decodeSignRound3Input(m *protocol.Message) (*sign.SignRound2Output, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := &sign.SignRound2Output{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeSignRound3Output(output *sign.SignRound3Output, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(output); err != nil { + return nil, errors.WithStack(err) + } + return newSignProtocolMessage(buf.Bytes(), "3", version), nil +} + +func decodeSignRound4Input(m *protocol.Message) (*sign.SignRound3Output, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := &sign.SignRound3Output{} + if err := dec.Decode(&decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} + +func encodeSignature(signature *curves.EcdsaSignature, version uint) (*protocol.Message, error) { + if version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + if err := enc.Encode(signature); err != nil { + return nil, errors.WithStack(err) + } + return newSignProtocolMessage(buf.Bytes(), "signature", version), nil +} + +// DecodeSignature serializes the signature. +func DecodeSignature(m *protocol.Message) (*curves.EcdsaSignature, error) { + if m.Version != protocol.Version1 { + return nil, errors.New("only version 1 is supported") + } + buf := bytes.NewBuffer(m.Payloads[payloadKey]) + dec := gob.NewDecoder(buf) + decoded := &curves.EcdsaSignature{} + if err := dec.Decode(decoded); err != nil { + return nil, errors.WithStack(err) + } + return decoded, nil +} diff --git a/pkg/crypto/tecdsa/dklsv1/testdata/alice-dkls-v1-dkg.bin b/pkg/crypto/tecdsa/dklsv1/testdata/alice-dkls-v1-dkg.bin new file mode 100755 index 000000000..682f9b8df --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/testdata/alice-dkls-v1-dkg.bin @@ -0,0 +1 @@ +{"Protocol":"DKLs18-DKG","Version":200,"Payloads":{"direct":"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"},"Metadata":{"round":"alice-output"}} \ No newline at end of file diff --git a/pkg/crypto/tecdsa/dklsv1/testdata/bob-dkls-v1-dkg.bin b/pkg/crypto/tecdsa/dklsv1/testdata/bob-dkls-v1-dkg.bin new file mode 100755 index 000000000..c6245ab99 --- /dev/null +++ b/pkg/crypto/tecdsa/dklsv1/testdata/bob-dkls-v1-dkg.bin @@ -0,0 +1 @@ +{"Protocol":"DKLs18-DKG","Version":200,"Payloads":{"direct":"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"},"Metadata":{"round":"bob-output"}} \ No newline at end of file diff --git a/pkg/crypto/ted25519/frost/README.md b/pkg/crypto/ted25519/frost/README.md new file mode 100755 index 000000000..c7ecc4a7b --- /dev/null +++ b/pkg/crypto/ted25519/frost/README.md @@ -0,0 +1,13 @@ +--- +aliases: [README] +tags: [] +title: README +linter-yaml-title-alias: README +date created: Wednesday, April 17th 2024, 4:11:40 pm +date modified: Thursday, April 18th 2024, 8:19:25 am +--- + +## FROST: Flexible Round-Optimized Schnorr Threshold Signatures + +This package is an implementation of t-of-n threshold signature of +[FROST: Flexible Round-Optimized Schnorr Threshold Signatures](https://eprint.iacr.org/2020/852.pdf) diff --git a/pkg/crypto/ted25519/frost/challenge_derive.go b/pkg/crypto/ted25519/frost/challenge_derive.go new file mode 100755 index 000000000..e01cf28bc --- /dev/null +++ b/pkg/crypto/ted25519/frost/challenge_derive.go @@ -0,0 +1,27 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package frost + +import ( + "crypto/sha512" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type ChallengeDerive interface { + DeriveChallenge(msg []byte, pubKey curves.Point, r curves.Point) (curves.Scalar, error) +} + +type Ed25519ChallengeDeriver struct{} + +func (ed Ed25519ChallengeDeriver) DeriveChallenge(msg []byte, pubKey curves.Point, r curves.Point) (curves.Scalar, error) { + h := sha512.New() + _, _ = h.Write(r.ToAffineCompressed()) + _, _ = h.Write(pubKey.ToAffineCompressed()) + _, _ = h.Write(msg) + return new(curves.ScalarEd25519).SetBytesWide(h.Sum(nil)) +} diff --git a/pkg/crypto/ted25519/frost/participant.go b/pkg/crypto/ted25519/frost/participant.go new file mode 100755 index 000000000..c0a2745e8 --- /dev/null +++ b/pkg/crypto/ted25519/frost/participant.go @@ -0,0 +1,83 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package frost is an implementation of t-of-n threshold signature of https://eprint.iacr.org/2020/852.pdf +package frost + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/dkg/frost" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// Signer is a tSchnorr player performing the signing operation. +type Signer struct { + skShare curves.Scalar // secret signing share for this signer + vkShare curves.Point // store verification key share + verificationKey curves.Point // verification key + id uint32 // The ID assigned to this signer's shamir share + threshold uint32 + curve *curves.Curve + round uint + lCoeffs map[uint32]curves.Scalar // lCoeffs are Lagrange coefficients of each cosigner. + cosigners []uint32 + state *state // Accumulated intermediate values associated with signing + challengeDeriver ChallengeDerive +} + +type state struct { + // Round 1 + capD, capE curves.Point // capD, capE are commitments this signer generates in signing round 1 + smallD, smallE curves.Scalar // smallD, smallE are scalars this signer generates in signing round 1 + + // Round 2 + commitments map[uint32]*Round1Bcast // Store commitments broadcast after signing round 1 + msg []byte + c curves.Scalar + capRs map[uint32]curves.Point + sumR curves.Point +} + +// NewSigner create a signer from a dkg participant +// Note that we can pre-assign Lagrange coefficients lcoeffs of each cosigner. This optimizes performance. +// See paragraph 3 of section 3 in the draft - https://tools.ietf.org/pdf/draft-komlo-frost-00.pdf +func NewSigner(info *frost.DkgParticipant, id, thresh uint32, lcoeffs map[uint32]curves.Scalar, cosigners []uint32, challengeDeriver ChallengeDerive) (*Signer, error) { + if info == nil || len(cosigners) == 0 || len(lcoeffs) == 0 { + return nil, internal.ErrNilArguments + } + + if thresh > uint32(len(cosigners)) { + return nil, fmt.Errorf("threshold is higher than number of signers") + } + + if len(lcoeffs) != len(cosigners) { + return nil, fmt.Errorf("expected coefficients to be equal to number of cosigners") + } + + // Check if cosigners and lcoeffs contain the same IDs + for i := 0; i < len(cosigners); i++ { + id := cosigners[i] + if _, ok := lcoeffs[id]; !ok { + return nil, fmt.Errorf("lcoeffs and cosigners have inconsistent ID") + } + } + + return &Signer{ + skShare: info.SkShare, + vkShare: info.VkShare, + verificationKey: info.VerificationKey, + id: id, + threshold: thresh, + curve: info.Curve, + round: 1, + lCoeffs: lcoeffs, + cosigners: cosigners, + state: &state{}, + challengeDeriver: challengeDeriver, + }, nil +} diff --git a/pkg/crypto/ted25519/frost/round1.go b/pkg/crypto/ted25519/frost/round1.go new file mode 100755 index 000000000..83d1f0d6e --- /dev/null +++ b/pkg/crypto/ted25519/frost/round1.go @@ -0,0 +1,78 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package frost + +import ( + "bytes" + crand "crypto/rand" + "encoding/gob" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// Round1Bcast contains values to be broadcast to all players after the completion of signing round 1. +type Round1Bcast struct { + Di, Ei curves.Point +} + +func (result *Round1Bcast) Encode() ([]byte, error) { + gob.Register(result.Di) // just the point for now + gob.Register(result.Ei) + buf := &bytes.Buffer{} + enc := gob.NewEncoder(buf) + if err := enc.Encode(result); err != nil { + return nil, errors.Wrap(err, "couldn't encode round 1 broadcast") + } + return buf.Bytes(), nil +} + +func (result *Round1Bcast) Decode(input []byte) error { + buf := bytes.NewBuffer(input) + dec := gob.NewDecoder(buf) + if err := dec.Decode(result); err != nil { + return errors.Wrap(err, "couldn't encode round 1 broadcast") + } + return nil +} + +func (signer *Signer) SignRound1() (*Round1Bcast, error) { + // Make sure signer is not empty + if signer == nil || signer.curve == nil { + return nil, internal.ErrNilArguments + } + + // Make sure round number is correct + if signer.round != 1 { + return nil, internal.ErrInvalidRound + } + + // Step 1 - Sample di, ei + di := signer.curve.Scalar.Random(crand.Reader) + + ei := signer.curve.Scalar.Random(crand.Reader) + + // Step 2 - Compute Di, Ei + Di := signer.curve.ScalarBaseMult(di) + + Ei := signer.curve.ScalarBaseMult(ei) + + // Update round number + signer.round = 2 + + // Store di, ei, Di, Ei locally and broadcast Di, Ei + signer.state.capD = Di + signer.state.capE = Ei + signer.state.smallD = di + signer.state.smallE = ei + return &Round1Bcast{ + Di, + Ei, + }, nil +} diff --git a/pkg/crypto/ted25519/frost/round2.go b/pkg/crypto/ted25519/frost/round2.go new file mode 100755 index 000000000..a39b39703 --- /dev/null +++ b/pkg/crypto/ted25519/frost/round2.go @@ -0,0 +1,181 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package frost + +import ( + "bytes" + "encoding/gob" + "fmt" + + "github.com/pkg/errors" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// Round2Bcast contains values that will be broadcast to other signers after completion of round 2. +type Round2Bcast struct { + Zi curves.Scalar + Vki curves.Point +} + +func (result *Round2Bcast) Encode() ([]byte, error) { + gob.Register(result.Zi) + gob.Register(result.Vki) // just the point for now + buf := &bytes.Buffer{} + enc := gob.NewEncoder(buf) + if err := enc.Encode(result); err != nil { + return nil, errors.Wrap(err, "couldn't encode round 1 broadcast") + } + return buf.Bytes(), nil +} + +func (result *Round2Bcast) Decode(input []byte) error { + buf := bytes.NewBuffer(input) + dec := gob.NewDecoder(buf) + if err := dec.Decode(result); err != nil { + return errors.Wrap(err, "couldn't encode round 1 broadcast") + } + return nil +} + +// SignRound2 implements FROST signing round 2. +func (signer *Signer) SignRound2(msg []byte, round2Input map[uint32]*Round1Bcast) (*Round2Bcast, error) { + // Make sure necessary items of signer are not empty + if signer == nil || signer.curve == nil || signer.state == nil { + return nil, internal.ErrNilArguments + } + + // Make sure those private d is not empty and not zero + if signer.state.smallD == nil || signer.state.smallD.IsZero() { + return nil, fmt.Errorf("empty d or d is zero") + } + + // Make sure those private e is not empty and not zero + if signer.state.smallE == nil || signer.state.smallE.IsZero() { + return nil, fmt.Errorf("empty e or e is zero") + } + + // Make sure msg is not empty + if len(msg) == 0 { + return nil, internal.ErrNilArguments + } + + // Make sure the round number is correct + if signer.round != 2 { + return nil, internal.ErrInvalidRound + } + + // Check length of round2Input + if uint32(len(round2Input)) != signer.threshold { + return nil, fmt.Errorf("Invalid length of round2Input") + } + + // Step 2 - Check Dj, Ej on the curve and Store round2Input + for id, input := range round2Input { + if input == nil || input.Di == nil || input.Ei == nil { + return nil, fmt.Errorf("round2Input is nil from participant with id %d\n", id) + } + if !input.Di.IsOnCurve() || input.Di.IsIdentity() { + return nil, fmt.Errorf("commitment Di is not on the curve with id %d\n", id) + } + if !input.Ei.IsOnCurve() || input.Ei.IsIdentity() { + return nil, fmt.Errorf("commitment Ei is not on the curve with id %d\n", id) + } + } + // Store Dj, Ej for further usage. + signer.state.commitments = round2Input + + // Step 3-6 + R := signer.curve.NewIdentityPoint() + var ri curves.Scalar + Rs := make(map[uint32]curves.Point, signer.threshold) + for id, data := range round2Input { + // Construct the blob (j, m, {Dj, Ej}) + blob := concatHashArray(id, msg, round2Input, signer.cosigners) + + // Step 4 - rj = H(j,m,{Dj,Ej}_{j in [1...t]}) + rj := signer.curve.Scalar.Hash(blob) + if signer.id == id { + ri = rj + } + + // Step 5 - R_j = D_j + r_j*E_j + rjEj := data.Ei.Mul(rj) + Rj := rjEj.Add(data.Di) + // assign Rj + Rs[id] = Rj + + // Step 6 - R = R+Rj + R = R.Add(Rj) + } + + // Step 7 - c = H(m, R) + c, err := signer.challengeDeriver.DeriveChallenge(msg, signer.verificationKey, R) + if err != nil { + return nil, err + } + + // Step 8 - Record c, R, Rjs + signer.state.c = c + signer.state.capRs = Rs + signer.state.sumR = R + + // Step 9 - zi = di + ei*ri + Li*ski*c + Li := signer.lCoeffs[signer.id] + Liski := Li.Mul(signer.skShare) + + Liskic := Liski.Mul(c) + + if R.IsNegative() { + signer.state.smallE = signer.state.smallE.Neg() + signer.state.smallD = signer.state.smallD.Neg() + } + + eiri := signer.state.smallE.Mul(ri) + + // Compute zi = di+ei*ri+Li*ski*c + zi := Liskic.Add(eiri) + zi = zi.Add(signer.state.smallD) + + // Update round number and store message + signer.round = 3 + signer.state.msg = msg + + // set smallD and smallE to zero since they are one-time use + signer.state.smallD = signer.curve.NewScalar() + signer.state.smallE = signer.curve.NewScalar() + + // Step 10 - Broadcast zi, vki to other participants + return &Round2Bcast{ + zi, + signer.vkShare, + }, nil +} + +// concatHashArray puts id, msg and (Dj,Ej), j=1...t into a byte array +func concatHashArray(id uint32, msg []byte, round2Input map[uint32]*Round1Bcast, cosigners []uint32) []byte { + var blob []byte + // Append identity id + blob = append(blob, byte(id)) + + // Append message msg + blob = append(blob, msg...) + + // Append (Dj, Ej) for all j in [1...t] + for i := 0; i < len(cosigners); i++ { + id := cosigners[i] + bytesDi := round2Input[id].Di.ToAffineCompressed() + bytesEi := round2Input[id].Ei.ToAffineCompressed() + + // Following the spec, we should add each party's identity. + blob = append(blob, byte(id)) + blob = append(blob, bytesDi...) + blob = append(blob, bytesEi...) + } + return blob +} diff --git a/pkg/crypto/ted25519/frost/round3.go b/pkg/crypto/ted25519/frost/round3.go new file mode 100755 index 000000000..ab62dddc8 --- /dev/null +++ b/pkg/crypto/ted25519/frost/round3.go @@ -0,0 +1,157 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package frost + +import ( + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + "github.com/onsonr/sonr/pkg/crypto/internal" +) + +// Round3Bcast contains the output of FROST signature, i.e., it contains FROST signature (z,c) and the +// corresponding message msg. +type Round3Bcast struct { + R curves.Point + Z, C curves.Scalar + msg []byte +} + +// Define frost signature type +type Signature struct { + Z curves.Scalar + C curves.Scalar +} + +func (signer *Signer) SignRound3(round3Input map[uint32]*Round2Bcast) (*Round3Bcast, error) { + // Make sure signer is not empty + if signer == nil || signer.curve == nil { + return nil, internal.ErrNilArguments + } + + // Make sure signer's smallD and smallE are zero + if !signer.state.smallD.IsZero() || !signer.state.smallE.IsZero() { + return nil, fmt.Errorf("signer's private smallD and smallE should be zero since one-time use") + } + + // Make sure the signer has had the msg + if len(signer.state.msg) == 0 { + return nil, internal.ErrNilArguments + } + + // Validate Round3Input + if round3Input == nil { + return nil, internal.ErrNilArguments + } + for _, data := range round3Input { + if data == nil { + return nil, internal.ErrNilArguments + } + } + + // Make sure the signer has commitments stored at the end of round 1. + if signer.state.commitments == nil || len(signer.state.commitments) != len(round3Input) { + return nil, internal.ErrNilArguments + } + + // Make sure the round number is correct + if signer.round != 3 { + return nil, internal.ErrInvalidRound + } + + // Round2 Input has different length of threshold + if uint32(len(round3Input)) != signer.threshold { + return nil, fmt.Errorf("invalid length of round3Input") + } + + // Step 1-3 + // Step 1: For j in [1...t] + z := signer.curve.NewScalar() + negate := signer.state.sumR.IsNegative() + for id, data := range round3Input { + zj := data.Zi + vkj := data.Vki + + // Step 2: Verify zj*G = Rj + c*Lj*vkj + // zj*G + zjG := signer.curve.ScalarBaseMult(zj) + + // c*Lj + cLj := signer.state.c.Mul(signer.lCoeffs[id]) + + // cLjvkj + cLjvkj := vkj.Mul(cLj) + + // Rj + c*Lj*vkj + Rj := signer.state.capRs[id] + if negate { + Rj = Rj.Neg() + } + right := cLjvkj.Add(Rj) + + // Check equation + if !zjG.Equal(right) { + return nil, fmt.Errorf("zjG != right with participant id %d\n", id) + } + + // Step 3 - z = z+zj + z = z.Add(zj) + } + + // Step 4 - 7: Self verify the signature (z, c) + // Step 5 - R' = z*G + (-c)*vk + zG := signer.curve.ScalarBaseMult(z) + cvk := signer.verificationKey.Mul(signer.state.c.Neg()) + tempR := zG.Add(cvk) + // Step 6 - c' = H(m, R') + tempC, err := signer.challengeDeriver.DeriveChallenge(signer.state.msg, signer.verificationKey, tempR) + if err != nil { + return nil, err + } + + // Step 7 - Check c = c' + if tempC.Cmp(signer.state.c) != 0 { + return nil, fmt.Errorf("invalid signature: c != c'") + } + + // Updating round number + signer.round = 4 + + // Step 8 - Broadcast signature and message + return &Round3Bcast{ + signer.state.sumR, + z, + signer.state.c, + signer.state.msg, + }, nil +} + +// Method to verify a frost signature. +func Verify(curve *curves.Curve, challengeDeriver ChallengeDerive, vk curves.Point, msg []byte, signature *Signature) (bool, error) { + if vk == nil || msg == nil || len(msg) == 0 || signature.C == nil || signature.Z == nil { + return false, fmt.Errorf("invalid input") + } + z := signature.Z + c := signature.C + + // R' = z*G - c*vk + zG := curve.ScalarBaseMult(z) + cvk := vk.Mul(c.Neg()) + tempR := zG.Add(cvk) + + // c' = H(m, R') + tempC, err := challengeDeriver.DeriveChallenge(msg, vk, tempR) + if err != nil { + return false, err + } + + // Check c == c' + if tempC.Cmp(c) != 0 { + return false, fmt.Errorf("invalid signature: c != c'") + } + return true, nil +} diff --git a/pkg/crypto/ted25519/frost/rounds_test.go b/pkg/crypto/ted25519/frost/rounds_test.go new file mode 100755 index 000000000..e0e7dcd8c --- /dev/null +++ b/pkg/crypto/ted25519/frost/rounds_test.go @@ -0,0 +1,404 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package frost + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + dkg "github.com/onsonr/sonr/pkg/crypto/dkg/frost" + "github.com/onsonr/sonr/pkg/crypto/sharing" +) + +var ( + testCurve = curves.ED25519() + ctx = "string to prevent replay attack" +) + +// Create two DKG participants. +func PrepareDkgOutput(t *testing.T) (*dkg.DkgParticipant, *dkg.DkgParticipant) { + // Initiate two participants and running DKG round 1 + p1, err := dkg.NewDkgParticipant(1, 2, ctx, testCurve, 2) + require.NoError(t, err) + p2, err := dkg.NewDkgParticipant(2, 2, ctx, testCurve, 1) + require.NoError(t, err) + bcast1, p2psend1, _ := p1.Round1(nil) + bcast2, p2psend2, _ := p2.Round1(nil) + bcast := make(map[uint32]*dkg.Round1Bcast) + p2p1 := make(map[uint32]*sharing.ShamirShare) + p2p2 := make(map[uint32]*sharing.ShamirShare) + bcast[1] = bcast1 + bcast[2] = bcast2 + p2p1[2] = p2psend2[1] + p2p2[1] = p2psend1[2] + + // Running DKG round 2 + _, _ = p1.Round2(bcast, p2p1) + _, _ = p2.Round2(bcast, p2p2) + return p1, p2 +} + +// Test FROST signing round 1 +func TestSignRound1Works(t *testing.T) { + p1, p2 := PrepareDkgOutput(t) + require.NotNil(t, p1) + require.NotNil(t, p2) + + scheme, _ := sharing.NewShamir(2, 2, testCurve) + lCoeffs, err := scheme.LagrangeCoeffs([]uint32{p1.Id, p2.Id}) + require.NoError(t, err) + signer1, err := NewSigner(p1, 1, 2, lCoeffs, []uint32{1, 2}, &Ed25519ChallengeDeriver{}) + require.NoError(t, err) + round1Out, _ := signer1.SignRound1() + require.NotNil(t, round1Out.Ei) + require.NotNil(t, round1Out.Di) + require.NotNil(t, signer1.state.smallE) + require.NotNil(t, signer1.state.smallD) + require.NotNil(t, signer1.state.capD) + require.NotNil(t, signer1.state.capE) + require.Equal(t, signer1.round, uint(2)) + require.Equal(t, signer1.cosigners, []uint32{1, 2}) +} + +func TestSignRound1RepeatCall(t *testing.T) { + p1, p2 := PrepareDkgOutput(t) + scheme, _ := sharing.NewShamir(2, 2, testCurve) + lCoeffs, err := scheme.LagrangeCoeffs([]uint32{p1.Id, p2.Id}) + require.NoError(t, err) + signer1, _ := NewSigner(p1, 1, 2, lCoeffs, []uint32{1, 2}, &Ed25519ChallengeDeriver{}) + _, err = signer1.SignRound1() + require.NoError(t, err) + _, err = signer1.SignRound1() + require.Error(t, err) +} + +func PrepareNewSigners(t *testing.T) (*Signer, *Signer) { + threshold := uint32(2) + limit := uint32(2) + p1, p2 := PrepareDkgOutput(t) + require.Equal(t, p1.VerificationKey, p2.VerificationKey) + scheme, err := sharing.NewShamir(threshold, limit, testCurve) + // field = sharing.NewField(p1.curve.Params().N) + require.NotNil(t, scheme) + require.NoError(t, err) + lCoeffs, err := scheme.LagrangeCoeffs([]uint32{p1.Id, p2.Id}) + require.NotNil(t, lCoeffs[1]) + require.NotNil(t, lCoeffs[2]) + require.NoError(t, err) + signer1, err := NewSigner(p1, p1.Id, threshold, lCoeffs, []uint32{p1.Id, p2.Id}, &Ed25519ChallengeDeriver{}) + require.NotNil(t, signer1) + require.NoError(t, err) + signer2, err := NewSigner(p2, p2.Id, threshold, lCoeffs, []uint32{p1.Id, p2.Id}, &Ed25519ChallengeDeriver{}) + require.NotNil(t, signer2) + require.NoError(t, err) + return signer1, signer2 +} + +func TestSignRound2Works(t *testing.T) { + // Preparing round 2 inputs + signer1, signer2 := PrepareNewSigners(t) + require.Equal(t, signer1.verificationKey, signer2.verificationKey) + require.NotNil(t, signer1) + require.NotNil(t, signer2) + round1Out1, _ := signer1.SignRound1() + round1Out2, _ := signer2.SignRound1() + round2Input := make(map[uint32]*Round1Bcast) + round2Input[signer1.id] = round1Out1 + round2Input[signer2.id] = round1Out2 + + // Actual Test + msg := []byte("message") + round2Out, err := signer1.SignRound2(msg, round2Input) + require.NotNil(t, round2Out) + require.NoError(t, err) + require.Equal(t, signer1.round, uint(3)) + require.NotNil(t, signer1.state.commitments) + require.Equal(t, signer1.state.msg, msg) + require.True(t, signer1.state.smallD.IsZero()) + require.True(t, signer1.state.smallE.IsZero()) +} + +func TestSignRound2RepeatCall(t *testing.T) { + // Preparing round 2 inputs + signer1, signer2 := PrepareNewSigners(t) + require.NotNil(t, signer1) + require.NotNil(t, signer2) + round1Out1, _ := signer1.SignRound1() + round1Out2, _ := signer2.SignRound1() + round2Input := make(map[uint32]*Round1Bcast) + round2Input[signer1.id] = round1Out1 + round2Input[signer2.id] = round1Out2 + + // Actual Test + msg := []byte("message") + _, err := signer1.SignRound2(msg, round2Input) + require.NoError(t, err) + _, err = signer1.SignRound2(msg, round2Input) + require.Error(t, err) +} + +func TestSignRound2BadInput(t *testing.T) { + // Preparing round 2 inputs + signer1, signer2 := PrepareNewSigners(t) + _, _ = signer1.SignRound1() + round1Out2, _ := signer2.SignRound1() + round2Input := make(map[uint32]*Round1Bcast) + + // Actual Test: Set an input to nil + round2Input[signer1.id] = nil + round2Input[signer2.id] = round1Out2 + msg := []byte("message") + _, err := signer1.SignRound2(msg, round2Input) + require.Error(t, err) + + // Preparing round 2 inputs + signer1, signer2 = PrepareNewSigners(t) + round1Out1, _ := signer1.SignRound1() + round1Out2, _ = signer2.SignRound1() + round2Input = make(map[uint32]*Round1Bcast) + round2Input[signer1.id] = round1Out1 + round2Input[signer2.id] = round1Out2 + // Actual Test: Nil message + _, err = signer1.SignRound2(nil, round2Input) + require.Error(t, err) + + // Preparing round 2 inputs + signer1, signer2 = PrepareNewSigners(t) + round1Out1, _ = signer1.SignRound1() + round1Out2, _ = signer2.SignRound1() + round2Input = make(map[uint32]*Round1Bcast) + + // Actual Test: Set invalid round2Input length + round2Input[signer1.id] = round1Out1 + round2Input[signer2.id] = round1Out2 + round2Input[3] = round1Out2 + _, err = signer1.SignRound2(msg, round2Input) + require.Error(t, err) + + // Preparing round 2 inputs + signer1, signer2 = PrepareNewSigners(t) + round1Out1, _ = signer1.SignRound1() + round1Out2, _ = signer2.SignRound1() + round2Input = make(map[uint32]*Round1Bcast) + + // Actual Test: Set invalid round2Input length + round1Out2.Ei = nil + round2Input[signer1.id] = round1Out1 + round2Input[signer2.id] = round1Out2 + _, err = signer1.SignRound2(msg, round2Input) + require.Error(t, err) + + // Preparing round 2 inputs + signer1, signer2 = PrepareNewSigners(t) + round1Out1, _ = signer1.SignRound1() + round1Out2, _ = signer2.SignRound1() + round2Input = make(map[uint32]*Round1Bcast) + round2Input[signer1.id] = round1Out1 + round2Input[signer2.id] = round1Out2 + + // Actual Test: Set nil smallD and smallE + signer1.state.smallD = testCurve.NewScalar() + signer1.state.smallE = nil + _, err = signer1.SignRound2(msg, round2Input) + require.Error(t, err) +} + +func PrepareRound3Input(t *testing.T) (*Signer, *Signer, map[uint32]*Round2Bcast) { + // Running sign round 1 + threshold := uint32(2) + limit := uint32(2) + p1, p2 := PrepareDkgOutput(t) + require.Equal(t, p1.VerificationKey, p2.VerificationKey) + scheme, err := sharing.NewShamir(threshold, limit, testCurve) + require.NotNil(t, scheme) + require.NoError(t, err) + lCoeffs, err := scheme.LagrangeCoeffs([]uint32{p1.Id, p2.Id}) + require.NotNil(t, lCoeffs[1]) + require.NotNil(t, lCoeffs[2]) + require.NoError(t, err) + + signer1, err := NewSigner(p1, p1.Id, threshold, lCoeffs, []uint32{p1.Id, p2.Id}, &Ed25519ChallengeDeriver{}) + require.NotNil(t, signer1) + require.NoError(t, err) + signer2, err := NewSigner(p2, p2.Id, threshold, lCoeffs, []uint32{p1.Id, p2.Id}, &Ed25519ChallengeDeriver{}) + require.NotNil(t, signer2) + require.NoError(t, err) + + round1Out1, _ := signer1.SignRound1() + round1Out2, _ := signer2.SignRound1() + round2Input := make(map[uint32]*Round1Bcast, threshold) + round2Input[signer1.id] = round1Out1 + round2Input[signer2.id] = round1Out2 + + // Running sign round 2 + msg := []byte("message") + round2Out1, _ := signer1.SignRound2(msg, round2Input) + round2Out2, _ := signer2.SignRound2(msg, round2Input) + round3Input := make(map[uint32]*Round2Bcast, threshold) + round3Input[signer1.id] = round2Out1 + round3Input[signer2.id] = round2Out2 + return signer1, signer2, round3Input +} + +func TestSignRound3Works(t *testing.T) { + signer1, signer2, round3Input := PrepareRound3Input(t) + round3Out1, err := signer1.SignRound3(round3Input) + require.NoError(t, err) + require.NotNil(t, round3Out1) + round3Out2, err := signer2.SignRound3(round3Input) + require.NoError(t, err) + require.NotNil(t, round3Out2) + // signer1 and signer2 outputs the same signature + require.Equal(t, round3Out1.Z, round3Out2.Z) + require.Equal(t, round3Out1.C, round3Out2.C) + + // test verify method + msg := []byte("message") + signature := &Signature{ + round3Out1.Z, + round3Out1.C, + } + vk := signer1.verificationKey + ok, err := Verify(signer1.curve, signer1.challengeDeriver, vk, msg, signature) + require.True(t, ok) + require.NoError(t, err) + + ok, err = Verify(signer2.curve, signer2.challengeDeriver, vk, msg, signature) + require.True(t, ok) + require.NoError(t, err) +} + +func TestSignRound3RepeatCall(t *testing.T) { + signer1, _, round3Input := PrepareRound3Input(t) + _, err := signer1.SignRound3(round3Input) + require.NoError(t, err) + _, err = signer1.SignRound3(round3Input) + require.Error(t, err) +} + +func TestSignRound3BadInput(t *testing.T) { + signer1, _, round3Input := PrepareRound3Input(t) + + // Actual test: nil input + round3Input[signer1.id] = nil + _, err := signer1.SignRound3(round3Input) + require.Error(t, err) + round3Input = nil + _, err = signer1.SignRound3(round3Input) + require.Error(t, err) + + // Actual test: set invalid length of round3Input + signer1, _, round3Input = PrepareRound3Input(t) + round3Input[100] = round3Input[signer1.id] + _, err = signer1.SignRound3(round3Input) + require.Error(t, err) + + // Actual test: maul the round3Input + signer1, _, round3Input = PrepareRound3Input(t) + round3Input[signer1.id].Zi = round3Input[signer1.id].Zi.Add(testCurve.Scalar.New(2)) + _, err = signer1.SignRound3(round3Input) + require.Error(t, err) + + // Actual test: set non-zero smallD and smallE + signer1, _, round3Input = PrepareRound3Input(t) + signer1.state.smallD = testCurve.Scalar.New(1) + _, err = signer1.SignRound3(round3Input) + require.Error(t, err) +} + +func TestFullRoundsWorks(t *testing.T) { + // Give a full-round test (FROST DKG + FROST Signing) with threshold = 2 and limit = 3, same as the test of tECDSA + threshold := 2 + limit := 3 + + // Prepare DKG participants + participants := make(map[uint32]*dkg.DkgParticipant, limit) + for i := 1; i <= limit; i++ { + otherIds := make([]uint32, limit-1) + idx := 0 + for j := 1; j <= limit; j++ { + if i == j { + continue + } + otherIds[idx] = uint32(j) + idx++ + } + p, err := dkg.NewDkgParticipant(uint32(i), uint32(threshold), ctx, testCurve, otherIds...) + require.NoError(t, err) + participants[uint32(i)] = p + } + + // FROST DKG round 1 + rnd1Bcast := make(map[uint32]*dkg.Round1Bcast, len(participants)) + rnd1P2p := make(map[uint32]dkg.Round1P2PSend, len(participants)) + for id, p := range participants { + bcast, p2psend, err := p.Round1(nil) + require.NoError(t, err) + rnd1Bcast[id] = bcast + rnd1P2p[id] = p2psend + } + + // FROST DKG round 2 + for id := range rnd1Bcast { + rnd1P2pForP := make(map[uint32]*sharing.ShamirShare) + for jid := range rnd1P2p { + if jid == id { + continue + } + rnd1P2pForP[jid] = rnd1P2p[jid][id] + } + _, err := participants[id].Round2(rnd1Bcast, rnd1P2pForP) + require.NoError(t, err) + } + + // Prepare Lagrange coefficients + scheme, _ := sharing.NewShamir(uint32(threshold), uint32(limit), testCurve) + + // Here we use {1, 3} as 2 of 3 cosigners, we can also set cosigners as {1, 2}, {2, 3} + signerIds := []uint32{1, 3} + lCoeffs, err := scheme.LagrangeCoeffs(signerIds) + require.NoError(t, err) + signers := make(map[uint32]*Signer, threshold) + for _, id := range signerIds { + signers[id], err = NewSigner(participants[id], id, uint32(threshold), lCoeffs, signerIds, &Ed25519ChallengeDeriver{}) + require.NoError(t, err) + require.NotNil(t, signers[id].skShare) + } + + // Running sign round 1 + round2Input := make(map[uint32]*Round1Bcast, threshold) + for id := range signers { + round1Out, err := signers[id].SignRound1() + require.NoError(t, err) + round2Input[signers[id].id] = round1Out + } + + // Running sign round 2 + msg := []byte("message") + round3Input := make(map[uint32]*Round2Bcast, threshold) + for id := range signers { + round2Out, err := signers[id].SignRound2(msg, round2Input) + require.NoError(t, err) + round3Input[signers[id].id] = round2Out + } + + // Running sign round 3 + result := make(map[uint32]*Round3Bcast, threshold) + for id := range signers { + round3Out, err := signers[id].SignRound3(round3Input) + require.NoError(t, err) + result[signers[id].id] = round3Out + } + + // Every signer has the same output Schnorr signature + require.Equal(t, result[1].Z, result[3].Z) + // require.Equal(t, z, result[3].Z) + require.Equal(t, result[1].C, result[3].C) + // require.Equal(t, c, result[3].C) +} diff --git a/pkg/crypto/ted25519/ted25519/ed25519.go b/pkg/crypto/ted25519/ted25519/ed25519.go new file mode 100755 index 000000000..fe66a1e05 --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/ed25519.go @@ -0,0 +1,288 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ted25519 implements the Ed25519 signature algorithm. See https://ed25519.cr.yp.to/ +// +// These functions are also compatible with the "Ed25519" function defined in +// RFC 8032. However, unlike RFC 8032's formulation, this package's private key +// representation includes a public key suffix to make multiple signing +// operations with the same key more efficient. This package refers to the RFC +// 8032 private key as the "seed". +// This code is a port of the public domain, “ref10” implementation of ed25519 +// from SUPERCOP. +package ted25519 + +import ( + "bytes" + "crypto" + cryptorand "crypto/rand" + "crypto/sha512" + "fmt" + "io" + "strconv" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +const ( + // PublicKeySize is the size, in bytes, of public keys as used in this package. + PublicKeySize = 32 + // PrivateKeySize is the size, in bytes, of private keys as used in this package. + PrivateKeySize = 64 + // SignatureSize is the size, in bytes, of signatures generated and verified by this package. + SignatureSize = 64 + // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. + SeedSize = 32 +) + +// PublicKey is the type of Ed25519 public keys. +type PublicKey []byte + +// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. +type PrivateKey []byte + +// Bytes returns the publicKey in byte array +func (p PublicKey) Bytes() []byte { + return p +} + +// Public returns the PublicKey corresponding to priv. +func (priv PrivateKey) Public() crypto.PublicKey { + publicKey := make([]byte, PublicKeySize) + copy(publicKey, priv[32:]) + return PublicKey(publicKey) +} + +// Seed returns the private key seed corresponding to priv. It is provided for +// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds +// in this package. +func (priv PrivateKey) Seed() []byte { + seed := make([]byte, SeedSize) + copy(seed, priv[:32]) + return seed +} + +// Sign signs the given message with priv. +// Ed25519 performs two passes over messages to be signed and therefore cannot +// handle pre-hashed messages. Thus opts.HashFunc() must return zero to +// indicate the message hasn't been hashed. This can be achieved by passing +// crypto.Hash(0) as the value for opts. +func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) { + if opts.HashFunc() != crypto.Hash(0) { + return nil, fmt.Errorf("ed25519: cannot sign hashed message") + } + sig, err := Sign(priv, message) + if err != nil { + return nil, err + } + return sig, nil +} + +// GenerateKey generates a public/private key pair using entropy from rand. +// If rand is nil, crypto/rand.Reader will be used. +func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { + if rand == nil { + rand = cryptorand.Reader + } + + seed := make([]byte, SeedSize) + if _, err := io.ReadFull(rand, seed); err != nil { + return nil, nil, err + } + + privateKey, err := NewKeyFromSeed(seed) + if err != nil { + return nil, nil, err + } + publicKey := make([]byte, PublicKeySize) + copy(publicKey, privateKey[32:]) + + return publicKey, privateKey, nil +} + +// NewKeyFromSeed calculates a private key from a seed. It will panic if +// len(seed) is not SeedSize. This function is provided for interoperability +// with RFC 8032. RFC 8032's private keys correspond to seeds in this +// package. +func NewKeyFromSeed(seed []byte) (PrivateKey, error) { + // Outline the function body so that the returned key can be stack-allocated. + privateKey := make([]byte, PrivateKeySize) + err := newKeyFromSeed(privateKey, seed) + if err != nil { + return nil, err + } + return privateKey, nil +} + +func newKeyFromSeed(privateKey, seed []byte) error { + if l := len(seed); l != SeedSize { + return fmt.Errorf("ed25519: bad seed length: " + strconv.Itoa(l)) + } + + digest := sha512.Sum512(seed) + digest[0] &= 248 + digest[31] &= 127 + digest[31] |= 64 + + var hBytes [32]byte + copy(hBytes[:], digest[:]) + + h, err := new(curves.ScalarEd25519).SetBytesClamping(hBytes[:]) + if err != nil { + return err + } + ed25519 := curves.ED25519() + A := ed25519.ScalarBaseMult(h) + + publicKeyBytes := A.ToAffineCompressed() + copy(privateKey, seed) + copy(privateKey[32:], publicKeyBytes[:]) + return nil +} + +// Sign signs the message with privateKey and returns a signature. It will +// panic if len(privateKey) is not PrivateKeySize. +func Sign(privateKey PrivateKey, message []byte) ([]byte, error) { + // Outline the function body so that the returned signature can be + // stack-allocated. + signature := make([]byte, SignatureSize) + err := sign(signature, privateKey, message) + if err != nil { + return nil, err + } + return signature, nil +} + +func sign(signature, privateKey, message []byte) error { + if l := len(privateKey); l != PrivateKeySize { + return fmt.Errorf("ed25519: bad private key length: " + strconv.Itoa(l)) + } + + var err error + h := sha512.New() + _, err = h.Write(privateKey[:32]) + if err != nil { + return err + } + + var digest1, messageDigest, hramDigest [64]byte + var expandedSecretKey [32]byte + _ = h.Sum(digest1[:0]) + copy(expandedSecretKey[:], digest1[:]) + expandedSecretKey[0] &= 248 + expandedSecretKey[31] &= 63 + expandedSecretKey[31] |= 64 + + h.Reset() + _, err = h.Write(digest1[32:]) + if err != nil { + return err + } + _, err = h.Write(message) + if err != nil { + return err + } + _ = h.Sum(messageDigest[:0]) + + r, err := new(curves.ScalarEd25519).SetBytesWide(messageDigest[:]) + if err != nil { + return err + } + + // R = r * G + R := curves.ED25519().Point.Generator().Mul(r) + encodedR := R.ToAffineCompressed() + + h.Reset() + _, err = h.Write(encodedR[:]) + if err != nil { + return err + } + _, err = h.Write(privateKey[32:]) + if err != nil { + return err + } + _, err = h.Write(message) + if err != nil { + return err + } + _ = h.Sum(hramDigest[:0]) + + // Set k and s + k, err := new(curves.ScalarEd25519).SetBytesWide(hramDigest[:]) + if err != nil { + return err + } + + s, err := new(curves.ScalarEd25519).SetBytesClamping(expandedSecretKey[:]) + if err != nil { + return err + } + + // S = k*s + r + S := k.MulAdd(s, r) + copy(signature[:], encodedR[:]) + copy(signature[32:], S.Bytes()[:]) + return nil +} + +// Verify reports whether sig is a valid signature of message by publicKey. It +// will panic if len(publicKey) is not PublicKeySize. +// Previously publicKey is of type PublicKey +func Verify(publicKey PublicKey, message, sig []byte) (bool, error) { + if l := len(publicKey); l != PublicKeySize { + return false, fmt.Errorf("ed25519: bad public key length: " + strconv.Itoa(l)) + } + + if len(sig) != SignatureSize || sig[63]&224 != 0 { + return false, fmt.Errorf("ed25519: bad signature size: " + strconv.Itoa(len(sig))) + } + + var publicKeyBytes [32]byte + copy(publicKeyBytes[:], publicKey) + + A, err := new(curves.PointEd25519).FromAffineCompressed(publicKeyBytes[:]) + if err != nil { + return false, err + } + + // Negate sets A = -A, and returns A. It actually negates X and T but keep Y and Z + negA := A.Neg() + + h := sha512.New() + _, err = h.Write(sig[:32]) + if err != nil { + panic(err) + } + + _, err = h.Write(publicKey[:]) + if err != nil { + return false, err + } + + _, err = h.Write(message) + if err != nil { + return false, err + } + + var digest [64]byte + _ = h.Sum(digest[:0]) + + hReduced, err := new(curves.ScalarEd25519).SetBytesWide(digest[:]) + if err != nil { + return false, err + } + + var s [32]byte + copy(s[:], sig[32:]) + sScalar, err := new(curves.ScalarEd25519).SetBytesCanonical(s[:]) + if err != nil { + return false, err + } + + // R' = hash * A + s * BasePoint + R := new(curves.PointEd25519).VarTimeDoubleScalarBaseMult(hReduced, negA, sScalar) + // Check R == R' + return bytes.Equal(sig[:32], R.ToAffineCompressed()), nil +} diff --git a/pkg/crypto/ted25519/ted25519/ed25519_test.go b/pkg/crypto/ted25519/ted25519/ed25519_test.go new file mode 100755 index 000000000..e7cc2cca2 --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/ed25519_test.go @@ -0,0 +1,165 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ted25519 + +import ( + "bytes" + "crypto" + "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// sign.input.gz is a selection of test cases from +// https://ed25519.cr.yp.to/python/sign.input +const testVectorPath = "../../../test/data/sign.input.gz" + +type zeroReader struct{} + +func (zeroReader) Read(buf []byte) (int, error) { + for i := range buf { + buf[i] = 0 + } + return len(buf), nil +} + +func TestUnmarshalMarshal(t *testing.T) { + pub, _, err := GenerateKey(rand.Reader) + require.NoError(t, err) + + var publicKeyBytes [32]byte + copy(publicKeyBytes[:], pub) + + A, err := new(curves.PointEd25519).FromAffineCompressed(publicKeyBytes[:]) + require.NoError(t, err) + var pub2 [32]byte + copy(pub2[:], A.ToAffineCompressed()) + + if publicKeyBytes != pub2 { + t.Errorf("FromBytes(%v)->ToBytes does not round-trip, got %x\n", publicKeyBytes, pub2) + } +} + +func TestSignVerify(t *testing.T) { + var zero zeroReader + public, private, err := GenerateKey(zero) + require.NoError(t, err) + + message := []byte("test message") + sig, err := Sign(private, message) + require.NoError(t, err) + ok, _ := Verify(public, message, sig) + require.True(t, ok) + + wrongMessage := []byte("wrong message") + ok, _ = Verify(public, wrongMessage, sig) + require.True(t, !ok) +} + +func TestCryptoSigner(t *testing.T) { + var zero zeroReader + public, private, _ := GenerateKey(zero) + + signer := crypto.Signer(private) + + publicInterface := signer.Public() + public2, ok := publicInterface.(PublicKey) + if !ok { + t.Fatalf("expected PublicKey from Public() but got %T", publicInterface) + } + + if !bytes.Equal(public, public2) { + t.Errorf("public keys do not match: original:%x vs Public():%x", public, public2) + } + + message := []byte("message") + var noHash crypto.Hash + signature, err := signer.Sign(zero, message, noHash) + if err != nil { + t.Fatalf("error from Sign(): %s", err) + } + + ok, _ = Verify(public, message, signature) + if !ok { + t.Errorf("Verify failed on signature from Sign()") + } +} + +func TestMalleability(t *testing.T) { + // https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test + // that s be in [0, order). This prevents someone from adding a multiple of + // order to s and obtaining a second valid signature for the same message. + msg := []byte{0x54, 0x65, 0x73, 0x74} + sig := []byte{ + 0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a, + 0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b, + 0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67, + 0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d, + 0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33, + 0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d, + } + publicKey := []byte{ + 0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5, + 0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34, + 0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa, + } + + ok, _ := Verify(publicKey, msg, sig) + if ok { + t.Fatal("non-canonical signature accepted") + } +} + +func BenchmarkKeyGeneration(b *testing.B) { + var zero zeroReader + for i := 0; i < b.N; i++ { + if _, _, err := GenerateKey(zero); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkNewKeyFromSeed(b *testing.B) { + seed := make([]byte, SeedSize) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, _ = NewKeyFromSeed(seed) + } +} + +func BenchmarkSigning(b *testing.B) { + var zero zeroReader + _, priv, err := GenerateKey(zero) + if err != nil { + b.Fatal(err) + } + message := []byte("Hello, world!") + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = Sign(priv, message) + } +} + +func BenchmarkVerification(b *testing.B) { + var zero zeroReader + pub, priv, err := GenerateKey(zero) + if err != nil { + b.Fatal(err) + } + message := []byte("Hello, world!") + signature, _ := Sign(priv, message) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = Verify(pub, message, signature) + } +} diff --git a/pkg/crypto/ted25519/ted25519/ext.go b/pkg/crypto/ted25519/ted25519/ext.go new file mode 100755 index 000000000..e5c60d4fb --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/ext.go @@ -0,0 +1,123 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "crypto/sha512" + "strconv" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// GeAdd returns the sum of two public keys, a and b. +func GeAdd(a PublicKey, b PublicKey) PublicKey { + aPoint, err := new(curves.PointEd25519).FromAffineCompressed(a) + if err != nil { + panic("attempted to add invalid point: a") + } + bPoint, err := new(curves.PointEd25519).FromAffineCompressed(b) + if err != nil { + panic("attempted to add invalid point: b") + } + + sum := aPoint.Add(bPoint) + return sum.ToAffineCompressed() +} + +// ExpandSeed applies the standard Ed25519 transform to the seed to turn it into the real private +// key that is used for signing. It returns the expanded seed. +func ExpandSeed(seed []byte) []byte { + digest := sha512.Sum512(seed) + digest[0] &= 248 + digest[31] &= 127 + digest[31] |= 64 + return digest[:32] +} + +// reverseBytes returns a new slice of the input bytes reversed +func reverseBytes(inBytes []byte) []byte { + outBytes := make([]byte, len(inBytes)) + + for i, j := 0, len(inBytes)-1; j >= 0; i, j = i+1, j-1 { + outBytes[i] = inBytes[j] + } + + return outBytes +} + +// ThresholdSign is used for creating signatures for threshold protocols that replace the values of +// the private key and nonce with shamir shares instead. Because of this we must have a custom +// signing implementation that accepts arguments for values that cannot be derived anymore and +// removes the extended key generation since that should be done before the secret is shared. +// +// expandedSecretKeyShare and rShare must be little-endian. +func ThresholdSign( + expandedSecretKeyShare []byte, publicKey PublicKey, + message []byte, + rShare []byte, R PublicKey, // nolint:gocritic +) []byte { + // These length checks are are sanity checks where we panic if a provided value falls outside of the expected range. + // These should never fail in practice but serve to protect us from some bug that would cause us to produce + // signatures using a zero value or clipping off extra bytes unintentionally. + // + // We don't specifically check for 32 byte values as any value within the subgroup field could show up here. This is + // different than the upstream Ed25519 which does, but this seems to be a result of how they initialize their byte + // slices to constants and does not guarantee the value itself is 32 bytes without padding. + if l := len(expandedSecretKeyShare); l == 0 || l > 32 { + panic("ed25519: bad key share length: " + strconv.Itoa(l)) + } + if l := len(rShare); l == 0 || l > 32 { + panic("ed25519: bad nonce share length: " + strconv.Itoa(l)) + } + + var expandedSecretKey, rBytes [32]byte + copy(expandedSecretKey[:], expandedSecretKeyShare) + copy(rBytes[:], rShare) + + // c = H(R || A || m) mod q + var hramDigest [64]byte + var err error + h := sha512.New() + _, err = h.Write(R[:]) + if err != nil { + panic(err) + } + _, err = h.Write(publicKey[:]) + if err != nil { + panic(err) + } + _, err = h.Write(message) + if err != nil { + panic(err) + } + _ = h.Sum(hramDigest[:0]) + + // Set c, x and r + c, err := new(curves.ScalarEd25519).SetBytesWide(hramDigest[:]) + if err != nil { + panic(err) + } + + x, err := new(curves.ScalarEd25519).SetBytesCanonical(expandedSecretKey[:]) + if err != nil { + panic(err) + } + + r, err := new(curves.ScalarEd25519).SetBytesCanonical(rBytes[:]) + if err != nil { + panic(err) + } + + // s = cx+r + s := c.MulAdd(x, r) + + signature := make([]byte, SignatureSize) + copy(signature, R[:]) + copy(signature[32:], s.Bytes()[:]) + + return signature +} diff --git a/pkg/crypto/ted25519/ted25519/ext_test.go b/pkg/crypto/ted25519/ted25519/ext_test.go new file mode 100755 index 000000000..a5e20e961 --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/ext_test.go @@ -0,0 +1,113 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "crypto/rand" + "encoding/hex" + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +const ( + expectedSeedHex = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" + expectedPrivKeyHex = "307c83864f2833cb427a2ef1c00a013cfdff2768d980c0a3a520f006904de94f" +) + +func TestExpandSeed(t *testing.T) { + seedBytes, err := hex.DecodeString(expectedSeedHex) + require.NoError(t, err) + privKeyHex := hex.EncodeToString(ExpandSeed(seedBytes)) + require.Equal(t, expectedPrivKeyHex, privKeyHex) +} + +func TestThresholdSign(t *testing.T) { + pub, priv, err := generateKey() + require.NoError(t, err) + field := curves.NewField(curves.Ed25519Order()) + keyShare := v1.NewShamirShare(0, priv, field) + r := big.NewInt(123456789).Bytes() + nonceShare := v1.NewShamirShare(0, r, field) + + r = reverseBytes(r) + var rInput [32]byte + copy(rInput[:], r) + scalar, err := new(curves.ScalarEd25519).SetBytesCanonical(rInput[:]) + require.NoError(t, err) + noncePub := curves.ED25519().Point.Generator().Mul(scalar) + + message := []byte("fnord!") + wrongMessage := []byte("23") + sig := ThresholdSign(reverseBytes(keyShare.Value.Bytes()), pub, message, reverseBytes(nonceShare.Value.Bytes()), noncePub.ToAffineCompressed()) + + ok, _ := Verify(pub, message, sig) + require.True(t, ok) + ok, _ = Verify(pub, wrongMessage, sig) + require.False(t, ok) +} + +func TestThresholdSign_invalid_secrets(t *testing.T) { + message := []byte("fnord!") + + secret := []byte{0x02} + secret = reverseBytes(secret) + var sInput [32]byte + copy(sInput[:], secret) + scalar, err := new(curves.ScalarEd25519).SetBytesCanonical(sInput[:]) + require.NoError(t, err) + pub := curves.ED25519().Point.Generator().Mul(scalar) + + nonce := []byte{0x03} + nonce = reverseBytes(nonce) + var nInput [32]byte + copy(nInput[:], nonce) + nScalar, err := new(curves.ScalarEd25519).SetBytesCanonical(nInput[:]) + require.NoError(t, err) + noncePub := curves.ED25519().Point.Generator().Mul(nScalar) + + require.PanicsWithValue(t, "ed25519: bad key share length: 0", + func() { + ThresholdSign(make([]byte, 0), pub.ToAffineCompressed(), message, nonce, noncePub.ToAffineCompressed()) + }, + ) + + require.PanicsWithValue(t, "ed25519: bad key share length: 33", + func() { + ThresholdSign(make([]byte, 33), pub.ToAffineCompressed(), message, nonce, noncePub.ToAffineCompressed()) + }, + ) + + require.PanicsWithValue(t, "ed25519: bad nonce share length: 0", + func() { + ThresholdSign(secret, pub.ToAffineCompressed(), message, make([]byte, 0), noncePub.ToAffineCompressed()) + }, + ) + + require.PanicsWithValue(t, "ed25519: bad nonce share length: 33", + func() { + ThresholdSign(secret, pub.ToAffineCompressed(), message, make([]byte, 33), noncePub.ToAffineCompressed()) + }, + ) +} + +// generateKey is the same as generateSharableKey, but used only for testing +func generateKey() (PublicKey, []byte, error) { + pub, priv, err := GenerateKey(rand.Reader) + if err != nil { + return nil, nil, err + } + seed := priv.Seed() + expandedSeed := reverseBytes(ExpandSeed(seed)) + field := &curves.Field{Int: curves.Ed25519Order()} + expandedSeedReduced := field.ReducedElementFromBytes(expandedSeed) + return pub, expandedSeedReduced.Bytes(), nil +} diff --git a/pkg/crypto/ted25519/ted25519/keygen.go b/pkg/crypto/ted25519/ted25519/keygen.go new file mode 100755 index 000000000..a260fa135 --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/keygen.go @@ -0,0 +1,240 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "encoding/binary" + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +// PublicKeyFromBytes converts byte array into PublicKey byte array +func PublicKeyFromBytes(bytes []byte) ([]byte, error) { + if l := len(bytes); l != PublicKeySize { + return nil, fmt.Errorf("invalid public key size: %d", l) + } + + return bytes, nil +} + +// KeyShare represents a share of a generated key. +type KeyShare struct { + *v1.ShamirShare +} + +// NewKeyShare is a KeyShare constructor. +func NewKeyShare(identifier byte, secret []byte) *KeyShare { + field := curves.NewField(curves.Ed25519Order()) + return &KeyShare{v1.NewShamirShare(uint32(identifier), secret, field)} +} + +// Commitments is a collection of public keys with each coefficient of a polynomial as the secret keys. +type Commitments []curves.Point + +// CommitmentsToBytes converts commitments to bytes +func (commitments Commitments) CommitmentsToBytes() [][]byte { + bytes := make([][]byte, len(commitments)) + + for i, c := range commitments { + bytes[i] = c.ToAffineCompressed() + } + + return bytes +} + +// CommitmentsFromBytes converts bytes to commitments +func CommitmentsFromBytes(bytes [][]byte) (Commitments, error) { + comms := make([]curves.Point, len(bytes)) + for i, pubKeyBytes := range bytes { + pubKey, err := PublicKeyFromBytes(pubKeyBytes) + if err != nil { + return nil, err + } + comms[i], err = new(curves.PointEd25519).FromAffineCompressed(pubKey) + if err != nil { + return nil, err + } + } + return comms, nil +} + +// KeyShareFromBytes converts byte array into KeyShare type +func KeyShareFromBytes(bytes []byte) *KeyShare { + field := curves.NewField(curves.Ed25519Order()) + element := field.ElementFromBytes(bytes[4:]) + + // We set first 4 bytes as identifier + identifier := binary.BigEndian.Uint32(bytes[:4]) + return &KeyShare{&v1.ShamirShare{Identifier: identifier, Value: element}} +} + +// ShareConfiguration sets threshold and limit for the protocol +type ShareConfiguration struct { + T int // threshold + N int // total shares +} + +// generateSharableKey generates a random key and returns the public key and private key in +// big-endian encoding. It returns an error if it cannot acquire sufficient randomness. +func generateSharableKey() (PublicKey, []byte, error) { + pub, priv, err := GenerateKey(nil) + if err != nil { + return nil, nil, err + } + + // Internally the PrivateKey type is represented as the seed || public key, but we want to pull + // out seed to share which is the actual private key. + seed := priv.Seed() + + // We must apply the key expansion to the seed before splitting the key. + // Ed25519 signing by default will apply this during signature generation, but since it involves + // a hash function, it breaks the relationship between shares and breaks aggregating signatures. + // Our signature generation does not apply this mutation at signing time. + // + // As per anything that comes from the ed25519 library this value should be treated as + // little-endian so we reverse it before using it. + expandedSeed := reverseBytes(ExpandSeed(seed)) + + // Lastly we must reduce this value into the size of the field so we can share it. This diverges + // from how the standard implementation treats this because their scalar multiplication accepts + // values up to the curve order but we must constrain it to be able to split it and aggregate. + // + // If you read the documentation for the ReducedElementFromBytes function we call below, it + // includes a big warning about how it will return non-uniform outputs depending on the input. + // This is true, but not a concern for keygen specifically because the value we are providing it + // has been generated as the ed25519 spec requires, which has a slight bias by definition of how + // the ExpandSeed operation works. + field := &curves.Field{Int: curves.Ed25519Order()} + expandedSeedReduced := field.ReducedElementFromBytes(expandedSeed) + + return pub, expandedSeedReduced.Bytes(), nil +} + +// GenerateSharedKey generates a random key, splits it, and returns the public key, shares, and VSS commitments. +func GenerateSharedKey(config *ShareConfiguration) (PublicKey, []*KeyShare, Commitments, error) { + pub, priv, err := generateSharableKey() + // pub, priv, err := ed25519.GenerateKey(nil) + if err != nil { + return nil, nil, nil, err + } + + keyShares, commitments, err := splitPrivateKey(config, priv) + if err != nil { + return nil, nil, nil, err + } + + return pub, keyShares, commitments, nil +} + +// splitPrivateKey splits the secret into a set of secret shares and creates a set of commitments of them. +func splitPrivateKey(config *ShareConfiguration, priv []byte) ([]*KeyShare, Commitments, error) { + commitments, shares, err := split(priv, config) + if err != nil { + return nil, nil, err + } + + keyShares := make([]*KeyShare, len(shares)) + for i, s := range shares { + keyShares[i] = &KeyShare{s} + } + return keyShares, commitments, nil +} + +// split contains core operations to split the secret and generate commitments. +func split(secret []byte, config *ShareConfiguration) ([]curves.Point, []*v1.ShamirShare, error) { + field := curves.NewField(curves.Ed25519Order()) + shamir, err := v1.NewShamir(config.T, config.N, field) + if err != nil { + return nil, nil, fmt.Errorf("error in NewShamir") + } + shares, poly, err := shamir.GetSharesAndPolynomial(secret) + if err != nil { + return nil, nil, fmt.Errorf("error in GetSharesAndPolynomial") + } + + // Generate the verifiable commitments to the polynomial for the shares + verifiers := make([]curves.Point, len(poly.Coefficients)) + // curve := sharing.Ed25519() + for i, c := range poly.Coefficients { + // We have to reverse each coefficient, which is different than the method sharing.Split + reverseC := reverseBytes(c.Bytes()) + var reverseInput [32]byte + copy(reverseInput[:], reverseC) + cScalar, err := new(curves.ScalarEd25519).SetBytesCanonical(reverseInput[:]) + if err != nil { + return nil, nil, fmt.Errorf("error in SetBytesCanonical reverseC") + } + v := curves.ED25519().Point.Generator().Mul(cScalar) + verifiers[i] = v + } + return verifiers, shares, nil +} + +// Reconstruct recovers the secret from a set of secret shares. +func Reconstruct(keyShares []*KeyShare, config *ShareConfiguration) ([]byte, error) { + curve := v1.Ed25519() + field := curves.NewField(curve.Params().N) + shamir, err := v1.NewShamir(config.T, config.N, field) + if err != nil { + return nil, err + } + + shares := make([]*v1.ShamirShare, len(keyShares)) + for i, s := range keyShares { + shares[i] = s.ShamirShare + } + return shamir.Combine(shares...) +} + +// VerifyVSS validates that a Share represents a solution to a Shamir polynomial +// in which len(commitments) + 1 solutions are required to construct the private +// key for the public key at commitments[0]. +func (share *KeyShare) VerifyVSS(commitments Commitments, config *ShareConfiguration) (bool, error) { + if len(commitments) < config.T { + return false, fmt.Errorf("not enough verifiers to check") + } + field := curves.NewField(curves.Ed25519Order()) + xBytes := make([]byte, 4) + binary.BigEndian.PutUint32(xBytes, share.Identifier) + x := field.ElementFromBytes(xBytes) + i := share.Value.Modulus.One() + + // c_0 + rhs := commitments[0] + + // Compute the sum of products + // c_0 * c_1^i * c_2^{i^2} *c_3^{i^3} + for j := 1; j < len(commitments); j++ { + // i *= x + i = i.Mul(x) + + var iBytes [32]byte + copy(iBytes[:], i.Bytes()[:]) + iScalar, err := new(curves.ScalarEd25519).SetBytesCanonical(iBytes[:]) + if err != nil { + return false, fmt.Errorf("error in SetBytesCanonical iBytes") + } + c := commitments[j].Mul(iScalar) + + // ...* c_j^{i^j} + rhs = rhs.Add(c) + } + + vValue := reverseBytes(share.Value.Bytes()) + var vInput [32]byte + copy(vInput[:], vValue) + vScalar, err := new(curves.ScalarEd25519).SetBytes(vInput[:]) + if err != nil { + return false, err + } + lhs := curves.ED25519().ScalarBaseMult(vScalar) + + // Check if lhs == rhs + return lhs.Equal(rhs), nil +} diff --git a/pkg/crypto/ted25519/ted25519/keygen_test.go b/pkg/crypto/ted25519/ted25519/keygen_test.go new file mode 100755 index 000000000..fe6f0bc2c --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/keygen_test.go @@ -0,0 +1,125 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +func TestGenerateEd25519Key(t *testing.T) { + config := ShareConfiguration{T: 2, N: 3} + + // Generate and verify correct number of shares are produced + pub, shares, _, err := GenerateSharedKey(&config) + require.NoError(t, err) + require.Equal(t, config.N, len(shares)) + + // Verify reconstuction works for all permutations of shares + shareVec := make([]*KeyShare, 2) + shareVec[0] = shares[0] + shareVec[1] = shares[1] + secret1, err := Reconstruct(shareVec, &config) + require.Nil(t, err) + shareVec[0] = shares[1] + shareVec[1] = shares[2] + secret2, err := Reconstruct(shareVec, &config) + require.Nil(t, err) + shareVec[0] = shares[0] + shareVec[1] = shares[2] + secret3, err := Reconstruct(shareVec, &config) + require.Nil(t, err) + require.Equal(t, secret1, secret2) + require.Equal(t, secret2, secret3) + + // Need to reverse secret1 + secret1 = reverseBytes(secret1) + var secret1Bytes [32]byte + copy(secret1Bytes[:], secret1) + scalar1, err := new(curves.ScalarEd25519).SetBytesCanonical(secret1Bytes[:]) + require.NoError(t, err) + ed25519 := curves.ED25519() + pubFromSeed := ed25519.Point.Generator().Mul(scalar1) + + require.NoError(t, err) + require.Equal(t, pubFromSeed.ToAffineCompressed(), pub.Bytes()) +} + +func TestGenerateEd25519KeyInvalidConfig(t *testing.T) { + invalidConfig := ShareConfiguration{T: 1, N: 1} + _, _, _, err := GenerateSharedKey(&invalidConfig) + require.NotNil(t, err) + require.Error(t, err) + + invalidConfig = ShareConfiguration{T: 2, N: 1} + _, _, _, err = GenerateSharedKey(&invalidConfig) + require.NotNil(t, err) + require.Error(t, err) +} + +func TestVerifyVSSEd25519(t *testing.T) { + config := ShareConfiguration{T: 2, N: 3} + pubKey1, shares1, commitments1, err := GenerateSharedKey(&config) + require.NoError(t, err) + pubKey2, shares2, commitments2, err := GenerateSharedKey(&config) + require.NoError(t, err) + + require.Equal(t, pubKey1.Bytes(), commitments1[0].ToAffineCompressed()) + require.Equal(t, pubKey2.Bytes(), commitments2[0].ToAffineCompressed()) + + for _, s := range shares1 { + ok, err := s.VerifyVSS(commitments1, &config) + require.NoError(t, err) + require.True(t, ok) + ok, _ = s.VerifyVSS(commitments2, &config) + require.True(t, !ok) + } + + for _, s := range shares2 { + ok, err := s.VerifyVSS(commitments2, &config) + require.NoError(t, err) + require.True(t, ok) + ok, _ = s.VerifyVSS(commitments1, &config) + require.True(t, !ok) + } +} + +func TestCommitmentsFromBytes(t *testing.T) { + config := ShareConfiguration{T: 2, N: 3} + _, _, comms, err := GenerateSharedKey(&config) + require.NoError(t, err) + + recoveredComms, err := CommitmentsFromBytes(comms.CommitmentsToBytes()) + require.NoError(t, err) + require.Equal(t, len(comms), len(recoveredComms)) + for i := range comms { + require.True(t, comms[i].Equal(recoveredComms[i])) + } + _, err = CommitmentsFromBytes([][]byte{{0x01}}) + require.Error(t, err) +} + +func TestPublicKeyFromBytes(t *testing.T) { + _, err := PublicKeyFromBytes([]byte{0x01}) + require.EqualError(t, err, "invalid public key size: 1") +} + +func TestKeyShareFromBytes(t *testing.T) { + field := curves.NewField(curves.Ed25519Order()) + share := &v1.ShamirShare{ + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + } + shareBytes := share.Bytes() + recoveredShare := KeyShareFromBytes(shareBytes) + require.Equal(t, recoveredShare.ShamirShare, share) +} diff --git a/pkg/crypto/ted25519/ted25519/noncegen.go b/pkg/crypto/ted25519/ted25519/noncegen.go new file mode 100755 index 000000000..1462f6c2c --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/noncegen.go @@ -0,0 +1,123 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "crypto/rand" + "crypto/sha256" + "io" + + "golang.org/x/crypto/hkdf" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +// NonceShare represents a share of a generated nonce. +type NonceShare struct { + *KeyShare +} + +// NewNonceShare is a NonceShare construction +func NewNonceShare(identifier byte, secret []byte) *NonceShare { + return &NonceShare{NewKeyShare(identifier, secret)} +} + +// NonceShareFromBytes unmashals a NonceShare from its bytes representation +func NonceShareFromBytes(bytes []byte) *NonceShare { + return &NonceShare{KeyShareFromBytes(bytes)} +} + +func generateSharableNonce(s *KeyShare, p PublicKey, m Message) (PublicKey, []byte, error) { + // Create an HKDF reader that produces random bytes that we will use to create a nonce + hkdf, err := generateRandomHkdf(s, p, m) + if err != nil { + return nil, nil, err + } + + // Generate a random nonce that is within the field range so that we can share it. + // + // This diverges from how the standard implementation treats it because their scalar + // multiplication accepts values up to the curve order, but we must constrain it to be able to + // split it and aggregate. + // + // WARN: This operation is not constant time and we are dealing with a secret value + nonce, err := curves.NewField(curves.Ed25519Order()).RandomElement(hkdf) + if err != nil { + return nil, nil, err + } + + nonceBytes := nonce.Bytes() + reverseBytes := reverseBytes(nonceBytes) + var reverseInput [32]byte + copy(reverseInput[:], reverseBytes) + scalar, err := new(curves.ScalarEd25519).SetBytesCanonical(reverseInput[:]) + if err != nil { + return nil, nil, err + } + + // Generate the nonce pubkey by multiplying it by the base point. + noncePubkey := curves.ED25519().Point.Generator().Mul(scalar) + + return noncePubkey.ToAffineCompressed(), nonceBytes, nil +} + +// GenerateSharedNonce generates a random nonce, splits it, and returns the nonce pubkey, nonce shares, and +// VSS commitments. +func GenerateSharedNonce(config *ShareConfiguration, s *KeyShare, p PublicKey, m Message) ( + PublicKey, + []*NonceShare, + Commitments, + error, +) { + noncePubkey, nonce, err := generateSharableNonce(s, p, m) + if err != nil { + return nil, nil, nil, err + } + keyShares, vssCommitments, err := splitPrivateKey(config, nonce) + if err != nil { + return nil, nil, nil, err + } + + nonceShares := make([]*NonceShare, len(keyShares)) + for i, k := range keyShares { + nonceShares[i] = &NonceShare{k} + } + return noncePubkey, nonceShares, vssCommitments, nil +} + +// Add returns the sum of two NonceShares. +func (n NonceShare) Add(other *NonceShare) *NonceShare { + return &NonceShare{ + &KeyShare{ + // use Add method from the shamir.Share type to sum the shares + // WARN: This is not constant time and deals with secrets + n.ShamirShare.Add(other.ShamirShare), + }, + } +} + +// generateRandomHkdf returns an HMAC-based extract-and-expand Key Derivation Function (see RFC 5869). +func generateRandomHkdf(s *KeyShare, p PublicKey, m Message) (io.Reader, error) { + // We _must_ introduce randomness to the HKDF to make the output non-deterministic because deterministic nonces open + // up threshold schemes to potential nonce-reuse attacks. We continue to use the HKDF that takes in context about + // what is going to be signed as it adds some protection against bad local randomness. + randNonce := make([]byte, SeedSize) + if _, err := io.ReadFull(rand.Reader, randNonce); err != nil { + return nil, err + } + + var secret []byte + secret = append(secret, s.Bytes()...) + secret = append(secret, randNonce...) + + info := []byte("ted25519nonce") + // We use info for non-secret inputs to limit an attacker's ability to influence the key. + info = append(info, p.Bytes()...) + info = append(info, m...) + + return hkdf.New(sha256.New, secret, nil, info), nil +} diff --git a/pkg/crypto/ted25519/ted25519/noncegen_test.go b/pkg/crypto/ted25519/ted25519/noncegen_test.go new file mode 100755 index 000000000..c880a5567 --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/noncegen_test.go @@ -0,0 +1,106 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +func TestNonceShareFromBytes(t *testing.T) { + field := curves.NewField(curves.Ed25519Order()) + share := &v1.ShamirShare{ + Identifier: 2, + Value: field.NewElement(big.NewInt(3)), + } + shareBytes := share.Bytes() + recoveredShare := NonceShareFromBytes(shareBytes) + require.Equal(t, recoveredShare.ShamirShare, share) + require.Equal(t, share.Identifier, uint32(2)) +} + +func TestGenerateSharedNonce_congruence(t *testing.T) { + config := &ShareConfiguration{T: 2, N: 3} + message := []byte("fnord!") + pubKey, keyShares, _, err := GenerateSharedKey(config) + require.NoError(t, err) + nonceCommitment, nonceShares, _, err := GenerateSharedNonce(config, keyShares[0], pubKey, message) + require.NoError(t, err) + field := curves.NewField(curves.Ed25519Order()) + shamir, err := v1.NewShamir(config.T, config.N, field) + require.NoError(t, err) + nonce, err := shamir.Combine(toShamirShare(nonceShares)...) + require.NoError(t, err) + + nonce = reverseBytes(nonce) + var nonceBytes [32]byte + copy(nonceBytes[:], nonce) + nonceScalar, err := new(curves.ScalarEd25519).SetBytesCanonical(nonceBytes[:]) + require.NoError(t, err) + ed25519 := curves.ED25519() + recoveredCommitment := ed25519.Point.Generator().Mul(nonceScalar) + require.Equal(t, recoveredCommitment.ToAffineCompressed(), nonceCommitment.Bytes()) +} + +func TestGenerateNonce_non_determinism(t *testing.T) { + config := &ShareConfiguration{T: 2, N: 3} + message := []byte("fnord!") + pubKey, keyShares, _, err := GenerateSharedKey(config) + require.NoError(t, err) + + _, nonceShares1, _, err := GenerateSharedNonce(config, keyShares[0], pubKey, message) + require.NoError(t, err) + field := curves.NewField(curves.Ed25519Order()) + shamir, err := v1.NewShamir(config.T, config.N, field) + require.NoError(t, err) + nonce1, err := shamir.Combine(toShamirShare(nonceShares1)...) + require.NoError(t, err) + + _, nonceShares2, _, err := GenerateSharedNonce(config, keyShares[1], pubKey, message) + require.NoError(t, err) + nonce2, err := shamir.Combine(toShamirShare(nonceShares2)...) + require.NoError(t, err) + + _, nonceShares3, _, err := GenerateSharedNonce(config, keyShares[0], pubKey, message) + require.NoError(t, err) + nonce3, err := shamir.Combine(toShamirShare(nonceShares3)...) + require.NoError(t, err) + + require.NotEqual(t, nonce1, nonce2) + require.NotEqual(t, nonce1, nonce3) +} + +func TestNonceSharesAdd(t *testing.T) { + one := NewNonceShare(0, []byte{0x01}) + two := NewNonceShare(0, []byte{0x02}) + + // basic addition + sum := one.Add(two) + require.Equal(t, uint32(0), sum.Identifier) + require.Equal(t, []byte{0x03}, sum.Value.Bytes()) +} + +func TestNonceSharesAdd_errors(t *testing.T) { + one := NewNonceShare(0, []byte{0x01}) + two := NewNonceShare(1, []byte{0x02}) + require.PanicsWithValue(t, "identifiers must match for valid addition", func() { + one.Add(two) + }) +} + +func toShamirShare(nonceShares []*NonceShare) []*v1.ShamirShare { + shamirShares := make([]*v1.ShamirShare, len(nonceShares)) + for i, n := range nonceShares { + shamirShares[i] = n.ShamirShare + } + return shamirShares +} diff --git a/pkg/crypto/ted25519/ted25519/partialsig.go b/pkg/crypto/ted25519/ted25519/partialsig.go new file mode 100755 index 000000000..91b39d7d1 --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/partialsig.go @@ -0,0 +1,55 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import "strconv" + +type Message []byte + +func (m Message) String() string { + return string(m) +} + +const signatureLength = 64 + +type PartialSignature struct { + ShareIdentifier byte // x-coordinate of which signer produced signature + Sig []byte // 64-byte signature: R || s +} + +// NewPartialSignature creates a new PartialSignature +func NewPartialSignature(identifier byte, sig []byte) *PartialSignature { + if l := len(sig); l != signatureLength { + panic("ted25519: invalid partial signature length: " + strconv.Itoa(l)) + } + return &PartialSignature{ShareIdentifier: identifier, Sig: sig} +} + +// R returns the R component of the signature +func (sig *PartialSignature) R() []byte { + return sig.Sig[:32] +} + +// S returns the s component of the signature +func (sig *PartialSignature) S() []byte { + return sig.Sig[32:] +} + +func (sig *PartialSignature) Bytes() []byte { + return sig.Sig +} + +// TSign generates a signature that can later be aggregated with others to produce a signature valid +// under the provided public key and nonce pair. +func TSign(message Message, key *KeyShare, pub PublicKey, nonce *NonceShare, noncePub PublicKey) *PartialSignature { + sig := ThresholdSign( + reverseBytes(key.Value.Bytes()), pub, + message, + reverseBytes(nonce.Value.Bytes()), noncePub, + ) + return NewPartialSignature(byte(key.ShamirShare.Identifier), sig) +} diff --git a/pkg/crypto/ted25519/ted25519/partialsig_test.go b/pkg/crypto/ted25519/ted25519/partialsig_test.go new file mode 100755 index 000000000..c50c80ab3 --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/partialsig_test.go @@ -0,0 +1,56 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestPartialSignNormalSignature(t *testing.T) { + pub, priv, err := generateSharableKey() + require.NoError(t, err) + keyShare := NewKeyShare(0, priv) + r := big.NewInt(123456789).Bytes() + nonceShare := NewNonceShare(0, r) + + r = reverseBytes(r) + var rInput [32]byte + copy(rInput[:], r) + scalar, err := new(curves.ScalarEd25519).SetBytesCanonical(rInput[:]) + require.NoError(t, err) + noncePub := curves.ED25519().Point.Generator().Mul(scalar) + + message := []byte("test message") + wrongMessage := []byte("wrong message") + sig := TSign(message, keyShare, pub, nonceShare, noncePub.ToAffineCompressed()) + + ok, _ := Verify(pub, message, sig.Sig) + require.True(t, ok) + ok, _ = Verify(pub, wrongMessage, sig.Sig) + require.False(t, ok) +} + +func TestNewPartialSignature(t *testing.T) { + s := []byte("11111111111111111111111111111111") + r := []byte("22222222222222222222222222222222") + sigBytes := []byte("2222222222222222222222222222222211111111111111111111111111111111") + sig := NewPartialSignature(1, sigBytes) + + require.Equal(t, byte(1), sig.ShareIdentifier) + require.Equal(t, s, sig.S()) + require.Equal(t, r, sig.R()) + require.Equal(t, sigBytes, sig.Bytes()) + + require.PanicsWithValue(t, "ted25519: invalid partial signature length: 3", func() { + NewPartialSignature(1, []byte("sig")) + }) +} diff --git a/pkg/crypto/ted25519/ted25519/sigagg.go b/pkg/crypto/ted25519/ted25519/sigagg.go new file mode 100755 index 000000000..193f626ed --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/sigagg.go @@ -0,0 +1,62 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "bytes" + "fmt" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" + v1 "github.com/onsonr/sonr/pkg/crypto/sharing/v1" +) + +type Signature = []byte + +func Aggregate(sigs []*PartialSignature, config *ShareConfiguration) (Signature, error) { + if len(sigs) == 0 { + return nil, fmt.Errorf("ted25519: sigs must be non-empty") + } + + // Verify all nonce pubKeys are the same by checking they all match the first one. + noncePubkey := sigs[0].R() + for i := 1; i < len(sigs); i++ { + if !bytes.Equal(sigs[i].R(), noncePubkey) { + return nil, fmt.Errorf( + "ted25519: unexpected nonce pubkey. got: %x expected: %x", + sigs[i].R(), + noncePubkey, + ) + } + } + + // Convert signatures to a Shamir share representation so we can recombine them + sigShares := make([]*v1.ShamirShare, len(sigs)) + field := curves.NewField(curves.Ed25519Order()) + shamir, err := v1.NewShamir(config.T, config.N, field) + if err != nil { + return nil, err + } + + for i, sig := range sigs { + sigShares[i] = v1.NewShamirShare( + uint32(sig.ShareIdentifier), + reverseBytes(sig.S()), + field, + ) + } + + sigS, err := shamir.Combine(sigShares...) + if err != nil { + return nil, err + } + + sig := make([]byte, signatureLength) + copy(sig[:32], noncePubkey) // R is the same on all sigs + copy(sig[32:], reverseBytes(sigS)) // be-to-le + + return sig, nil +} diff --git a/pkg/crypto/ted25519/ted25519/sigagg_test.go b/pkg/crypto/ted25519/ted25519/sigagg_test.go new file mode 100755 index 000000000..2ef15d1de --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/sigagg_test.go @@ -0,0 +1,93 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package ted25519 + +import ( + "encoding/hex" + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSigAgg(t *testing.T) { + config := ShareConfiguration{T: 2, N: 3} + pub, secretShares, _, err := GenerateSharedKey(&config) + require.NoError(t, err) + + message := []byte("test message") + + // Each party generates a nonce and we combine them together into an aggregate one + noncePub1, nonceShares1, _, err := GenerateSharedNonce(&config, secretShares[0], pub, message) + require.NoError(t, err) + noncePub2, nonceShares2, _, err := GenerateSharedNonce(&config, secretShares[1], pub, message) + require.NoError(t, err) + noncePub3, nonceShares3, _, err := GenerateSharedNonce(&config, secretShares[2], pub, message) + require.NoError(t, err) + nonceShares := []*NonceShare{ + nonceShares1[0].Add(nonceShares2[0]).Add(nonceShares3[0]), + nonceShares1[1].Add(nonceShares2[1]).Add(nonceShares3[1]), + nonceShares1[2].Add(nonceShares2[2]).Add(nonceShares3[2]), + } + + noncePub := GeAdd(GeAdd(noncePub1, noncePub2), noncePub3) + + sig1 := TSign(message, secretShares[0], pub, nonceShares[0], noncePub) + sig2 := TSign(message, secretShares[1], pub, nonceShares[1], noncePub) + sig3 := TSign(message, secretShares[2], pub, nonceShares[2], noncePub) + + // Test signer 1&2 verification + sig, err := Aggregate([]*PartialSignature{sig1, sig2}, &config) + require.NoError(t, err) + assertSignatureVerifies(t, pub, message, sig) + + // Test signer 2&3 verification + sig, err = Aggregate([]*PartialSignature{sig2, sig3}, &config) + require.NoError(t, err) + assertSignatureVerifies(t, pub, message, sig) + + // Test signer 1&3 verification + sig, err = Aggregate([]*PartialSignature{sig1, sig3}, &config) + require.NoError(t, err) + assertSignatureVerifies(t, pub, message, sig) +} + +func TestSigAgg_validations(t *testing.T) { + config := ShareConfiguration{T: 2, N: 3} + _, err := Aggregate([]*PartialSignature{}, &config) + require.EqualError(t, err, "ted25519: sigs must be non-empty") + + sig1bytes, _ := hex.DecodeString( + "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155" + + "5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b", + ) + sig2bytes, _ := hex.DecodeString( + "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da" + + "085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00", + ) + sig1 := NewPartialSignature(1, sig1bytes) + sig2 := NewPartialSignature(2, sig2bytes) + + _, err = Aggregate([]*PartialSignature{sig1, sig2}, &config) + require.EqualError( + t, + err, + fmt.Sprintf("ted25519: unexpected nonce pubkey. got: %x expected: %x", sig2bytes[:32], sig1bytes[:32]), + ) +} + +func assertSignatureVerifies(t *testing.T, pub, message, sig []byte) { + ok, _ := Verify(pub, message, sig) + if !ok { + t.Errorf("valid signature rejected") + } + wrongMessage := []byte("wrong message") + ok, _ = Verify(pub, wrongMessage, sig) + if ok { + t.Errorf("signature of different message accepted") + } +} diff --git a/pkg/crypto/ted25519/ted25519/twobytwo_test.go b/pkg/crypto/ted25519/ted25519/twobytwo_test.go new file mode 100755 index 000000000..ec03774ca --- /dev/null +++ b/pkg/crypto/ted25519/ted25519/twobytwo_test.go @@ -0,0 +1,55 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +/* +* This is a simple example of a 2x2 signature scheme to prove out a simpler case than the threshold +* variants. We don't intend to use it and it is not modeled off of any specific known protocol. + */ +package ted25519 + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func AggregateSignatures(sig1, sig2 *PartialSignature) []byte { + field := curves.NewField(curves.Ed25519Order()) + sig1s := field.ElementFromBytes(reverseBytes(sig1.S())) + sig2s := field.ElementFromBytes(reverseBytes(sig2.S())) + sigS := sig1s.Add(sig2s) + + // Create signature as R || s. The R is the same so we use the same one + sig := make([]byte, SignatureSize) + copy(sig, sig1.R()) + copy(sig[32:], reverseBytes(sigS.Bytes())) + return sig +} + +func TestTwoByTwoSigning(t *testing.T) { + // generate shared pubkey + pub1, priv1, _ := generateSharableKey() + pub2, priv2, _ := generateSharableKey() + pub := GeAdd(pub1, pub2) + + // generate shared nonce + pubr1, r1, _ := generateSharableKey() + pubr2, r2, _ := generateSharableKey() + noncePub := GeAdd(pubr1, pubr2) + + // generate partial sigs + msg := []byte("test message") + sig1 := TSign(msg, NewKeyShare(0, priv1), pub, NewNonceShare(0, r1), noncePub) + sig2 := TSign(msg, NewKeyShare(0, priv2), pub, NewNonceShare(0, r2), noncePub) + + // add sigs (s+s) + sig := AggregateSignatures(sig1, sig2) + + ok, _ := Verify(pub, msg, sig) + require.True(t, ok, "signature failed verification") +} diff --git a/pkg/crypto/zkp/schnorr/schnorr.go b/pkg/crypto/zkp/schnorr/schnorr.go new file mode 100755 index 000000000..87c6cb9d4 --- /dev/null +++ b/pkg/crypto/zkp/schnorr/schnorr.go @@ -0,0 +1,140 @@ +// +// Copyright Coinbase, Inc. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Package schnorr implements a Schnorr proof, as described and used in Doerner, et al. https://eprint.iacr.org/2018/499.pdf +// see Functionalities 6. it also implements a "committed" version, as described in Functionality 7. +package schnorr + +import ( + "crypto/rand" + "crypto/subtle" + "fmt" + + "github.com/pkg/errors" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +type Commitment = []byte + +type Prover struct { + curve *curves.Curve + basePoint curves.Point + uniqueSessionId []byte +} + +// Proof contains the (c, s) schnorr proof. `Statement` is the curve point you're proving knowledge of discrete log of, +// with respect to the base point. +type Proof struct { + C curves.Scalar + S curves.Scalar + Statement curves.Point +} + +// NewProver generates a `Prover` object, ready to generate Schnorr proofs on any given point. +// We allow the option `basePoint == nil`, in which case `basePoint` is auto-assigned to be the "default" generator for the group. +func NewProver(curve *curves.Curve, basepoint curves.Point, uniqueSessionId []byte) *Prover { + if basepoint == nil { + basepoint = curve.NewGeneratorPoint() + } + return &Prover{ + curve: curve, + basePoint: basepoint, + uniqueSessionId: uniqueSessionId, + } +} + +// Prove generates and returns a Schnorr proof, given the scalar witness `x`. +// in the process, it will actually also construct the statement (just one curve mult in this case) +func (p *Prover) Prove(x curves.Scalar) (*Proof, error) { + // assumes that params, and pub are already populated. populates the fields c and s... + var err error + result := &Proof{} + result.Statement = p.basePoint.Mul(x) + k := p.curve.Scalar.Random(rand.Reader) + random := p.basePoint.Mul(k) + hash := sha3.New256() + if _, err = hash.Write(p.uniqueSessionId); err != nil { + return nil, errors.Wrap(err, "writing salt to hash in schnorr prove") + } + if _, err = hash.Write(p.basePoint.ToAffineCompressed()); err != nil { + return nil, errors.Wrap(err, "writing basePoint to hash in schnorr prove") + } + if _, err = hash.Write(result.Statement.ToAffineCompressed()); err != nil { + return nil, errors.Wrap(err, "writing statement to hash in schnorr prove") + } + if _, err = hash.Write(random.ToAffineCompressed()); err != nil { + return nil, errors.Wrap(err, "writing point K to hash in schnorr prove") + } + result.C, err = p.curve.Scalar.SetBytes(hash.Sum(nil)) + if err != nil { + return nil, errors.Wrap(err, "writing point K to hash in schnorr prove") + } + result.S = result.C.Mul(x).Add(k) + return result, nil +} + +// Verify verifies the `proof`, given the prover parameters `scalar` and `curve`. +// As for the prover, we allow `basePoint == nil`, in this case, it's auto-assigned to be the group's default generator. +func Verify(proof *Proof, curve *curves.Curve, basepoint curves.Point, uniqueSessionId []byte) error { + if basepoint == nil { + basepoint = curve.NewGeneratorPoint() + } + gs := basepoint.Mul(proof.S) + xc := proof.Statement.Mul(proof.C.Neg()) + random := gs.Add(xc) + hash := sha3.New256() + if _, err := hash.Write(uniqueSessionId); err != nil { + return errors.Wrap(err, "writing salt to hash in schnorr verify") + } + if _, err := hash.Write(basepoint.ToAffineCompressed()); err != nil { + return errors.Wrap(err, "writing basePoint to hash in schnorr verify") + } + if _, err := hash.Write(proof.Statement.ToAffineCompressed()); err != nil { + return errors.Wrap(err, "writing statement to hash in schnorr verify") + } + if _, err := hash.Write(random.ToAffineCompressed()); err != nil { + return errors.Wrap(err, "writing point K to hash in schnorr verify") + } + if subtle.ConstantTimeCompare(proof.C.Bytes(), hash.Sum(nil)) != 1 { + return fmt.Errorf("schnorr verification failed") + } + return nil +} + +// ProveCommit generates _and_ commits to a schnorr proof which is later revealed; see Functionality 7. +// returns the Proof and Commitment. +func (p *Prover) ProveCommit(x curves.Scalar) (*Proof, Commitment, error) { + proof, err := p.Prove(x) + if err != nil { + return nil, nil, err + } + hash := sha3.New256() + if _, err = hash.Write(proof.C.Bytes()); err != nil { + return nil, nil, err + } + if _, err = hash.Write(proof.S.Bytes()); err != nil { + return nil, nil, err + } + return proof, hash.Sum(nil), nil +} + +// DecommitVerify receives a `Proof` and a `Commitment`; it first checks that the proof actually opens the commitment; +// then it verifies the proof. returns and error if either on eof thse fail. +func DecommitVerify(proof *Proof, commitment Commitment, curve *curves.Curve, basepoint curves.Point, uniqueSessionId []byte) error { + hash := sha3.New256() + if _, err := hash.Write(proof.C.Bytes()); err != nil { + return err + } + if _, err := hash.Write(proof.S.Bytes()); err != nil { + return err + } + if subtle.ConstantTimeCompare(hash.Sum(nil), commitment) != 1 { + return fmt.Errorf("initial hash decommitment failed") + } + return Verify(proof, curve, basepoint, uniqueSessionId) +} diff --git a/pkg/crypto/zkp/schnorr/schnorr_test.go b/pkg/crypto/zkp/schnorr/schnorr_test.go new file mode 100755 index 000000000..8baa5811f --- /dev/null +++ b/pkg/crypto/zkp/schnorr/schnorr_test.go @@ -0,0 +1,37 @@ +package schnorr + +import ( + "crypto/rand" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" + + "github.com/onsonr/sonr/pkg/crypto/core/curves" +) + +func TestZKPOverMultipleCurves(t *testing.T) { + curveInstances := []*curves.Curve{ + curves.K256(), + curves.P256(), + // TODO: the code fails on the following curves. Investigate if this is expected. + // curves.PALLAS(), + // curves.BLS12377G1(), + // curves.BLS12377G2(), + // curves.BLS12381G1(), + // curves.BLS12381G2(), + // curves.ED25519(), + } + for i, curve := range curveInstances { + uniqueSessionId := sha3.New256().Sum([]byte("random seed")) + prover := NewProver(curve, nil, uniqueSessionId) + + secret := curve.Scalar.Random(rand.Reader) + proof, err := prover.Prove(secret) + require.NoError(t, err, fmt.Sprintf("failed in curve %d", i)) + + err = Verify(proof, curve, nil, uniqueSessionId) + require.NoError(t, err, fmt.Sprintf("failed in curve %d", i)) + } +} diff --git a/pkg/hway/README.md b/pkg/hway/README.md deleted file mode 100644 index 9a88828c3..000000000 --- a/pkg/hway/README.md +++ /dev/null @@ -1 +0,0 @@ -# Hway diff --git a/pkg/hway/handlers/jsonrpc.go b/pkg/hway/handlers/jsonrpc.go deleted file mode 100644 index 5ac8282f4..000000000 --- a/pkg/hway/handlers/jsonrpc.go +++ /dev/null @@ -1 +0,0 @@ -package handlers diff --git a/pkg/hway/handlers/querier.go b/pkg/hway/handlers/querier.go deleted file mode 100644 index 5ac8282f4..000000000 --- a/pkg/hway/handlers/querier.go +++ /dev/null @@ -1 +0,0 @@ -package handlers diff --git a/pkg/hway/handlers/sync.go b/pkg/hway/handlers/sync.go deleted file mode 100644 index 62fb99ec9..000000000 --- a/pkg/hway/handlers/sync.go +++ /dev/null @@ -1,13 +0,0 @@ -package handlers - -import "github.com/labstack/echo/v4" - -func FetchInitial(e echo.Context) error { - // Implement database schema endpoint - return nil -} - -func FetchCurrent(e echo.Context) error { - // Implement account entries endpoint - return nil -} diff --git a/pkg/hway/routes/routes.go b/pkg/hway/routes/routes.go deleted file mode 100644 index ea02888f0..000000000 --- a/pkg/hway/routes/routes.go +++ /dev/null @@ -1,16 +0,0 @@ -package routes - -import ( - "github.com/labstack/echo/v4" - - "github.com/onsonr/sonr/pkg/nebula/routes" -) - -func RegisterGatewayAPI(e *echo.Echo) { -} - -func RegisterGatewayViews(e *echo.Echo) { - e.GET("/", routes.HomeRoute) - e.GET("/login", routes.LoginModalRoute) - e.GET("/register", routes.RegisterModalRoute) -} diff --git a/pkg/hway/types/api.pb.go b/pkg/hway/types/api.pb.go deleted file mode 100644 index 32a95f644..000000000 --- a/pkg/hway/types/api.pb.go +++ /dev/null @@ -1,535 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc (unknown) -// source: hway/v1/api.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type GetJWKSRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *GetJWKSRequest) Reset() { - *x = GetJWKSRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_hway_v1_api_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetJWKSRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetJWKSRequest) ProtoMessage() {} - -func (x *GetJWKSRequest) ProtoReflect() protoreflect.Message { - mi := &file_hway_v1_api_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetJWKSRequest.ProtoReflect.Descriptor instead. -func (*GetJWKSRequest) Descriptor() ([]byte, []int) { - return file_hway_v1_api_proto_rawDescGZIP(), []int{0} -} - -type GetJWKSResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Jwks string `protobuf:"bytes,1,opt,name=jwks,proto3" json:"jwks,omitempty"` -} - -func (x *GetJWKSResponse) Reset() { - *x = GetJWKSResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_hway_v1_api_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetJWKSResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetJWKSResponse) ProtoMessage() {} - -func (x *GetJWKSResponse) ProtoReflect() protoreflect.Message { - mi := &file_hway_v1_api_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetJWKSResponse.ProtoReflect.Descriptor instead. -func (*GetJWKSResponse) Descriptor() ([]byte, []int) { - return file_hway_v1_api_proto_rawDescGZIP(), []int{1} -} - -func (x *GetJWKSResponse) GetJwks() string { - if x != nil { - return x.Jwks - } - return "" -} - -type GetTokenRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"` - Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` - Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` - Asset string `protobuf:"bytes,4,opt,name=asset,proto3" json:"asset,omitempty"` -} - -func (x *GetTokenRequest) Reset() { - *x = GetTokenRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_hway_v1_api_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetTokenRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetTokenRequest) ProtoMessage() {} - -func (x *GetTokenRequest) ProtoReflect() protoreflect.Message { - mi := &file_hway_v1_api_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetTokenRequest.ProtoReflect.Descriptor instead. -func (*GetTokenRequest) Descriptor() ([]byte, []int) { - return file_hway_v1_api_proto_rawDescGZIP(), []int{2} -} - -func (x *GetTokenRequest) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *GetTokenRequest) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *GetTokenRequest) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *GetTokenRequest) GetAsset() string { - if x != nil { - return x.Asset - } - return "" -} - -type GetTokenResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` -} - -func (x *GetTokenResponse) Reset() { - *x = GetTokenResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_hway_v1_api_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetTokenResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetTokenResponse) ProtoMessage() {} - -func (x *GetTokenResponse) ProtoReflect() protoreflect.Message { - mi := &file_hway_v1_api_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetTokenResponse.ProtoReflect.Descriptor instead. -func (*GetTokenResponse) Descriptor() ([]byte, []int) { - return file_hway_v1_api_proto_rawDescGZIP(), []int{3} -} - -func (x *GetTokenResponse) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -type GrantAuthorizationRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"` - Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` - Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` - Asset string `protobuf:"bytes,4,opt,name=asset,proto3" json:"asset,omitempty"` - Assertion string `protobuf:"bytes,5,opt,name=assertion,proto3" json:"assertion,omitempty"` -} - -func (x *GrantAuthorizationRequest) Reset() { - *x = GrantAuthorizationRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_hway_v1_api_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GrantAuthorizationRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GrantAuthorizationRequest) ProtoMessage() {} - -func (x *GrantAuthorizationRequest) ProtoReflect() protoreflect.Message { - mi := &file_hway_v1_api_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GrantAuthorizationRequest.ProtoReflect.Descriptor instead. -func (*GrantAuthorizationRequest) Descriptor() ([]byte, []int) { - return file_hway_v1_api_proto_rawDescGZIP(), []int{4} -} - -func (x *GrantAuthorizationRequest) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *GrantAuthorizationRequest) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *GrantAuthorizationRequest) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *GrantAuthorizationRequest) GetAsset() string { - if x != nil { - return x.Asset - } - return "" -} - -func (x *GrantAuthorizationRequest) GetAssertion() string { - if x != nil { - return x.Assertion - } - return "" -} - -type GrantAuthorizationResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` -} - -func (x *GrantAuthorizationResponse) Reset() { - *x = GrantAuthorizationResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_hway_v1_api_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GrantAuthorizationResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GrantAuthorizationResponse) ProtoMessage() {} - -func (x *GrantAuthorizationResponse) ProtoReflect() protoreflect.Message { - mi := &file_hway_v1_api_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GrantAuthorizationResponse.ProtoReflect.Descriptor instead. -func (*GrantAuthorizationResponse) Descriptor() ([]byte, []int) { - return file_hway_v1_api_proto_rawDescGZIP(), []int{5} -} - -func (x *GrantAuthorizationResponse) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -var File_hway_v1_api_proto protoreflect.FileDescriptor - -var file_hway_v1_api_proto_rawDesc = []byte{ - 0x0a, 0x11, 0x68, 0x77, 0x61, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x22, 0x10, 0x0a, 0x0e, - 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x25, - 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x77, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6a, 0x77, 0x6b, 0x73, 0x22, 0x6b, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x22, 0x28, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x93, 0x01, 0x0a, - 0x19, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, - 0x73, 0x73, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xe7, 0x01, 0x0a, 0x07, 0x48, 0x69, 0x67, 0x68, 0x77, - 0x61, 0x79, 0x12, 0x3c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x12, 0x17, 0x2e, - 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x3f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x18, 0x2e, 0x68, - 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x5d, 0x0a, 0x12, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x68, 0x77, - 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, - 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x68, - 0x77, 0x61, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_hway_v1_api_proto_rawDescOnce sync.Once - file_hway_v1_api_proto_rawDescData = file_hway_v1_api_proto_rawDesc -) - -func file_hway_v1_api_proto_rawDescGZIP() []byte { - file_hway_v1_api_proto_rawDescOnce.Do(func() { - file_hway_v1_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_hway_v1_api_proto_rawDescData) - }) - return file_hway_v1_api_proto_rawDescData -} - -var file_hway_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_hway_v1_api_proto_goTypes = []interface{}{ - (*GetJWKSRequest)(nil), // 0: hway.v1.GetJWKSRequest - (*GetJWKSResponse)(nil), // 1: hway.v1.GetJWKSResponse - (*GetTokenRequest)(nil), // 2: hway.v1.GetTokenRequest - (*GetTokenResponse)(nil), // 3: hway.v1.GetTokenResponse - (*GrantAuthorizationRequest)(nil), // 4: hway.v1.GrantAuthorizationRequest - (*GrantAuthorizationResponse)(nil), // 5: hway.v1.GrantAuthorizationResponse -} -var file_hway_v1_api_proto_depIdxs = []int32{ - 0, // 0: hway.v1.Highway.GetJWKS:input_type -> hway.v1.GetJWKSRequest - 2, // 1: hway.v1.Highway.GetToken:input_type -> hway.v1.GetTokenRequest - 4, // 2: hway.v1.Highway.GrantAuthorization:input_type -> hway.v1.GrantAuthorizationRequest - 1, // 3: hway.v1.Highway.GetJWKS:output_type -> hway.v1.GetJWKSResponse - 3, // 4: hway.v1.Highway.GetToken:output_type -> hway.v1.GetTokenResponse - 5, // 5: hway.v1.Highway.GrantAuthorization:output_type -> hway.v1.GrantAuthorizationResponse - 3, // [3:6] is the sub-list for method output_type - 0, // [0:3] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_hway_v1_api_proto_init() } -func file_hway_v1_api_proto_init() { - if File_hway_v1_api_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_hway_v1_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetJWKSRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hway_v1_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetJWKSResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hway_v1_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTokenRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hway_v1_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetTokenResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hway_v1_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GrantAuthorizationRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hway_v1_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GrantAuthorizationResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_hway_v1_api_proto_rawDesc, - NumEnums: 0, - NumMessages: 6, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_hway_v1_api_proto_goTypes, - DependencyIndexes: file_hway_v1_api_proto_depIdxs, - MessageInfos: file_hway_v1_api_proto_msgTypes, - }.Build() - File_hway_v1_api_proto = out.File - file_hway_v1_api_proto_rawDesc = nil - file_hway_v1_api_proto_goTypes = nil - file_hway_v1_api_proto_depIdxs = nil -} diff --git a/pkg/hway/types/client.pb.go b/pkg/hway/types/client.pb.go deleted file mode 100644 index 6fc6c8616..000000000 --- a/pkg/hway/types/client.pb.go +++ /dev/null @@ -1,63 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc (unknown) -// source: hway/v1/client.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -var File_hway_v1_client_proto protoreflect.FileDescriptor - -var file_hway_v1_client_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x68, 0x77, 0x61, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x68, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x42, - 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, - 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x68, 0x77, - 0x61, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, -} - -var file_hway_v1_client_proto_goTypes = []interface{}{} -var file_hway_v1_client_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_hway_v1_client_proto_init() } -func file_hway_v1_client_proto_init() { - if File_hway_v1_client_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_hway_v1_client_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_hway_v1_client_proto_goTypes, - DependencyIndexes: file_hway_v1_client_proto_depIdxs, - }.Build() - File_hway_v1_client_proto = out.File - file_hway_v1_client_proto_rawDesc = nil - file_hway_v1_client_proto_goTypes = nil - file_hway_v1_client_proto_depIdxs = nil -} diff --git a/pkg/motr/README.md b/pkg/motr/README.md deleted file mode 100644 index cab2301c5..000000000 --- a/pkg/motr/README.md +++ /dev/null @@ -1 +0,0 @@ -# Motr diff --git a/pkg/motr/config/init.pkl.go b/pkg/motr/config/init.pkl.go deleted file mode 100644 index 5b5b2afa0..000000000 --- a/pkg/motr/config/init.pkl.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated from Pkl module `dwn`. DO NOT EDIT. -package config - -import "github.com/apple/pkl-go/pkl" - -func init() { - pkl.RegisterMapping("dwn", Dwn{}) - pkl.RegisterMapping("dwn#Config", Config{}) - pkl.RegisterMapping("dwn#Schema", Schema{}) -} diff --git a/pkg/motr/embed.go b/pkg/motr/embed.go deleted file mode 100644 index c4e6c99d2..000000000 --- a/pkg/motr/embed.go +++ /dev/null @@ -1,38 +0,0 @@ -package motr - -import ( - _ "embed" - "encoding/json" - - "github.com/ipfs/boxo/files" - - "github.com/onsonr/sonr/pkg/motr/config" - "github.com/onsonr/sonr/pkg/motr/static" -) - -const ( - FileNameConfigJSON = "dwn.pkl" - FileNameIndexHTML = "index.html" - FileNameWorkerJS = "sw.js" -) - -//go:embed static/sw.js -var swJSData []byte - -// NewVaultDirectory creates a new directory with the default files -func NewVaultDirectory(cnfg *config.Config) (files.Node, error) { - idxFile, err := static.BuildVaultFile(cnfg) - if err != nil { - return nil, err - } - cnfgBz, err := json.Marshal(cnfg) - if err != nil { - return nil, err - } - fileMap := map[string]files.Node{ - FileNameConfigJSON: files.NewBytesFile(cnfgBz), - FileNameIndexHTML: idxFile, - FileNameWorkerJS: files.NewBytesFile(swJSData), - } - return files.NewMapDirectory(fileMap), nil -} diff --git a/pkg/motr/routes/routes.go b/pkg/motr/routes/routes.go deleted file mode 100644 index 71ee2f696..000000000 --- a/pkg/motr/routes/routes.go +++ /dev/null @@ -1,26 +0,0 @@ -package routes - -import ( - "github.com/labstack/echo/v4" - - "github.com/onsonr/sonr/pkg/motr/handlers" -) - -// RegisterWebNodeAPI registers the Decentralized Web Node API routes. -func RegisterWebNodeAPI(e *echo.Echo) { - g1 := e.Group("api") - g1.GET("/register/:subject/start", handlers.RegisterSubjectStart) - g1.POST("/register/:subject/check", handlers.RegisterSubjectCheck) - g1.POST("/register/:subject/finish", handlers.RegisterSubjectFinish) - - g1.GET("/login/:subject/start", handlers.LoginSubjectStart) - g1.POST("/login/:subject/check", handlers.LoginSubjectCheck) - g1.POST("/login/:subject/finish", handlers.LoginSubjectFinish) - - g1.GET("/:origin/grant/jwks", handlers.GetJWKS) - g1.GET("/:origin/grant/token", handlers.GetToken) - g1.POST("/:origin/grant/:subject", handlers.GrantAuthorization) -} - -func RegisterWebNodeViews(e *echo.Echo) { -} diff --git a/pkg/motr/static/index.go b/pkg/motr/static/index.go deleted file mode 100644 index 079d92da6..000000000 --- a/pkg/motr/static/index.go +++ /dev/null @@ -1,22 +0,0 @@ -package static - -import ( - "bytes" - "context" - - "github.com/ipfs/boxo/files" - - dwn "github.com/onsonr/sonr/pkg/motr/config" - "github.com/onsonr/sonr/pkg/nebula/views" -) - -// BuildVaultFile builds the index.html file for the vault -func BuildVaultFile(cnfg *dwn.Config) (files.Node, error) { - w := bytes.NewBuffer(nil) - err := views.VaultIndexFile().Render(context.Background(), w) - if err != nil { - return nil, err - } - indexData := w.Bytes() - return files.NewBytesFile(indexData), nil -} diff --git a/pkg/motr/static/sw.js b/pkg/motr/static/sw.js deleted file mode 100644 index 2a0b46c6c..000000000 --- a/pkg/motr/static/sw.js +++ /dev/null @@ -1,22 +0,0 @@ -importScripts( - "https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js", - "https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v1.1.0/sw.js", -); - -registerWasmHTTPListener("/app.wasm"); - -// Skip installed stage and jump to activating stage -self.addEventListener("install", (event) => { - event.waitUntil(skipWaiting()); -}); - -// Start controlling clients as soon as the SW is activated -self.addEventListener("activate", (event) => { - event.waitUntil(clients.claim()); -}); - -self.addEventListener("canmakepayment", function (e) { - e.respondWith(new Promise(function (resolve, reject) { - resolve(true); - })); -}); diff --git a/pkg/motr/types/api.pb.go b/pkg/motr/types/api.pb.go deleted file mode 100644 index fa349d9ca..000000000 --- a/pkg/motr/types/api.pb.go +++ /dev/null @@ -1,342 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc (unknown) -// source: motr/v1/api.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type PinRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Cid string `protobuf:"bytes,1,opt,name=cid,proto3" json:"cid,omitempty"` -} - -func (x *PinRequest) Reset() { - *x = PinRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_motr_v1_api_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PinRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PinRequest) ProtoMessage() {} - -func (x *PinRequest) ProtoReflect() protoreflect.Message { - mi := &file_motr_v1_api_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PinRequest.ProtoReflect.Descriptor instead. -func (*PinRequest) Descriptor() ([]byte, []int) { - return file_motr_v1_api_proto_rawDescGZIP(), []int{0} -} - -func (x *PinRequest) GetCid() string { - if x != nil { - return x.Cid - } - return "" -} - -type PinResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` -} - -func (x *PinResponse) Reset() { - *x = PinResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_motr_v1_api_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PinResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PinResponse) ProtoMessage() {} - -func (x *PinResponse) ProtoReflect() protoreflect.Message { - mi := &file_motr_v1_api_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PinResponse.ProtoReflect.Descriptor instead. -func (*PinResponse) Descriptor() ([]byte, []int) { - return file_motr_v1_api_proto_rawDescGZIP(), []int{1} -} - -func (x *PinResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -type UnpinRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Cid string `protobuf:"bytes,1,opt,name=cid,proto3" json:"cid,omitempty"` -} - -func (x *UnpinRequest) Reset() { - *x = UnpinRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_motr_v1_api_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UnpinRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnpinRequest) ProtoMessage() {} - -func (x *UnpinRequest) ProtoReflect() protoreflect.Message { - mi := &file_motr_v1_api_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UnpinRequest.ProtoReflect.Descriptor instead. -func (*UnpinRequest) Descriptor() ([]byte, []int) { - return file_motr_v1_api_proto_rawDescGZIP(), []int{2} -} - -func (x *UnpinRequest) GetCid() string { - if x != nil { - return x.Cid - } - return "" -} - -type UnpinResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` -} - -func (x *UnpinResponse) Reset() { - *x = UnpinResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_motr_v1_api_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UnpinResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnpinResponse) ProtoMessage() {} - -func (x *UnpinResponse) ProtoReflect() protoreflect.Message { - mi := &file_motr_v1_api_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UnpinResponse.ProtoReflect.Descriptor instead. -func (*UnpinResponse) Descriptor() ([]byte, []int) { - return file_motr_v1_api_proto_rawDescGZIP(), []int{3} -} - -func (x *UnpinResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -var File_motr_v1_api_proto protoreflect.FileDescriptor - -var file_motr_v1_api_proto_rawDesc = []byte{ - 0x0a, 0x11, 0x6d, 0x6f, 0x74, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, 0x22, 0x1e, 0x0a, 0x0a, - 0x50, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x22, 0x27, 0x0a, 0x0b, - 0x50, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x20, 0x0a, 0x0c, 0x55, 0x6e, 0x70, 0x69, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x22, 0x29, 0x0a, 0x0d, 0x55, 0x6e, 0x70, 0x69, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x32, 0x70, 0x0a, 0x04, 0x4d, 0x6f, 0x74, 0x72, 0x12, 0x30, 0x0a, 0x03, 0x50, 0x69, - 0x6e, 0x12, 0x13, 0x2e, 0x6d, 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6d, 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, - 0x55, 0x6e, 0x70, 0x69, 0x6e, 0x12, 0x15, 0x2e, 0x6d, 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x6e, 0x70, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d, - 0x6f, 0x74, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x70, - 0x6b, 0x67, 0x2f, 0x6d, 0x6f, 0x74, 0x72, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_motr_v1_api_proto_rawDescOnce sync.Once - file_motr_v1_api_proto_rawDescData = file_motr_v1_api_proto_rawDesc -) - -func file_motr_v1_api_proto_rawDescGZIP() []byte { - file_motr_v1_api_proto_rawDescOnce.Do(func() { - file_motr_v1_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_motr_v1_api_proto_rawDescData) - }) - return file_motr_v1_api_proto_rawDescData -} - -var file_motr_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_motr_v1_api_proto_goTypes = []interface{}{ - (*PinRequest)(nil), // 0: motr.v1.PinRequest - (*PinResponse)(nil), // 1: motr.v1.PinResponse - (*UnpinRequest)(nil), // 2: motr.v1.UnpinRequest - (*UnpinResponse)(nil), // 3: motr.v1.UnpinResponse -} -var file_motr_v1_api_proto_depIdxs = []int32{ - 0, // 0: motr.v1.Motr.Pin:input_type -> motr.v1.PinRequest - 2, // 1: motr.v1.Motr.Unpin:input_type -> motr.v1.UnpinRequest - 1, // 2: motr.v1.Motr.Pin:output_type -> motr.v1.PinResponse - 3, // 3: motr.v1.Motr.Unpin:output_type -> motr.v1.UnpinResponse - 2, // [2:4] is the sub-list for method output_type - 0, // [0:2] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_motr_v1_api_proto_init() } -func file_motr_v1_api_proto_init() { - if File_motr_v1_api_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_motr_v1_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PinRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_motr_v1_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PinResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_motr_v1_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnpinRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_motr_v1_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnpinResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_motr_v1_api_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_motr_v1_api_proto_goTypes, - DependencyIndexes: file_motr_v1_api_proto_depIdxs, - MessageInfos: file_motr_v1_api_proto_msgTypes, - }.Build() - File_motr_v1_api_proto = out.File - file_motr_v1_api_proto_rawDesc = nil - file_motr_v1_api_proto_goTypes = nil - file_motr_v1_api_proto_depIdxs = nil -} diff --git a/pkg/motr/types/orm/init.pkl.go b/pkg/motr/types/orm/init.pkl.go deleted file mode 100644 index 8e343a63a..000000000 --- a/pkg/motr/types/orm/init.pkl.go +++ /dev/null @@ -1,17 +0,0 @@ -// Code generated from Pkl module `orm`. DO NOT EDIT. -package orm - -import "github.com/apple/pkl-go/pkl" - -func init() { - pkl.RegisterMapping("orm", Orm{}) - pkl.RegisterMapping("orm#Account", Account{}) - pkl.RegisterMapping("orm#Asset", Asset{}) - pkl.RegisterMapping("orm#Chain", Chain{}) - pkl.RegisterMapping("orm#Credential", Credential{}) - pkl.RegisterMapping("orm#DID", DID{}) - pkl.RegisterMapping("orm#JWK", JWK{}) - pkl.RegisterMapping("orm#Grant", Grant{}) - pkl.RegisterMapping("orm#Keyshare", Keyshare{}) - pkl.RegisterMapping("orm#Profile", Profile{}) -} diff --git a/pkg/motr/types/orm/webauthn.go b/pkg/motr/types/orm/webauthn.go deleted file mode 100644 index a6352a639..000000000 --- a/pkg/motr/types/orm/webauthn.go +++ /dev/null @@ -1,54 +0,0 @@ -package orm - -import ( - "github.com/go-webauthn/webauthn/protocol" - "github.com/go-webauthn/webauthn/protocol/webauthncose" -) - -func NewCredentialCreationOptions(subject, address string, challenge protocol.URLEncodedBase64) *protocol.PublicKeyCredentialCreationOptions { - return &protocol.PublicKeyCredentialCreationOptions{ - Challenge: challenge, - User: protocol.UserEntity{ - DisplayName: subject, - ID: address, - }, - Attestation: defaultAttestation(), - AuthenticatorSelection: defaultAuthenticatorSelection(), - Parameters: defaultCredentialParameters(), - } -} - -func buildUserEntity(userID string) protocol.UserEntity { - return protocol.UserEntity{ - ID: userID, - } -} - -func defaultAttestation() protocol.ConveyancePreference { - return protocol.PreferDirectAttestation -} - -func defaultAuthenticatorSelection() protocol.AuthenticatorSelection { - return protocol.AuthenticatorSelection{ - AuthenticatorAttachment: "platform", - ResidentKey: protocol.ResidentKeyRequirementPreferred, - UserVerification: "preferred", - } -} - -func defaultCredentialParameters() []protocol.CredentialParameter { - return []protocol.CredentialParameter{ - { - Type: "public-key", - Algorithm: webauthncose.AlgES256, - }, - { - Type: "public-key", - Algorithm: webauthncose.AlgES256K, - }, - { - Type: "public-key", - Algorithm: webauthncose.AlgEdDSA, - }, - } -} diff --git a/pkg/nebula/README.md b/pkg/nebula/README.md deleted file mode 100644 index 4ac359740..000000000 --- a/pkg/nebula/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Nebula - -A Templ component library for the Sonr DWN (Decentralized Web Node) client. - -## Overview - -### 3rd Party - -- [htmx](https://htmx.org/) -- [tailwindcss](https://tailwindcss.com/) -- [templ](https://templ.dev/) -- [alpinejs](https://alpinejs.dev/) - -### Components - -- Navbar -- Footer -- Login -- Register -- Profile -- Authorize - -## Usage - -```go -package main - -import ( - "github.com/onsonr/sonr/pkg/nebula" - "github.com/onsonr/sonr/pkg/nebula/components" - "github.com/onsonr/sonr/pkg/nebula/pages" -) - -func main() { - e := echo.New() - e.GET("/", pages.Home) - e.GET("/login", pages.Login) - e.GET("/register", pages.Register) - e.GET("/profile", pages.Profile) - e.GET("/authorize", pages.Authorize) - e.GET("/components", components.Home) - e.Logger.Fatal(e.Start(":1323")) -} -``` - -## License - -[MIT](LICENSE) diff --git a/pkg/nebula/assets/css/styles.css b/pkg/nebula/assets/css/styles.css deleted file mode 100644 index 03ffcb50a..000000000 --- a/pkg/nebula/assets/css/styles.css +++ /dev/null @@ -1,4366 +0,0 @@ -@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500&family=Inter+Tight:ital,wght@0,500;0,600;0,700;1,700&display=fallback"); - -/* src/css/styles.css */ - -*, ::before, ::after{ - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; - --motion-origin-scale-x: 1; - --motion-origin-scale-y: 1; - --motion-origin-translate-x: 0; - --motion-origin-translate-y: 0; - --motion-origin-rotate: 0; - --motion-origin-blur: 0; - --motion-origin-grayscale: 0; - --motion-origin-opacity: 1; - --motion-origin-background-color: ; - --motion-origin-text-color: ; - --motion-end-scale-x: 1; - --motion-end-scale-y: 1; - --motion-end-translate-x: 0; - --motion-end-translate-y: 0; - --motion-end-rotate: 0; - --motion-end-blur: 0; - --motion-end-grayscale: 0; - --motion-end-opacity: 1; - --motion-end-background-color: ; - --motion-end-text-color: ; - --motion-duration: 750ms; - --motion-timing: var(--motion-default-timing); - --motion-perceptual-duration-multiplier: 1; - --motion-delay: 0ms; - --motion-scale-duration: var(--motion-duration); - --motion-scale-timing: var(--motion-timing); - --motion-scale-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-scale-delay: var(--motion-delay); - --motion-translate-duration: var(--motion-duration); - --motion-translate-timing: var(--motion-timing); - --motion-translate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-translate-delay: var(--motion-delay); - --motion-rotate-duration: var(--motion-duration); - --motion-rotate-timing: var(--motion-timing); - --motion-rotate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-rotate-delay: var(--motion-delay); - --motion-filter-duration: var(--motion-duration); - --motion-filter-timing: var(--motion-timing); - --motion-filter-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-filter-delay: var(--motion-delay); - --motion-opacity-duration: var(--motion-duration); - --motion-opacity-timing: var(--motion-timing); - --motion-opacity-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-opacity-delay: var(--motion-delay); - --motion-background-color-duration: var(--motion-duration); - --motion-background-color-timing: var(--motion-timing); - --motion-background-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-background-color-delay: var(--motion-delay); - --motion-text-color-duration: var(--motion-duration); - --motion-text-color-timing: var(--motion-timing); - --motion-text-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-text-color-delay: var(--motion-delay); - --motion-scale-in-animation: none; - --motion-translate-in-animation: none; - --motion-rotate-in-animation: none; - --motion-filter-in-animation: none; - --motion-opacity-in-animation: none; - --motion-background-color-in-animation: none; - --motion-text-color-in-animation: none; - --motion-scale-out-animation: none; - --motion-translate-out-animation: none; - --motion-rotate-out-animation: none; - --motion-filter-out-animation: none; - --motion-opacity-out-animation: none; - --motion-background-color-out-animation: none; - --motion-text-color-out-animation: none; - --motion-all-enter-animations: var(--motion-scale-in-animation), var(--motion-translate-in-animation), var(--motion-rotate-in-animation), var(--motion-filter-in-animation), var(--motion-opacity-in-animation), var(--motion-background-color-in-animation), var(--motion-text-color-in-animation); - --motion-all-exit-animations: var(--motion-scale-out-animation), var(--motion-translate-out-animation), var(--motion-rotate-out-animation), var(--motion-filter-out-animation), var(--motion-opacity-out-animation), var(--motion-background-color-out-animation), var(--motion-text-color-out-animation); -} - -::backdrop{ - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; - --motion-origin-scale-x: 1; - --motion-origin-scale-y: 1; - --motion-origin-translate-x: 0; - --motion-origin-translate-y: 0; - --motion-origin-rotate: 0; - --motion-origin-blur: 0; - --motion-origin-grayscale: 0; - --motion-origin-opacity: 1; - --motion-origin-background-color: ; - --motion-origin-text-color: ; - --motion-end-scale-x: 1; - --motion-end-scale-y: 1; - --motion-end-translate-x: 0; - --motion-end-translate-y: 0; - --motion-end-rotate: 0; - --motion-end-blur: 0; - --motion-end-grayscale: 0; - --motion-end-opacity: 1; - --motion-end-background-color: ; - --motion-end-text-color: ; - --motion-duration: 750ms; - --motion-timing: var(--motion-default-timing); - --motion-perceptual-duration-multiplier: 1; - --motion-delay: 0ms; - --motion-scale-duration: var(--motion-duration); - --motion-scale-timing: var(--motion-timing); - --motion-scale-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-scale-delay: var(--motion-delay); - --motion-translate-duration: var(--motion-duration); - --motion-translate-timing: var(--motion-timing); - --motion-translate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-translate-delay: var(--motion-delay); - --motion-rotate-duration: var(--motion-duration); - --motion-rotate-timing: var(--motion-timing); - --motion-rotate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-rotate-delay: var(--motion-delay); - --motion-filter-duration: var(--motion-duration); - --motion-filter-timing: var(--motion-timing); - --motion-filter-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-filter-delay: var(--motion-delay); - --motion-opacity-duration: var(--motion-duration); - --motion-opacity-timing: var(--motion-timing); - --motion-opacity-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-opacity-delay: var(--motion-delay); - --motion-background-color-duration: var(--motion-duration); - --motion-background-color-timing: var(--motion-timing); - --motion-background-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-background-color-delay: var(--motion-delay); - --motion-text-color-duration: var(--motion-duration); - --motion-text-color-timing: var(--motion-timing); - --motion-text-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-text-color-delay: var(--motion-delay); - --motion-scale-in-animation: none; - --motion-translate-in-animation: none; - --motion-rotate-in-animation: none; - --motion-filter-in-animation: none; - --motion-opacity-in-animation: none; - --motion-background-color-in-animation: none; - --motion-text-color-in-animation: none; - --motion-scale-out-animation: none; - --motion-translate-out-animation: none; - --motion-rotate-out-animation: none; - --motion-filter-out-animation: none; - --motion-opacity-out-animation: none; - --motion-background-color-out-animation: none; - --motion-text-color-out-animation: none; - --motion-all-enter-animations: var(--motion-scale-in-animation), var(--motion-translate-in-animation), var(--motion-rotate-in-animation), var(--motion-filter-in-animation), var(--motion-opacity-in-animation), var(--motion-background-color-in-animation), var(--motion-text-color-in-animation); - --motion-all-exit-animations: var(--motion-scale-out-animation), var(--motion-translate-out-animation), var(--motion-rotate-out-animation), var(--motion-filter-out-animation), var(--motion-opacity-out-animation), var(--motion-background-color-out-animation), var(--motion-text-color-out-animation); -} - -/* ! tailwindcss v3.4.13 | MIT License | https://tailwindcss.com */ - -/* -1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) -2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) -*/ - -*, -::before, -::after { - box-sizing: border-box; - /* 1 */ - border-width: 0; - /* 2 */ - border-style: solid; - /* 2 */ - border-color: #e5e7eb; - /* 2 */ -} - -::before, -::after { - --tw-content: ''; -} - -/* -1. Use a consistent sensible line-height in all browsers. -2. Prevent adjustments of font size after orientation changes in iOS. -3. Use a more readable tab size. -4. Use the user's configured `sans` font-family by default. -5. Use the user's configured `sans` font-feature-settings by default. -6. Use the user's configured `sans` font-variation-settings by default. -7. Disable tap highlights on iOS -*/ - -html, -:host { - line-height: 1.5; - /* 1 */ - -webkit-text-size-adjust: 100%; - /* 2 */ - -moz-tab-size: 4; - /* 3 */ - -o-tab-size: 4; - tab-size: 4; - /* 3 */ - font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - /* 4 */ - font-feature-settings: normal; - /* 5 */ - font-variation-settings: normal; - /* 6 */ - -webkit-tap-highlight-color: transparent; - /* 7 */ -} - -/* -1. Remove the margin in all browsers. -2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. -*/ - -body { - margin: 0; - /* 1 */ - line-height: inherit; - /* 2 */ -} - -/* -1. Add the correct height in Firefox. -2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) -3. Ensure horizontal rules are visible by default. -*/ - -hr { - height: 0; - /* 1 */ - color: inherit; - /* 2 */ - border-top-width: 1px; - /* 3 */ -} - -/* -Add the correct text decoration in Chrome, Edge, and Safari. -*/ - -abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; -} - -/* -Remove the default font size and weight for headings. -*/ - -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: inherit; - font-weight: inherit; -} - -/* -Reset links to optimize for opt-in styling instead of opt-out. -*/ - -a { - color: inherit; - text-decoration: inherit; -} - -/* -Add the correct font weight in Edge and Safari. -*/ - -b, -strong { - font-weight: bolder; -} - -/* -1. Use the user's configured `mono` font-family by default. -2. Use the user's configured `mono` font-feature-settings by default. -3. Use the user's configured `mono` font-variation-settings by default. -4. Correct the odd `em` font sizing in all browsers. -*/ - -code, -kbd, -samp, -pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - /* 1 */ - font-feature-settings: normal; - /* 2 */ - font-variation-settings: normal; - /* 3 */ - font-size: 1em; - /* 4 */ -} - -/* -Add the correct font size in all browsers. -*/ - -small { - font-size: 80%; -} - -/* -Prevent `sub` and `sup` elements from affecting the line height in all browsers. -*/ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -/* -1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) -2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) -3. Remove gaps between table borders by default. -*/ - -table { - text-indent: 0; - /* 1 */ - border-color: inherit; - /* 2 */ - border-collapse: collapse; - /* 3 */ -} - -/* -1. Change the font styles in all browsers. -2. Remove the margin in Firefox and Safari. -3. Remove default padding in all browsers. -*/ - -button, -input, -optgroup, -select, -textarea { - font-family: inherit; - /* 1 */ - font-feature-settings: inherit; - /* 1 */ - font-variation-settings: inherit; - /* 1 */ - font-size: 100%; - /* 1 */ - font-weight: inherit; - /* 1 */ - line-height: inherit; - /* 1 */ - letter-spacing: inherit; - /* 1 */ - color: inherit; - /* 1 */ - margin: 0; - /* 2 */ - padding: 0; - /* 3 */ -} - -/* -Remove the inheritance of text transform in Edge and Firefox. -*/ - -button, -select { - text-transform: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Remove default button styles. -*/ - -button, -input:where([type='button']), -input:where([type='reset']), -input:where([type='submit']) { - -webkit-appearance: button; - /* 1 */ - background-color: transparent; - /* 2 */ - background-image: none; - /* 2 */ -} - -/* -Use the modern Firefox focus style for all focusable elements. -*/ - -:-moz-focusring { - outline: auto; -} - -/* -Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) -*/ - -:-moz-ui-invalid { - box-shadow: none; -} - -/* -Add the correct vertical alignment in Chrome and Firefox. -*/ - -progress { - vertical-align: baseline; -} - -/* -Correct the cursor style of increment and decrement buttons in Safari. -*/ - -::-webkit-inner-spin-button, -::-webkit-outer-spin-button { - height: auto; -} - -/* -1. Correct the odd appearance in Chrome and Safari. -2. Correct the outline style in Safari. -*/ - -[type='search'] { - -webkit-appearance: textfield; - /* 1 */ - outline-offset: -2px; - /* 2 */ -} - -/* -Remove the inner padding in Chrome and Safari on macOS. -*/ - -::-webkit-search-decoration { - -webkit-appearance: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Change font properties to `inherit` in Safari. -*/ - -::-webkit-file-upload-button { - -webkit-appearance: button; - /* 1 */ - font: inherit; - /* 2 */ -} - -/* -Add the correct display in Chrome and Safari. -*/ - -summary { - display: list-item; -} - -/* -Removes the default spacing and border for appropriate elements. -*/ - -blockquote, -dl, -dd, -h1, -h2, -h3, -h4, -h5, -h6, -hr, -figure, -p, -pre { - margin: 0; -} - -fieldset { - margin: 0; - padding: 0; -} - -legend { - padding: 0; -} - -ol, -ul, -menu { - list-style: none; - margin: 0; - padding: 0; -} - -/* -Reset default styling for dialogs. -*/ - -dialog { - padding: 0; -} - -/* -Prevent resizing textareas horizontally by default. -*/ - -textarea { - resize: vertical; -} - -/* -1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) -2. Set the default placeholder color to the user's configured gray 400 color. -*/ - -input::-moz-placeholder, textarea::-moz-placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -input::placeholder, -textarea::placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -/* -Set the default cursor for buttons. -*/ - -button, -[role="button"] { - cursor: pointer; -} - -/* -Make sure disabled buttons don't get the pointer cursor. -*/ - -:disabled { - cursor: default; -} - -/* -1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) -2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) - This can trigger a poorly considered lint error in some tools but is included by design. -*/ - -img, -svg, -video, -canvas, -audio, -iframe, -embed, -object { - display: block; - /* 1 */ - vertical-align: middle; - /* 2 */ -} - -/* -Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) -*/ - -img, -video { - max-width: 100%; - height: auto; -} - -/* Make elements with the HTML hidden attribute stay hidden by default */ - -[hidden] { - display: none; -} - -[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select{ - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - border-radius: 0px; - padding-top: 0.5rem; - padding-right: 0.75rem; - padding-bottom: 0.5rem; - padding-left: 0.75rem; - font-size: 1rem; - line-height: 1.5rem; - --tw-shadow: 0 0 #0000; -} - -[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus{ - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - border-color: #2563eb; -} - -input::-moz-placeholder, textarea::-moz-placeholder{ - color: #6b7280; - opacity: 1; -} - -input::placeholder,textarea::placeholder{ - color: #6b7280; - opacity: 1; -} - -::-webkit-datetime-edit-fields-wrapper{ - padding: 0; -} - -::-webkit-date-and-time-value{ - min-height: 1.5em; - text-align: inherit; -} - -::-webkit-datetime-edit{ - display: inline-flex; -} - -::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{ - padding-top: 0; - padding-bottom: 0; -} - -select{ - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); - background-position: right 0.5rem center; - background-repeat: no-repeat; - background-size: 1.5em 1.5em; - padding-right: 2.5rem; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; -} - -[multiple],[size]:where(select:not([size="1"])){ - background-image: initial; - background-position: initial; - background-repeat: unset; - background-size: initial; - padding-right: 0.75rem; - -webkit-print-color-adjust: unset; - print-color-adjust: unset; -} - -[type='checkbox'],[type='radio']{ - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - padding: 0; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; - display: inline-block; - vertical-align: middle; - background-origin: border-box; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - flex-shrink: 0; - height: 1rem; - width: 1rem; - color: #2563eb; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - --tw-shadow: 0 0 #0000; -} - -[type='checkbox']{ - border-radius: 0px; -} - -[type='radio']{ - border-radius: 100%; -} - -[type='checkbox']:focus,[type='radio']:focus{ - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 2px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); -} - -[type='checkbox']:checked,[type='radio']:checked{ - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -[type='checkbox']:checked{ - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); -} - -@media (forced-colors: active) { - [type='checkbox']:checked{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='radio']:checked{ - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); -} - -@media (forced-colors: active) { - [type='radio']:checked{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus{ - border-color: transparent; - background-color: currentColor; -} - -[type='checkbox']:indeterminate{ - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -@media (forced-colors: active) { - [type='checkbox']:indeterminate{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus{ - border-color: transparent; - background-color: currentColor; -} - -[type='file']{ - background: unset; - border-color: inherit; - border-width: 0; - border-radius: 0; - padding: 0; - font-size: unset; - line-height: inherit; -} - -[type='file']:focus{ - outline: 1px solid ButtonText; - outline: 1px auto -webkit-focus-ring-color; -} - -:root{ - --motion-default-timing: cubic-bezier(.165, .84, .44, 1); - --motion-bounce: linear(0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141 13.6%, 0.25, 0.391, 0.563, 0.765,1, 0.891 40.9%, 0.848, 0.813, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785,0.813, 0.848, 0.891 68.2%, 1 72.7%, 0.973, 0.953, 0.941, 0.938, 0.941, 0.953,0.973, 1, 0.988, 0.984, 0.988, 1); - --motion-spring-smooth: linear(0, 0.001 0.44%, 0.0045 0.94%, 0.0195 2.03%, 0.0446 3.19%, 0.0811 4.5%, 0.1598 6.82%, 0.3685 12.34%, 0.4693 15.17%, 0.5663, 0.6498 21.27%, 0.7215 24.39%, 0.7532 25.98%, 0.7829 27.65%, 0.8105, 0.8349 31.14%, 0.8573 32.95%, 0.8776 34.84%, 0.8964 36.87%, 0.9136 39.05%, 0.929 41.37%, 0.9421 43.77%, 0.9537 46.38%, 0.9636 49.14%, 0.9789 55.31%, 0.9888 62.35%, 0.9949 71.06%, 0.9982 82.52%, 0.9997 99.94%); - --motion-spring-snappy: linear(0, 0.0014, 0.0053 1.02%, 0.0126, 0.0227 2.18%, 0.0517 3.41%, 0.094 4.79%, 0.1865 7.26%, 0.4182 12.77%, 0.5246 15.46%, 0.6249, 0.7112, 0.7831 23.95%, 0.8146 25.4%, 0.844, 0.8699 28.45%, 0.8935, 0.9139 31.64%, 0.932, 0.9473, 0.9601 36.65%, 0.9714 38.47%, 0.9808 40.35%, 0.9948 44.49%, 1.0031 49.43%, 1.0057 53.35%, 1.0063 58.14%, 1.0014 80.78%, 1.0001 99.94%); - --motion-spring-bouncy: linear(0, 0.0018, 0.0069, 0.0151 1.74%, 0.0277 2.4%, 0.062 3.7%, 0.1115 5.15%, 0.2211 7.77%, 0.4778 13.21%, 0.5912 15.75%, 0.6987 18.44%, 0.7862 20.98%, 0.861 23.59%, 0.8926, 0.9205, 0.945 27.51%, 0.9671 28.89%, 0.9868, 1.003 31.79%, 1.0224 34.11%, 1.0358 36.58%, 1.0436 39.27%, 1.046 42.31%, 1.0446 44.71%, 1.0406 47.47%, 1.0118 61.84%, 1.0027 69.53%, 0.9981 80.49%, 0.9991 99.94%); - --motion-spring-bouncier: linear(0, 0.0023, 0.0088, 0.0194 1.59%, 0.035 2.17%, 0.078 3.33%, 0.1415 4.64%, 0.2054 5.75%, 0.2821 6.95%, 0.5912 11.45%, 0.7205 13.43%, 0.8393 15.45%, 0.936 17.39%, 0.9778, 1.015, 1.0477, 1.0759, 1.0998 22.22%, 1.1203, 1.1364, 1.1484 25.26%, 1.1586 26.61%, 1.1629 28.06%, 1.1613 29.56%, 1.1537 31.2%, 1.1434 32.6%, 1.1288 34.19%, 1.0508 41.29%, 1.0174 44.87%, 1.0025 46.89%, 0.9911 48.87%, 0.9826 50.9%, 0.9769 53.03%, 0.9735 56.02%, 0.9748 59.45%, 0.9964 72.64%, 1.0031 79.69%, 1.0042 86.83%, 1.0008 99.97%); - --motion-spring-bounciest: linear(0, 0.0032, 0.0131, 0.0294, 0.0524, 0.0824, 0.1192 1.54%, 0.2134 2.11%, 0.3102 2.59%, 0.4297 3.13%, 0.8732 4.95%, 1.0373, 1.1827 6.36%, 1.2972 7.01%, 1.3444, 1.3859, 1.4215, 1.4504, 1.4735, 1.4908, 1.5024, 1.5084 9.5%, 1.5091, 1.5061, 1.4993, 1.4886, 1.4745, 1.4565 11.11%, 1.4082 11.7%, 1.3585 12.2%, 1.295 12.77%, 1.0623 14.64%, 0.9773, 0.9031 16.08%, 0.8449 16.73%, 0.8014, 0.7701 17.95%, 0.7587, 0.7501, 0.7443, 0.7412 19.16%, 0.7421 19.68%, 0.7508 20.21%, 0.7672 20.77%, 0.7917 21.37%, 0.8169 21.87%, 0.8492 22.43%, 0.9681 24.32%, 1.0114, 1.0492 25.75%, 1.0789 26.41%, 1.1008, 1.1167, 1.1271, 1.1317 28.81%, 1.1314, 1.1271 29.87%, 1.1189 30.43%, 1.1063 31.03%, 1.0769 32.11%, 0.9941 34.72%, 0.9748 35.43%, 0.9597 36.09%, 0.9487, 0.9407, 0.9355, 0.933 38.46%, 0.9344 39.38%, 0.9421 40.38%, 0.9566 41.5%, 0.9989 44.12%, 1.0161 45.37%, 1.029 46.75%, 1.0341 48.1%, 1.0335 49.04%, 1.0295 50.05%, 1.0221 51.18%, 0.992 55.02%, 0.9854 56.38%, 0.9827 57.72%, 0.985 59.73%, 1.004 64.67%, 1.0088 67.34%, 1.0076 69.42%, 0.9981 74.28%, 0.9956 76.85%, 0.9961 79.06%, 1.0023 86.46%, 0.999 95.22%, 0.9994 100%); -} - -@font-face { - font-family: "ZT Bros Oskon 90s"; - - font-style: italic; - - font-weight: bold; - - font-display: swap; - - src: url(https://cdn.sonr.id/fonts/ZTBrosOskon90s-BoldSemExpIta.woff2) - format("woff2"); -} - -@font-face { - font-family: "ZT Bros Oskon 90s"; - - font-style: normal; - - font-weight: bold; - - font-display: swap; - - src: url(https://cdn.sonr.id/fonts/ZTBrosOskon90s-BoldSemExp.woff2) - format("woff2"); -} - -.container{ - width: 100%; -} - -@media (min-width: 640px){ - .container{ - max-width: 640px; - } -} - -@media (min-width: 768px){ - .container{ - max-width: 768px; - } -} - -@media (min-width: 1024px){ - .container{ - max-width: 1024px; - } -} - -@media (min-width: 1280px){ - .container{ - max-width: 1280px; - } -} - -@media (min-width: 1536px){ - .container{ - max-width: 1536px; - } -} - -.form-input,.form-textarea,.form-select,.form-multiselect{ - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - border-radius: 0px; - padding-top: 0.5rem; - padding-right: 0.75rem; - padding-bottom: 0.5rem; - padding-left: 0.75rem; - font-size: 1rem; - line-height: 1.5rem; - --tw-shadow: 0 0 #0000; -} - -.form-input:focus, .form-textarea:focus, .form-select:focus, .form-multiselect:focus{ - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - border-color: #2563eb; -} - -.form-input::-moz-placeholder, .form-textarea::-moz-placeholder{ - color: #6b7280; - opacity: 1; -} - -.form-input::placeholder,.form-textarea::placeholder{ - color: #6b7280; - opacity: 1; -} - -.form-input::-webkit-datetime-edit-fields-wrapper{ - padding: 0; -} - -.form-input::-webkit-date-and-time-value{ - min-height: 1.5em; - text-align: inherit; -} - -.form-input::-webkit-datetime-edit{ - display: inline-flex; -} - -.form-input::-webkit-datetime-edit,.form-input::-webkit-datetime-edit-year-field,.form-input::-webkit-datetime-edit-month-field,.form-input::-webkit-datetime-edit-day-field,.form-input::-webkit-datetime-edit-hour-field,.form-input::-webkit-datetime-edit-minute-field,.form-input::-webkit-datetime-edit-second-field,.form-input::-webkit-datetime-edit-millisecond-field,.form-input::-webkit-datetime-edit-meridiem-field{ - padding-top: 0; - padding-bottom: 0; -} - -.form-select{ - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); - background-position: right 0.5rem center; - background-repeat: no-repeat; - background-size: 1.5em 1.5em; - padding-right: 2.5rem; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; -} - -.form-select:where([size]:not([size="1"])){ - background-image: initial; - background-position: initial; - background-repeat: unset; - background-size: initial; - padding-right: 0.75rem; - -webkit-print-color-adjust: unset; - print-color-adjust: unset; -} - -.form-checkbox,.form-radio{ - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - padding: 0; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; - display: inline-block; - vertical-align: middle; - background-origin: border-box; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - flex-shrink: 0; - height: 1rem; - width: 1rem; - color: #2563eb; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - --tw-shadow: 0 0 #0000; -} - -.form-checkbox{ - border-radius: 0px; -} - -.form-radio{ - border-radius: 100%; -} - -.form-checkbox:focus,.form-radio:focus{ - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 2px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); -} - -.form-checkbox:checked,.form-radio:checked{ - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -.form-checkbox:checked{ - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); -} - -@media (forced-colors: active) { - .form-checkbox:checked{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -.form-radio:checked{ - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); -} - -@media (forced-colors: active) { - .form-radio:checked{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -.form-checkbox:checked:hover,.form-checkbox:checked:focus,.form-radio:checked:hover,.form-radio:checked:focus{ - border-color: transparent; - background-color: currentColor; -} - -.form-checkbox:indeterminate{ - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -@media (forced-colors: active) { - .form-checkbox:indeterminate{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -.form-checkbox:indeterminate:hover,.form-checkbox:indeterminate:focus{ - border-color: transparent; - background-color: currentColor; -} - -.motion-preset-slide-up{ - --motion-origin-translate-y: 25%; - --motion-origin-opacity: 0; - --motion-opacity-in-animation: motion-opacity-in calc(var(--motion-opacity-duration) * var(--motion-opacity-perceptual-duration-multiplier)) var(--motion-opacity-timing) var(--motion-opacity-delay) both; - --motion-translate-in-animation: motion-translate-in calc(var(--motion-translate-duration) * var(--motion-translate-perceptual-duration-multiplier)) var(--motion-translate-timing) var(--motion-translate-delay) both; - animation: var(--motion-all-enter-animations); -} - -@keyframes RomboConfettiPop{ - 0%{ - opacity: 0; - transform: scale(1); - } - - 33%{ - opacity: 1; - transform: scale(1.15); - } - - 50%{ - transform: scale(0.975); - } - - 65%{ - transform: scale(1.025); - } - - 80%{ - transform: scale(0.99); - } - - 87%{ - transform: scale(1.01); - } - - 100%{ - opacity: 1; - transform: scale(1); - } -} - -@keyframes topfetti{ - 0%{ - background-position: 5% 90%, 10% 90%, 10% 90%, 15% 90%, 25% 90%, 25% 90%, 40% 90%, 55% 90%, 70% 90%; - } - - 50%{ - background-position: 0% 80%, 0% 20%, 10% 40%, 20% 0%, 30% 30%, 22% 50%, 50% 50%, 65% 20%, 90% 30%; - } - - 100%{ - background-position: 0% 70%, 0% 10%, 10% 30%, 20% -10%, 30% 20%, 22% 40%, 50% 40%, 65% 10%, 90% 20%; - background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; - } -} - -@keyframes bottomfetti{ - 0%{ - background-position: 10% -10%, 30% 10%, 55% -10%, 70% -10%, 85% -10%,70% -10%, 70% 0%; - } - - 50%{ - background-position: 0% 80%, 20% 80%, 45% 60%, 60% 100%, 75% 70%, 95% 60%, 105% 0%; - } - - 100%{ - background-position: 0% 90%, 20% 90%, 45% 70%, 60% 110%, 75% 80%, 95% 70%, 110% 10%; - background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; - } -} - -.invisible{ - visibility: hidden; -} - -.fixed{ - position: fixed; -} - -.absolute{ - position: absolute; -} - -.relative{ - position: relative; -} - -.inset-0{ - inset: 0px; -} - -.bottom-0{ - bottom: 0px; -} - -.left-0{ - left: 0px; -} - -.left-1\/2{ - left: 50%; -} - -.right-0{ - right: 0px; -} - -.top-0{ - top: 0px; -} - -.top-2{ - top: 0.5rem; -} - -.-z-10{ - z-index: -10; -} - -.z-10{ - z-index: 10; -} - -.z-20{ - z-index: 20; -} - -.z-30{ - z-index: 30; -} - -.z-40{ - z-index: 40; -} - -.z-50{ - z-index: 50; -} - -.z-\[99\]{ - z-index: 99; -} - -.order-first{ - order: -9999; -} - -.-m-2{ - margin: -0.5rem; -} - -.m-2{ - margin: 0.5rem; -} - -.mx-0{ - margin-left: 0px; - margin-right: 0px; -} - -.mx-3{ - margin-left: 0.75rem; - margin-right: 0.75rem; -} - -.mx-auto{ - margin-left: auto; - margin-right: auto; -} - -.mb-1{ - margin-bottom: 0.25rem; -} - -.mb-2{ - margin-bottom: 0.5rem; -} - -.mb-3{ - margin-bottom: 0.75rem; -} - -.mb-4{ - margin-bottom: 1rem; -} - -.mb-6{ - margin-bottom: 1.5rem; -} - -.mb-8{ - margin-bottom: 2rem; -} - -.ml-1{ - margin-left: 0.25rem; -} - -.ml-2{ - margin-left: 0.5rem; -} - -.mr-0\.5{ - margin-right: 0.125rem; -} - -.mr-1{ - margin-right: 0.25rem; -} - -.mr-2{ - margin-right: 0.5rem; -} - -.mr-3{ - margin-right: 0.75rem; -} - -.mr-4{ - margin-right: 1rem; -} - -.mr-5{ - margin-right: 1.25rem; -} - -.mr-7{ - margin-right: 1.75rem; -} - -.mt-0{ - margin-top: 0px; -} - -.mt-0\.5{ - margin-top: 0.125rem; -} - -.mt-1{ - margin-top: 0.25rem; -} - -.mt-12{ - margin-top: 3rem; -} - -.mt-2{ - margin-top: 0.5rem; -} - -.mt-24{ - margin-top: 6rem; -} - -.mt-4{ - margin-top: 1rem; -} - -.mt-5{ - margin-top: 1.25rem; -} - -.mt-6{ - margin-top: 1.5rem; -} - -.mt-8{ - margin-top: 2rem; -} - -.box-content{ - box-sizing: content-box; -} - -.block{ - display: block; -} - -.flex{ - display: flex; -} - -.inline-flex{ - display: inline-flex; -} - -.grid{ - display: grid; -} - -.hidden{ - display: none; -} - -.aspect-video{ - aspect-ratio: 16 / 9; -} - -.h-1{ - height: 0.25rem; -} - -.h-1\.5{ - height: 0.375rem; -} - -.h-1\/4{ - height: 25%; -} - -.h-10{ - height: 2.5rem; -} - -.h-12{ - height: 3rem; -} - -.h-14{ - height: 3.5rem; -} - -.h-20{ - height: 5rem; -} - -.h-24{ - height: 6rem; -} - -.h-3{ - height: 0.75rem; -} - -.h-32{ - height: 8rem; -} - -.h-4{ - height: 1rem; -} - -.h-5{ - height: 1.25rem; -} - -.h-6{ - height: 1.5rem; -} - -.h-8{ - height: 2rem; -} - -.h-9{ - height: 2.25rem; -} - -.h-\[18px\]{ - height: 18px; -} - -.h-\[280px\]{ - height: 280px; -} - -.h-\[360px\]{ - height: 360px; -} - -.h-auto{ - height: auto; -} - -.h-full{ - height: 100%; -} - -.h-screen{ - height: 100vh; -} - -.min-h-screen{ - min-height: 100vh; -} - -.w-0{ - width: 0px; -} - -.w-10{ - width: 2.5rem; -} - -.w-12{ - width: 3rem; -} - -.w-14{ - width: 3.5rem; -} - -.w-16{ - width: 4rem; -} - -.w-20{ - width: 5rem; -} - -.w-24{ - width: 6rem; -} - -.w-3{ - width: 0.75rem; -} - -.w-4{ - width: 1rem; -} - -.w-5{ - width: 1.25rem; -} - -.w-6{ - width: 1.5rem; -} - -.w-8{ - width: 2rem; -} - -.w-\[18px\]{ - width: 18px; -} - -.w-\[22rem\]{ - width: 22rem; -} - -.w-\[365px\]{ - width: 365px; -} - -.w-\[calc\(100\%\+1rem\)\]{ - width: calc(100% + 1rem); -} - -.w-\[full\]{ - width: full; -} - -.w-auto{ - width: auto; -} - -.w-fit{ - width: -moz-fit-content; - width: fit-content; -} - -.w-full{ - width: 100%; -} - -.w-screen{ - width: 100vw; -} - -.min-w-\[640px\]{ - min-width: 640px; -} - -.max-w-2xl{ - max-width: 42rem; -} - -.max-w-3xl{ - max-width: 48rem; -} - -.max-w-4xl{ - max-width: 56rem; -} - -.max-w-5xl{ - max-width: 64rem; -} - -.max-w-6xl{ - max-width: 72rem; -} - -.max-w-\[94rem\]{ - max-width: 94rem; -} - -.max-w-lg{ - max-width: 32rem; -} - -.max-w-md{ - max-width: 28rem; -} - -.max-w-screen-sm{ - max-width: 640px; -} - -.max-w-sm{ - max-width: 24rem; -} - -.max-w-xl{ - max-width: 36rem; -} - -.max-w-xs{ - max-width: 20rem; -} - -.shrink-0{ - flex-shrink: 0; -} - -.grow{ - flex-grow: 1; -} - -.-translate-x-0{ - --tw-translate-x: -0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-1\/2{ - --tw-translate-x: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-4{ - --tw-translate-x: -1rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-7{ - --tw-translate-x: -1.75rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-8{ - --tw-translate-x: -2rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-y-0\.5{ - --tw-translate-y: -0.125rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-y-4{ - --tw-translate-y: -1rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-y-8{ - --tw-translate-y: -2rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-y-full{ - --tw-translate-y: -100%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-x-0{ - --tw-translate-x: 0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-x-0\.5{ - --tw-translate-x: 0.125rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-x-8{ - --tw-translate-x: 2rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-x-px{ - --tw-translate-x: 1px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-0{ - --tw-translate-y: 0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-1\/3{ - --tw-translate-y: 33.333333%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-24{ - --tw-translate-y: 6rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-3{ - --tw-translate-y: 0.75rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-4{ - --tw-translate-y: 1rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-full{ - --tw-translate-y: 100%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-px{ - --tw-translate-y: 1px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.rotate-1{ - --tw-rotate: 1deg; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.scale-100{ - --tw-scale-x: 1; - --tw-scale-y: 1; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.scale-50{ - --tw-scale-x: .5; - --tw-scale-y: .5; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.scale-75{ - --tw-scale-x: .75; - --tw-scale-y: .75; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.scale-90{ - --tw-scale-x: .9; - --tw-scale-y: .9; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.transform{ - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -@keyframes infinite-scroll{ - from{ - transform: translateX(0); - } - - to{ - transform: translateX(-100%); - } -} - -.animate-infinite-scroll{ - animation: infinite-scroll 60s linear infinite; -} - -@keyframes infinite-scroll-inverse{ - from{ - transform: translateX(-100%); - } - - to{ - transform: translateX(0); - } -} - -.animate-infinite-scroll-inverse{ - animation: infinite-scroll-inverse 60s linear infinite; -} - -.cursor-default{ - cursor: default; -} - -.cursor-pointer{ - cursor: pointer; -} - -.appearance-none{ - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} - -.grid-cols-1{ - grid-template-columns: repeat(1, minmax(0, 1fr)); -} - -.grid-cols-2{ - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.flex-row{ - flex-direction: row; -} - -.flex-col{ - flex-direction: column; -} - -.flex-col-reverse{ - flex-direction: column-reverse; -} - -.flex-wrap{ - flex-wrap: wrap; -} - -.flex-nowrap{ - flex-wrap: nowrap; -} - -.items-start{ - align-items: flex-start; -} - -.items-end{ - align-items: flex-end; -} - -.items-center{ - align-items: center; -} - -.justify-end{ - justify-content: flex-end; -} - -.justify-center{ - justify-content: center; -} - -.justify-between{ - justify-content: space-between; -} - -.gap-12{ - gap: 3rem; -} - -.gap-2{ - gap: 0.5rem; -} - -.gap-3{ - gap: 0.75rem; -} - -.gap-4{ - gap: 1rem; -} - -.gap-6{ - gap: 1.5rem; -} - -.gap-8{ - gap: 2rem; -} - -.gap-x-3{ - -moz-column-gap: 0.75rem; - column-gap: 0.75rem; -} - -.gap-y-3{ - row-gap: 0.75rem; -} - -.space-x-1 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(0.25rem * var(--tw-space-x-reverse)); - margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse))); -} - -.space-x-3 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(0.75rem * var(--tw-space-x-reverse)); - margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); -} - -.space-x-4 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(1rem * var(--tw-space-x-reverse)); - margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); -} - -.space-y-1 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); -} - -.space-y-1\.5 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.375rem * var(--tw-space-y-reverse)); -} - -.space-y-12 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(3rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(3rem * var(--tw-space-y-reverse)); -} - -.space-y-2 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); -} - -.space-y-3 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); -} - -.space-y-4 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1rem * var(--tw-space-y-reverse)); -} - -.space-y-6 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); -} - -.divide-y > :not([hidden]) ~ :not([hidden]){ - --tw-divide-y-reverse: 0; - border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); - border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); -} - -.overflow-hidden{ - overflow: hidden; -} - -.rounded{ - border-radius: 0.25rem; -} - -.rounded-full{ - border-radius: 9999px; -} - -.rounded-lg{ - border-radius: 0.5rem; -} - -.rounded-md{ - border-radius: 0.375rem; -} - -.rounded-xl{ - border-radius: 0.75rem; -} - -.rounded-t-lg{ - border-top-left-radius: 0.5rem; - border-top-right-radius: 0.5rem; -} - -.border{ - border-width: 1px; -} - -.border-0{ - border-width: 0px; -} - -.border-2{ - border-width: 2px; -} - -.border-b-2{ - border-bottom-width: 2px; -} - -.border-t{ - border-top-width: 1px; -} - -.border-blue-600{ - --tw-border-opacity: 1; - border-color: rgb(37 99 235 / var(--tw-border-opacity)); -} - -.border-gray-200{ - --tw-border-opacity: 1; - border-color: rgb(229 231 235 / var(--tw-border-opacity)); -} - -.border-gray-300{ - --tw-border-opacity: 1; - border-color: rgb(209 213 219 / var(--tw-border-opacity)); -} - -.border-green-600{ - --tw-border-opacity: 1; - border-color: rgb(22 163 74 / var(--tw-border-opacity)); -} - -.border-neutral-200\/60{ - border-color: rgb(229 229 229 / 0.6); -} - -.border-neutral-200\/70{ - border-color: rgb(229 229 229 / 0.7); -} - -.border-neutral-300{ - --tw-border-opacity: 1; - border-color: rgb(212 212 212 / var(--tw-border-opacity)); -} - -.border-neutral-900{ - --tw-border-opacity: 1; - border-color: rgb(23 23 23 / var(--tw-border-opacity)); -} - -.border-red-600{ - --tw-border-opacity: 1; - border-color: rgb(220 38 38 / var(--tw-border-opacity)); -} - -.border-transparent{ - border-color: transparent; -} - -.border-white{ - --tw-border-opacity: 1; - border-color: rgb(255 255 255 / var(--tw-border-opacity)); -} - -.border-yellow-500{ - --tw-border-opacity: 1; - border-color: rgb(234 179 8 / var(--tw-border-opacity)); -} - -.border-zinc-200{ - --tw-border-opacity: 1; - border-color: rgb(228 228 231 / var(--tw-border-opacity)); -} - -.border-zinc-300{ - --tw-border-opacity: 1; - border-color: rgb(212 212 216 / var(--tw-border-opacity)); -} - -.border-zinc-600{ - --tw-border-opacity: 1; - border-color: rgb(82 82 91 / var(--tw-border-opacity)); -} - -.bg-black{ - --tw-bg-opacity: 1; - background-color: rgb(0 0 0 / var(--tw-bg-opacity)); -} - -.bg-blue-50{ - --tw-bg-opacity: 1; - background-color: rgb(239 246 255 / var(--tw-bg-opacity)); -} - -.bg-blue-600{ - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity)); -} - -.bg-gray-100{ - --tw-bg-opacity: 1; - background-color: rgb(243 244 246 / var(--tw-bg-opacity)); -} - -.bg-gray-200{ - --tw-bg-opacity: 1; - background-color: rgb(229 231 235 / var(--tw-bg-opacity)); -} - -.bg-green-50{ - --tw-bg-opacity: 1; - background-color: rgb(240 253 244 / var(--tw-bg-opacity)); -} - -.bg-green-600{ - --tw-bg-opacity: 1; - background-color: rgb(22 163 74 / var(--tw-bg-opacity)); -} - -.bg-neutral-50{ - --tw-bg-opacity: 1; - background-color: rgb(250 250 250 / var(--tw-bg-opacity)); -} - -.bg-neutral-900{ - --tw-bg-opacity: 1; - background-color: rgb(23 23 23 / var(--tw-bg-opacity)); -} - -.bg-neutral-950{ - --tw-bg-opacity: 1; - background-color: rgb(10 10 10 / var(--tw-bg-opacity)); -} - -.bg-red-50{ - --tw-bg-opacity: 1; - background-color: rgb(254 242 242 / var(--tw-bg-opacity)); -} - -.bg-red-600{ - --tw-bg-opacity: 1; - background-color: rgb(220 38 38 / var(--tw-bg-opacity)); -} - -.bg-transparent{ - background-color: transparent; -} - -.bg-white{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.bg-yellow-50{ - --tw-bg-opacity: 1; - background-color: rgb(254 252 232 / var(--tw-bg-opacity)); -} - -.bg-yellow-600{ - --tw-bg-opacity: 1; - background-color: rgb(202 138 4 / var(--tw-bg-opacity)); -} - -.bg-zinc-100{ - --tw-bg-opacity: 1; - background-color: rgb(244 244 245 / var(--tw-bg-opacity)); -} - -.bg-zinc-50{ - --tw-bg-opacity: 1; - background-color: rgb(250 250 250 / var(--tw-bg-opacity)); -} - -.bg-zinc-800{ - --tw-bg-opacity: 1; - background-color: rgb(39 39 42 / var(--tw-bg-opacity)); -} - -.bg-zinc-900{ - --tw-bg-opacity: 1; - background-color: rgb(24 24 27 / var(--tw-bg-opacity)); -} - -.bg-opacity-0{ - --tw-bg-opacity: 0; -} - -.bg-opacity-20{ - --tw-bg-opacity: 0.2; -} - -.bg-opacity-80{ - --tw-bg-opacity: 0.8; -} - -.bg-opacity-90{ - --tw-bg-opacity: 0.9; -} - -.bg-gradient-to-b{ - background-image: linear-gradient(to bottom, var(--tw-gradient-stops)); -} - -.bg-gradient-to-r{ - background-image: linear-gradient(to right, var(--tw-gradient-stops)); -} - -.from-black{ - --tw-gradient-from: #000 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.from-transparent{ - --tw-gradient-from: transparent var(--tw-gradient-from-position); - --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.from-zinc-100{ - --tw-gradient-from: #f4f4f5 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(244 244 245 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.from-zinc-500{ - --tw-gradient-from: #71717a var(--tw-gradient-from-position); - --tw-gradient-to: rgb(113 113 122 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.via-zinc-900{ - --tw-gradient-to: rgb(24 24 27 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), #18181b var(--tw-gradient-via-position), var(--tw-gradient-to); -} - -.to-black{ - --tw-gradient-to: #000 var(--tw-gradient-to-position); -} - -.to-transparent{ - --tw-gradient-to: transparent var(--tw-gradient-to-position); -} - -.to-white{ - --tw-gradient-to: #fff var(--tw-gradient-to-position); -} - -.to-zinc-900{ - --tw-gradient-to: #18181b var(--tw-gradient-to-position); -} - -.bg-clip-text{ - -webkit-background-clip: text; - background-clip: text; -} - -.fill-current{ - fill: currentColor; -} - -.fill-zinc-300{ - fill: #d4d4d8; -} - -.fill-zinc-400{ - fill: #a1a1aa; -} - -.object-cover{ - -o-object-fit: cover; - object-fit: cover; -} - -.object-left{ - -o-object-position: left; - object-position: left; -} - -.p-1{ - padding: 0.25rem; -} - -.p-4{ - padding: 1rem; -} - -.p-5{ - padding: 1.25rem; -} - -.p-6{ - padding: 1.5rem; -} - -.p-7{ - padding: 1.75rem; -} - -.px-0\.5{ - padding-left: 0.125rem; - padding-right: 0.125rem; -} - -.px-2\.5{ - padding-left: 0.625rem; - padding-right: 0.625rem; -} - -.px-3{ - padding-left: 0.75rem; - padding-right: 0.75rem; -} - -.px-3\.5{ - padding-left: 0.875rem; - padding-right: 0.875rem; -} - -.px-4{ - padding-left: 1rem; - padding-right: 1rem; -} - -.px-5{ - padding-left: 1.25rem; - padding-right: 1.25rem; -} - -.px-6{ - padding-left: 1.5rem; - padding-right: 1.5rem; -} - -.px-7{ - padding-left: 1.75rem; - padding-right: 1.75rem; -} - -.px-8{ - padding-left: 2rem; - padding-right: 2rem; -} - -.py-0\.5{ - padding-top: 0.125rem; - padding-bottom: 0.125rem; -} - -.py-1{ - padding-top: 0.25rem; - padding-bottom: 0.25rem; -} - -.py-12{ - padding-top: 3rem; - padding-bottom: 3rem; -} - -.py-2{ - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} - -.py-4{ - padding-top: 1rem; - padding-bottom: 1rem; -} - -.py-5{ - padding-top: 1.25rem; - padding-bottom: 1.25rem; -} - -.py-6{ - padding-top: 1.5rem; - padding-bottom: 1.5rem; -} - -.py-8{ - padding-top: 2rem; - padding-bottom: 2rem; -} - -.pb-1{ - padding-bottom: 0.25rem; -} - -.pb-12{ - padding-bottom: 3rem; -} - -.pb-2{ - padding-bottom: 0.5rem; -} - -.pb-3{ - padding-bottom: 0.75rem; -} - -.pb-4{ - padding-bottom: 1rem; -} - -.pb-6{ - padding-bottom: 1.5rem; -} - -.pb-8{ - padding-bottom: 2rem; -} - -.pl-4{ - padding-left: 1rem; -} - -.pr-2{ - padding-right: 0.5rem; -} - -.pr-4{ - padding-right: 1rem; -} - -.pt-0{ - padding-top: 0px; -} - -.pt-2{ - padding-top: 0.5rem; -} - -.pt-32{ - padding-top: 8rem; -} - -.pt-6{ - padding-top: 1.5rem; -} - -.pt-8{ - padding-top: 2rem; -} - -.text-left{ - text-align: left; -} - -.text-center{ - text-align: center; -} - -.align-top{ - vertical-align: top; -} - -.font-inter{ - font-family: Inter, sans-serif; -} - -.font-inter-tight{ - font-family: Inter Tight, sans-serif; -} - -.font-mono{ - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; -} - -.text-2xl{ - font-size: 1.5rem; - line-height: 1.415; - letter-spacing: -0.017em; -} - -.text-3xl{ - font-size: 2rem; - line-height: 1.3125; - letter-spacing: -0.017em; -} - -.text-4xl{ - font-size: 2.5rem; - line-height: 1.25; - letter-spacing: -0.017em; -} - -.text-base{ - font-size: 1rem; - line-height: 1.5; - letter-spacing: -0.017em; -} - -.text-lg{ - font-size: 1.125rem; - line-height: 1.5; - letter-spacing: -0.017em; -} - -.text-sm{ - font-size: 0.875rem; - line-height: 1.5715; -} - -.text-xl{ - font-size: 1.25rem; - line-height: 1.5; - letter-spacing: -0.017em; -} - -.text-xs{ - font-size: 0.75rem; - line-height: 1.5; -} - -.font-bold{ - font-weight: 700; -} - -.font-medium{ - font-weight: 500; -} - -.font-normal{ - font-weight: 400; -} - -.font-semibold{ - font-weight: 600; -} - -.italic{ - font-style: italic; -} - -.not-italic{ - font-style: normal; -} - -.tabular-nums{ - --tw-numeric-spacing: tabular-nums; - font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); -} - -.leading-none{ - line-height: 1; -} - -.tracking-tight{ - letter-spacing: -0.025em; -} - -.tracking-wide{ - letter-spacing: 0.025em; -} - -.text-black{ - --tw-text-opacity: 1; - color: rgb(0 0 0 / var(--tw-text-opacity)); -} - -.text-blue-500{ - --tw-text-opacity: 1; - color: rgb(59 130 246 / var(--tw-text-opacity)); -} - -.text-blue-600{ - --tw-text-opacity: 1; - color: rgb(37 99 235 / var(--tw-text-opacity)); -} - -.text-gray-400{ - --tw-text-opacity: 1; - color: rgb(156 163 175 / var(--tw-text-opacity)); -} - -.text-gray-400\/70{ - color: rgb(156 163 175 / 0.7); -} - -.text-gray-500{ - --tw-text-opacity: 1; - color: rgb(107 114 128 / var(--tw-text-opacity)); -} - -.text-gray-600{ - --tw-text-opacity: 1; - color: rgb(75 85 99 / var(--tw-text-opacity)); -} - -.text-gray-700{ - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity)); -} - -.text-gray-900{ - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); -} - -.text-green-500{ - --tw-text-opacity: 1; - color: rgb(34 197 94 / var(--tw-text-opacity)); -} - -.text-green-600{ - --tw-text-opacity: 1; - color: rgb(22 163 74 / var(--tw-text-opacity)); -} - -.text-indigo-600{ - --tw-text-opacity: 1; - color: rgb(79 70 229 / var(--tw-text-opacity)); -} - -.text-neutral-100{ - --tw-text-opacity: 1; - color: rgb(245 245 245 / var(--tw-text-opacity)); -} - -.text-neutral-500{ - --tw-text-opacity: 1; - color: rgb(115 115 115 / var(--tw-text-opacity)); -} - -.text-neutral-800{ - --tw-text-opacity: 1; - color: rgb(38 38 38 / var(--tw-text-opacity)); -} - -.text-neutral-900{ - --tw-text-opacity: 1; - color: rgb(23 23 23 / var(--tw-text-opacity)); -} - -.text-red-500{ - --tw-text-opacity: 1; - color: rgb(239 68 68 / var(--tw-text-opacity)); -} - -.text-red-600{ - --tw-text-opacity: 1; - color: rgb(220 38 38 / var(--tw-text-opacity)); -} - -.text-transparent{ - color: transparent; -} - -.text-white{ - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.text-yellow-600{ - --tw-text-opacity: 1; - color: rgb(202 138 4 / var(--tw-text-opacity)); -} - -.text-zinc-100{ - --tw-text-opacity: 1; - color: rgb(244 244 245 / var(--tw-text-opacity)); -} - -.text-zinc-200{ - --tw-text-opacity: 1; - color: rgb(228 228 231 / var(--tw-text-opacity)); -} - -.text-zinc-400{ - --tw-text-opacity: 1; - color: rgb(161 161 170 / var(--tw-text-opacity)); -} - -.text-zinc-500{ - --tw-text-opacity: 1; - color: rgb(113 113 122 / var(--tw-text-opacity)); -} - -.text-zinc-600{ - --tw-text-opacity: 1; - color: rgb(82 82 91 / var(--tw-text-opacity)); -} - -.text-zinc-700{ - --tw-text-opacity: 1; - color: rgb(63 63 70 / var(--tw-text-opacity)); -} - -.text-zinc-800{ - --tw-text-opacity: 1; - color: rgb(39 39 42 / var(--tw-text-opacity)); -} - -.text-zinc-900{ - --tw-text-opacity: 1; - color: rgb(24 24 27 / var(--tw-text-opacity)); -} - -.underline{ - text-decoration-line: underline; -} - -.antialiased{ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.opacity-0{ - opacity: 0; -} - -.opacity-100{ - opacity: 1; -} - -.opacity-20{ - opacity: 0.2; -} - -.opacity-50{ - opacity: 0.5; -} - -.opacity-60{ - opacity: 0.6; -} - -.opacity-80{ - opacity: 0.8; -} - -.mix-blend-exclusion{ - mix-blend-mode: exclusion; -} - -.shadow{ - --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-2xl{ - --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); - --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-md{ - --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-sm{ - --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); - --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-zinc-950\/20{ - --tw-shadow-color: rgb(9 9 11 / 0.2); - --tw-shadow: var(--tw-shadow-colored); -} - -.drop-shadow-md{ - --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); -} - -.backdrop-blur-sm{ - --tw-backdrop-blur: blur(4px); - -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); -} - -.transition{ - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.transition-colors{ - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.delay-200{ - transition-delay: 200ms; -} - -.duration-100{ - transition-duration: 100ms; -} - -.duration-1000{ - transition-duration: 1000ms; -} - -.duration-150{ - transition-duration: 150ms; -} - -.duration-200{ - transition-duration: 200ms; -} - -.duration-300{ - transition-duration: 300ms; -} - -.duration-700{ - transition-duration: 700ms; -} - -.ease-in{ - transition-timing-function: cubic-bezier(0.4, 0, 1, 1); -} - -.ease-in-out{ - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); -} - -.ease-out{ - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); -} - -@media screen and (prefers-reduced-motion: no-preference){ - @keyframes motion-scale-in{ - 0%{ - scale: var(--motion-origin-scale-x) var(--motion-origin-scale-y); - } - - 100%{ - scale: 1 1; - } - } - - @keyframes motion-scale-out{ - 0%{ - scale: 1 1; - } - - 100%{ - scale: var(--motion-end-scale-x) var(--motion-end-scale-y); - } - } - - @keyframes motion-translate-in{ - 0%{ - translate: var(--motion-origin-translate-x) var(--motion-origin-translate-y); - } - - 100%{ - translate: 0 0; - } - } - - @keyframes motion-translate-out{ - 0%{ - translate: 0 0; - } - - 100%{ - translate: var(--motion-end-translate-x) var(--motion-end-translate-y); - } - } - - @keyframes motion-rotate-in{ - 0%{ - rotate: var(--motion-origin-rotate); - } - - 100%{ - rotate: 0; - } - } - - @keyframes motion-rotate-out{ - 0%{ - rotate: 0; - } - - 100%{ - rotate: var(--motion-end-rotate); - } - } -} - -@keyframes motion-filter-in{ - 0%{ - filter: blur(var(--motion-origin-blur)) grayscale(var(--motion-origin-grayscale)); - } - - 100%{ - filter: blur(0) grayscale(0); - } -} - -@keyframes motion-filter-out{ - 0%{ - filter: blur(0) grayscale(0); - } - - 100%{ - filter: blur(var(--motion-end-blur)) grayscale(var(--motion-end-grayscale)); - } -} - -@keyframes motion-opacity-in{ - 0%{ - opacity: var(--motion-origin-opacity); - } -} - -@keyframes motion-opacity-out{ - 100%{ - opacity: var(--motion-end-opacity); - } -} - -@keyframes motion-background-color-in{ - 0%{ - background-color: var(--motion-origin-background-color); - } -} - -@keyframes motion-background-color-out{ - 100%{ - background-color: var(--motion-end-background-color); - } -} - -@keyframes motion-text-color-in{ - 0%{ - color: var(--motion-origin-text-color); - } -} - -@keyframes motion-text-color-out{ - 100%{ - color: var(--motion-end-text-color); - } -} - -.motion-scale-in-50{ - --motion-origin-scale-x: .5; - --motion-origin-scale-y: .5; - --motion-scale-in-animation: motion-scale-in calc(var(--motion-scale-duration) * var(--motion-scale-perceptual-duration-multiplier)) var(--motion-scale-timing) var(--motion-scale-delay) both; - animation: var(--motion-all-enter-animations); -} - -.motion-opacity-in-0{ - --motion-origin-opacity: 0.001; - --motion-opacity-in-animation: motion-opacity-in calc(var(--motion-opacity-duration) * var(--motion-opacity-perceptual-duration-multiplier)) var(--motion-opacity-timing) var(--motion-opacity-delay) both; - animation: var(--motion-all-enter-animations); -} - -.\[animation-delay\:-7\.5s\]{ - animation-delay: -7.5s; -} - -.\[background\:linear-gradient\(\#2E2E32\2c \#2E2E32\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ - background: linear-gradient(#2E2E32,#2E2E32) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; -} - -.\[background\:linear-gradient\(\#323237\2c \#323237\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ - background: linear-gradient(#323237,#323237) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; -} - -.\[background\:linear-gradient\(theme\(colors\.white\)\2c theme\(colors\.white\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ - background: linear-gradient(#fff,#fff) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; -} - -.\[background\:linear-gradient\(theme\(colors\.white\)\2c theme\(colors\.zinc\.50\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ - background: linear-gradient(#fff,#fafafa) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; -} - -.\[background\:linear-gradient\(theme\(colors\.zinc\.50\)\2c theme\(colors\.zinc\.50\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ - background: linear-gradient(#fafafa,#fafafa) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; -} - -.\[background\:linear-gradient\(theme\(colors\.zinc\.800\)\2c theme\(colors\.zinc\.800\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ - background: linear-gradient(#27272a,#27272a) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; -} - -.\[mask-image\:_linear-gradient\(to_right\2c transparent_0\2c _black_28\%\2c _black_calc\(100\%-28\%\)\2c transparent_100\%\)\]{ - -webkit-mask-image: linear-gradient(to right,transparent 0, black 28%, black calc(100% - 28%),transparent 100%); - mask-image: linear-gradient(to right,transparent 0, black 28%, black calc(100% - 28%),transparent 100%); -} - -.\[mask-image\:linear-gradient\(to_right\2c transparent_8px\2c _theme\(colors\.white\/\.7\)_64px\2c _theme\(colors\.white\)_50\%\2c _theme\(colors\.white\/\.7\)_calc\(100\%-64px\)\2c _transparent_calc\(100\%-8px\)\)\]{ - -webkit-mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); - mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); -} - -/* See Alpine.js: https://github.com/alpinejs/alpine#x-cloak */ - -[x-cloak=""] { - display: none; -} - -/* Custom styles */ - -.form-input:focus, -.form-textarea:focus, -.form-multiselect:focus, -.form-select:focus, -.form-checkbox:focus, -.form-radio:focus{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -/* Hamburger button */ - -.hamburger svg > *:nth-child(1), -.hamburger svg > *:nth-child(2), -.hamburger svg > *:nth-child(3) { - transform-origin: center; - transform: rotate(0deg); -} - -.hamburger svg > *:nth-child(1) { - transition: - y 0.1s 0.25s ease-in, - transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), - opacity 0.1s ease-in; -} - -.hamburger svg > *:nth-child(2) { - transition: transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19); -} - -.hamburger svg > *:nth-child(3) { - transition: - y 0.1s 0.25s ease-in, - transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), - width 0.1s 0.25s ease-in; -} - -.hamburger.active svg > *:nth-child(1) { - opacity: 0; - y: 11; - transform: rotate(225deg); - transition: - y 0.1s ease-out, - transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), - opacity 0.1s 0.12s ease-out; -} - -.hamburger.active svg > *:nth-child(2) { - transform: rotate(225deg); - transition: transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1); -} - -.hamburger.active svg > *:nth-child(3) { - y: 11; - transform: rotate(135deg); - transition: - y 0.1s ease-out, - transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), - width 0.1s ease-out; -} - -/* Typography */ - -.h1{ - font-size: 3.25rem; - line-height: 1.2; - letter-spacing: -0.017em; - font-weight: 700; -} - -.h2{ - font-size: 2.5rem; - line-height: 1.25; - letter-spacing: -0.017em; - font-weight: 700; -} - -.h3{ - font-size: 2rem; - line-height: 1.3125; - letter-spacing: -0.017em; - font-weight: 700; -} - -.h4{ - font-size: 1.5rem; - line-height: 1.415; - letter-spacing: -0.017em; - font-weight: 700; -} - -@media (min-width: 768px) { - .h1{ - font-size: 3.75rem; - line-height: 1.1666; - letter-spacing: -0.017em; - } - - .h2{ - font-size: 3.25rem; - line-height: 1.2; - letter-spacing: -0.017em; - } - - .h3{ - font-size: 2.5rem; - line-height: 1.25; - letter-spacing: -0.017em; - } -} - -/* Buttons */ - -.btn, -.btn-sm{ - display: inline-flex; - align-items: center; - justify-content: center; - border-radius: 0.375rem; - border-width: 1px; - border-color: transparent; - font-size: 0.875rem; - line-height: 1.5715; - font-weight: 500; - letter-spacing: 0em; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.btn{ - padding-left: 1rem; - padding-right: 1rem; - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} - -.btn-sm{ - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; -} - -/* Forms */ - -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-results-button, -input[type="search"]::-webkit-search-results-decoration { - -webkit-appearance: none; -} - -.form-input, -.form-textarea, -.form-multiselect, -.form-select, -.form-checkbox, -.form-radio{ - border-width: 1px; - --tw-border-opacity: 1; - border-color: rgb(228 228 231 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); - --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); - --tw-shadow-color: rgb(0 0 0 / 0.05); - --tw-shadow: var(--tw-shadow-colored); -} - -.form-input:focus, -.form-textarea:focus, -.form-multiselect:focus, -.form-select:focus, -.form-checkbox:focus, -.form-radio:focus{ - --tw-border-opacity: 1; - border-color: rgb(161 161 170 / var(--tw-border-opacity)); -} - -.form-input, -.form-textarea, -.form-multiselect, -.form-select, -.form-checkbox{ - border-radius: 0.25rem; -} - -.form-input, -.form-textarea, -.form-multiselect, -.form-select{ - padding-left: 1rem; - padding-right: 1rem; - padding-top: 0.5rem; - padding-bottom: 0.5rem; - font-size: 0.875rem; - line-height: 1.5715; - --tw-text-opacity: 1; - color: rgb(82 82 91 / var(--tw-text-opacity)); -} - -.form-input::-moz-placeholder, .form-textarea::-moz-placeholder{ - --tw-placeholder-opacity: 1; - color: rgb(161 161 170 / var(--tw-placeholder-opacity)); -} - -.form-input::placeholder, -.form-textarea::placeholder{ - --tw-placeholder-opacity: 1; - color: rgb(161 161 170 / var(--tw-placeholder-opacity)); -} - -.form-select{ - padding-right: 2.5rem; -} - -.form-checkbox, -.form-radio{ - --tw-text-opacity: 1; - color: rgb(39 39 42 / var(--tw-text-opacity)); -} - -.form-checkbox{ - border-radius: 0.125rem; -} - -/* Chrome, Safari and Opera */ - -.no-scrollbar::-webkit-scrollbar { - display: none; -} - -.no-scrollbar { - -ms-overflow-style: none; - /* IE and Edge */ - scrollbar-width: none; - /* Firefox */ -} - -.placeholder\:text-zinc-400::-moz-placeholder{ - --tw-text-opacity: 1; - color: rgb(161 161 170 / var(--tw-text-opacity)); -} - -.placeholder\:text-zinc-400::placeholder{ - --tw-text-opacity: 1; - color: rgb(161 161 170 / var(--tw-text-opacity)); -} - -.before\:pointer-events-none::before{ - content: var(--tw-content); - pointer-events: none; -} - -.before\:absolute::before{ - content: var(--tw-content); - position: absolute; -} - -.before\:inset-0::before{ - content: var(--tw-content); - inset: 0px; -} - -.before\:-top-12::before{ - content: var(--tw-content); - top: -3rem; -} - -.before\:-z-10::before{ - content: var(--tw-content); - z-index: -10; -} - -.before\:h-52::before{ - content: var(--tw-content); - height: 13rem; -} - -.before\:h-80::before{ - content: var(--tw-content); - height: 20rem; -} - -.before\:h-96::before{ - content: var(--tw-content); - height: 24rem; -} - -.before\:w-52::before{ - content: var(--tw-content); - width: 13rem; -} - -.before\:w-96::before{ - content: var(--tw-content); - width: 24rem; -} - -.before\:rounded-full::before{ - content: var(--tw-content); - border-radius: 9999px; -} - -.before\:bg-zinc-900::before{ - content: var(--tw-content); - --tw-bg-opacity: 1; - background-color: rgb(24 24 27 / var(--tw-bg-opacity)); -} - -.before\:bg-gradient-to-b::before{ - content: var(--tw-content); - background-image: linear-gradient(to bottom, var(--tw-gradient-stops)); -} - -.before\:from-zinc-100::before{ - content: var(--tw-content); - --tw-gradient-from: #f4f4f5 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(244 244 245 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.before\:opacity-\[\.08\]::before{ - content: var(--tw-content); - opacity: .08; -} - -.before\:opacity-\[\.15\]::before{ - content: var(--tw-content); - opacity: .15; -} - -.before\:blur-3xl::before{ - content: var(--tw-content); - --tw-blur: blur(64px); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); -} - -.before\:content-\[\'\\0022\'\]::before{ - --tw-content: '\0022'; - content: var(--tw-content); -} - -.after\:pointer-events-none::after{ - content: var(--tw-content); - pointer-events: none; -} - -.after\:absolute::after{ - content: var(--tw-content); - position: absolute; -} - -.after\:right-0::after{ - content: var(--tw-content); - right: 0px; -} - -.after\:top-0::after{ - content: var(--tw-content); - top: 0px; -} - -.after\:top-1\/2::after{ - content: var(--tw-content); - top: 50%; -} - -.after\:hidden::after{ - content: var(--tw-content); - display: none; -} - -.after\:h-8::after{ - content: var(--tw-content); - height: 2rem; -} - -.after\:h-full::after{ - content: var(--tw-content); - height: 100%; -} - -.after\:w-96::after{ - content: var(--tw-content); - width: 24rem; -} - -.after\:w-px::after{ - content: var(--tw-content); - width: 1px; -} - -.after\:-translate-y-1\/2::after{ - content: var(--tw-content); - --tw-translate-y: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.after\:border-l::after{ - content: var(--tw-content); - border-left-width: 1px; -} - -.after\:border-dashed::after{ - content: var(--tw-content); - border-style: dashed; -} - -.after\:border-zinc-300::after{ - content: var(--tw-content); - --tw-border-opacity: 1; - border-color: rgb(212 212 216 / var(--tw-border-opacity)); -} - -.after\:bg-gradient-to-l::after{ - content: var(--tw-content); - background-image: linear-gradient(to left, var(--tw-gradient-stops)); -} - -.after\:from-zinc-800::after{ - content: var(--tw-content); - --tw-gradient-from: #27272a var(--tw-gradient-from-position); - --tw-gradient-to: rgb(39 39 42 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.after\:content-\[\'\\0022\'\]::after{ - --tw-content: '\0022'; - content: var(--tw-content); -} - -.last\:after\:hidden:last-child::after{ - content: var(--tw-content); - display: none; -} - -.hover\:scale-100:hover{ - --tw-scale-x: 1; - --tw-scale-y: 1; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.hover\:bg-blue-100:hover{ - --tw-bg-opacity: 1; - background-color: rgb(219 234 254 / var(--tw-bg-opacity)); -} - -.hover\:bg-blue-600:hover{ - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity)); -} - -.hover\:bg-blue-700:hover{ - --tw-bg-opacity: 1; - background-color: rgb(29 78 216 / var(--tw-bg-opacity)); -} - -.hover\:bg-gray-50:hover{ - --tw-bg-opacity: 1; - background-color: rgb(249 250 251 / var(--tw-bg-opacity)); -} - -.hover\:bg-green-100:hover{ - --tw-bg-opacity: 1; - background-color: rgb(220 252 231 / var(--tw-bg-opacity)); -} - -.hover\:bg-green-600:hover{ - --tw-bg-opacity: 1; - background-color: rgb(22 163 74 / var(--tw-bg-opacity)); -} - -.hover\:bg-green-700:hover{ - --tw-bg-opacity: 1; - background-color: rgb(21 128 61 / var(--tw-bg-opacity)); -} - -.hover\:bg-neutral-100:hover{ - --tw-bg-opacity: 1; - background-color: rgb(245 245 245 / var(--tw-bg-opacity)); -} - -.hover\:bg-neutral-800:hover{ - --tw-bg-opacity: 1; - background-color: rgb(38 38 38 / var(--tw-bg-opacity)); -} - -.hover\:bg-neutral-900:hover{ - --tw-bg-opacity: 1; - background-color: rgb(23 23 23 / var(--tw-bg-opacity)); -} - -.hover\:bg-red-100:hover{ - --tw-bg-opacity: 1; - background-color: rgb(254 226 226 / var(--tw-bg-opacity)); -} - -.hover\:bg-red-600:hover{ - --tw-bg-opacity: 1; - background-color: rgb(220 38 38 / var(--tw-bg-opacity)); -} - -.hover\:bg-red-700:hover{ - --tw-bg-opacity: 1; - background-color: rgb(185 28 28 / var(--tw-bg-opacity)); -} - -.hover\:bg-yellow-100:hover{ - --tw-bg-opacity: 1; - background-color: rgb(254 249 195 / var(--tw-bg-opacity)); -} - -.hover\:bg-yellow-500:hover{ - --tw-bg-opacity: 1; - background-color: rgb(234 179 8 / var(--tw-bg-opacity)); -} - -.hover\:bg-yellow-700:hover{ - --tw-bg-opacity: 1; - background-color: rgb(161 98 7 / var(--tw-bg-opacity)); -} - -.hover\:bg-zinc-50:hover{ - --tw-bg-opacity: 1; - background-color: rgb(250 250 250 / var(--tw-bg-opacity)); -} - -.hover\:bg-zinc-800:hover{ - --tw-bg-opacity: 1; - background-color: rgb(39 39 42 / var(--tw-bg-opacity)); -} - -.hover\:text-blue-600:hover{ - --tw-text-opacity: 1; - color: rgb(37 99 235 / var(--tw-text-opacity)); -} - -.hover\:text-green-600:hover{ - --tw-text-opacity: 1; - color: rgb(22 163 74 / var(--tw-text-opacity)); -} - -.hover\:text-neutral-600:hover{ - --tw-text-opacity: 1; - color: rgb(82 82 82 / var(--tw-text-opacity)); -} - -.hover\:text-neutral-700:hover{ - --tw-text-opacity: 1; - color: rgb(64 64 64 / var(--tw-text-opacity)); -} - -.hover\:text-neutral-900:hover{ - --tw-text-opacity: 1; - color: rgb(23 23 23 / var(--tw-text-opacity)); -} - -.hover\:text-red-600:hover{ - --tw-text-opacity: 1; - color: rgb(220 38 38 / var(--tw-text-opacity)); -} - -.hover\:text-white:hover{ - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.hover\:text-yellow-700:hover{ - --tw-text-opacity: 1; - color: rgb(161 98 7 / var(--tw-text-opacity)); -} - -.hover\:text-zinc-300:hover{ - --tw-text-opacity: 1; - color: rgb(212 212 216 / var(--tw-text-opacity)); -} - -.hover\:text-zinc-800:hover{ - --tw-text-opacity: 1; - color: rgb(39 39 42 / var(--tw-text-opacity)); -} - -.hover\:text-zinc-900:hover{ - --tw-text-opacity: 1; - color: rgb(24 24 27 / var(--tw-text-opacity)); -} - -.hover\:underline:hover{ - text-decoration-line: underline; -} - -.hover\:opacity-100:hover{ - opacity: 1; -} - -.focus\:border-black:focus{ - --tw-border-opacity: 1; - border-color: rgb(0 0 0 / var(--tw-border-opacity)); -} - -.focus\:border-gray-300:focus{ - --tw-border-opacity: 1; - border-color: rgb(209 213 219 / var(--tw-border-opacity)); -} - -.focus\:border-gray-500:focus{ - --tw-border-opacity: 1; - border-color: rgb(107 114 128 / var(--tw-border-opacity)); -} - -.focus\:border-indigo-300:focus{ - --tw-border-opacity: 1; - border-color: rgb(165 180 252 / var(--tw-border-opacity)); -} - -.focus\:border-transparent:focus{ - border-color: transparent; -} - -.focus\:border-zinc-300:focus{ - --tw-border-opacity: 1; - border-color: rgb(212 212 216 / var(--tw-border-opacity)); -} - -.focus\:bg-gray-200:focus{ - --tw-bg-opacity: 1; - background-color: rgb(229 231 235 / var(--tw-bg-opacity)); -} - -.focus\:bg-white:focus{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.focus\:outline-none:focus{ - outline: 2px solid transparent; - outline-offset: 2px; -} - -.focus\:ring:focus{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus\:ring-0:focus{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus\:ring-1:focus{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus\:ring-2:focus{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus\:ring-black:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(0 0 0 / var(--tw-ring-opacity)); -} - -.focus\:ring-blue-100:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(219 234 254 / var(--tw-ring-opacity)); -} - -.focus\:ring-blue-700:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(29 78 216 / var(--tw-ring-opacity)); -} - -.focus\:ring-gray-500:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity)); -} - -.focus\:ring-gray-700:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(55 65 81 / var(--tw-ring-opacity)); -} - -.focus\:ring-green-100:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(220 252 231 / var(--tw-ring-opacity)); -} - -.focus\:ring-green-700:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(21 128 61 / var(--tw-ring-opacity)); -} - -.focus\:ring-indigo-200:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(199 210 254 / var(--tw-ring-opacity)); -} - -.focus\:ring-neutral-100:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(245 245 245 / var(--tw-ring-opacity)); -} - -.focus\:ring-neutral-200\/60:focus{ - --tw-ring-color: rgb(229 229 229 / 0.6); -} - -.focus\:ring-neutral-400:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(163 163 163 / var(--tw-ring-opacity)); -} - -.focus\:ring-neutral-900:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(23 23 23 / var(--tw-ring-opacity)); -} - -.focus\:ring-red-100:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(254 226 226 / var(--tw-ring-opacity)); -} - -.focus\:ring-red-700:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(185 28 28 / var(--tw-ring-opacity)); -} - -.focus\:ring-yellow-100:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(254 249 195 / var(--tw-ring-opacity)); -} - -.focus\:ring-yellow-700:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(161 98 7 / var(--tw-ring-opacity)); -} - -.focus\:ring-opacity-50:focus{ - --tw-ring-opacity: 0.5; -} - -.focus\:ring-offset-0:focus{ - --tw-ring-offset-width: 0px; -} - -.focus\:ring-offset-2:focus{ - --tw-ring-offset-width: 2px; -} - -.focus-visible\:outline-none:focus-visible{ - outline: 2px solid transparent; - outline-offset: 2px; -} - -.focus-visible\:ring-2:focus-visible{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus-visible\:ring-offset-2:focus-visible{ - --tw-ring-offset-width: 2px; -} - -.active\:bg-white:active{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.disabled\:pointer-events-none:disabled{ - pointer-events: none; -} - -.disabled\:cursor-not-allowed:disabled{ - cursor: not-allowed; -} - -.disabled\:opacity-50:disabled{ - opacity: 0.5; -} - -.group:hover .group-hover\:visible{ - visibility: visible; -} - -.group:hover .group-hover\:mx-1{ - margin-left: 0.25rem; - margin-right: 0.25rem; -} - -.group:hover .group-hover\:w-12{ - width: 3rem; -} - -.group:hover .group-hover\:scale-110{ - --tw-scale-x: 1.1; - --tw-scale-y: 1.1; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.group:hover .group-hover\:\[animation-play-state\:paused\]{ - animation-play-state: paused; -} - -.peer:disabled ~ .peer-disabled\:cursor-not-allowed{ - cursor: not-allowed; -} - -.peer:disabled ~ .peer-disabled\:opacity-70{ - opacity: 0.7; -} - -@supports (overflow:clip){ - .supports-\[overflow\:clip\]\:overflow-clip{ - overflow: clip; - } -} - -@media not all and (min-width: 1024px){ - .max-lg\:w-32{ - width: 8rem; - } - - .max-lg\:after\:hidden::after{ - content: var(--tw-content); - display: none; - } -} - -@media not all and (min-width: 640px){ - .max-sm\:order-1{ - order: 1; - } -} - -@media (min-width: 640px){ - .sm\:col-span-2{ - grid-column: span 2 / span 2; - } - - .sm\:col-span-6{ - grid-column: span 6 / span 6; - } - - .sm\:mb-0{ - margin-bottom: 0px; - } - - .sm\:inline-flex{ - display: inline-flex; - } - - .sm\:h-auto{ - height: auto; - } - - .sm\:max-w-lg{ - max-width: 32rem; - } - - .sm\:max-w-none{ - max-width: none; - } - - .sm\:grid-cols-12{ - grid-template-columns: repeat(12, minmax(0, 1fr)); - } - - .sm\:grid-cols-2{ - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .sm\:flex-row{ - flex-direction: row; - } - - .sm\:justify-center{ - justify-content: center; - } - - .sm\:justify-between{ - justify-content: space-between; - } - - .sm\:gap-4{ - gap: 1rem; - } - - .sm\:space-x-2 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(0.5rem * var(--tw-space-x-reverse)); - margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); - } - - .sm\:space-x-4 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(1rem * var(--tw-space-x-reverse)); - margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); - } - - .sm\:space-y-0 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0px * var(--tw-space-y-reverse)); - } - - .sm\:rounded-lg{ - border-radius: 0.5rem; - } - - .sm\:object-contain{ - -o-object-fit: contain; - object-fit: contain; - } - - .sm\:px-6{ - padding-left: 1.5rem; - padding-right: 1.5rem; - } -} - -@media (min-width: 768px){ - .md\:top-6{ - top: 1.5rem; - } - - .md\:col-span-3{ - grid-column: span 3 / span 3; - } - - .md\:-mx-5{ - margin-left: -1.25rem; - margin-right: -1.25rem; - } - - .md\:mb-0{ - margin-bottom: 0px; - } - - .md\:max-w-4xl{ - max-width: 56rem; - } - - .md\:max-w-none{ - max-width: none; - } - - .md\:grid-cols-2{ - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .md\:grid-cols-3{ - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .md\:grid-cols-4{ - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - - .md\:flex-row{ - flex-direction: row; - } - - .md\:justify-start{ - justify-content: flex-start; - } - - .md\:gap-0{ - gap: 0px; - } - - .md\:gap-4{ - gap: 1rem; - } - - .md\:gap-6{ - gap: 1.5rem; - } - - .md\:px-5{ - padding-left: 1.25rem; - padding-right: 1.25rem; - } - - .md\:py-12{ - padding-top: 3rem; - padding-bottom: 3rem; - } - - .md\:py-20{ - padding-top: 5rem; - padding-bottom: 5rem; - } - - .md\:pb-16{ - padding-bottom: 4rem; - } - - .md\:pb-20{ - padding-bottom: 5rem; - } - - .md\:pt-40{ - padding-top: 10rem; - } - - .md\:text-3xl{ - font-size: 2rem; - line-height: 1.3125; - letter-spacing: -0.017em; - } - - .md\:text-4xl{ - font-size: 2.5rem; - line-height: 1.25; - letter-spacing: -0.017em; - } - - .md\:text-5xl{ - font-size: 3.25rem; - line-height: 1.2; - letter-spacing: -0.017em; - } - - .md\:after\:block::after{ - content: var(--tw-content); - display: block; - } -} - -@media (min-width: 1024px){ - .lg\:col-span-2{ - grid-column: span 2 / span 2; - } - - .lg\:col-span-6{ - grid-column: span 6 / span 6; - } - - .lg\:mt-32{ - margin-top: 8rem; - } - - .lg\:flex{ - display: flex; - } - - .lg\:min-w-\[524px\]{ - min-width: 524px; - } - - .lg\:max-w-6xl{ - max-width: 72rem; - } - - .lg\:max-w-none{ - max-width: none; - } - - .lg\:grid-cols-3{ - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .lg\:gap-16{ - gap: 4rem; - } - - .lg\:gap-8{ - gap: 2rem; - } - - .lg\:space-x-12 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(3rem * var(--tw-space-x-reverse)); - margin-left: calc(3rem * calc(1 - var(--tw-space-x-reverse))); - } - - .lg\:space-y-0 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0px * var(--tw-space-y-reverse)); - } - - .lg\:p-24{ - padding: 6rem; - } - - .lg\:px-5{ - padding-left: 1.25rem; - padding-right: 1.25rem; - } - - .lg\:text-2xl{ - font-size: 1.5rem; - line-height: 1.415; - letter-spacing: -0.017em; - } - - .lg\:text-3xl{ - font-size: 2rem; - line-height: 1.3125; - letter-spacing: -0.017em; - } - - .lg\:text-xl{ - font-size: 1.25rem; - line-height: 1.5; - letter-spacing: -0.017em; - } -} - -@media (min-width: 1280px){ - .xl\:space-x-24 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(6rem * var(--tw-space-x-reverse)); - margin-left: calc(6rem * calc(1 - var(--tw-space-x-reverse))); - } -} - -.\[\&\:\:-moz-range-progress\]\:rounded-full::-moz-range-progress{ - border-radius: 9999px; -} - -.\[\&\:\:-moz-range-progress\]\:bg-blue-600::-moz-range-progress{ - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-moz-range-progress\]\:bg-white::-moz-range-progress{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-moz-range-progress\]\:bg-opacity-80::-moz-range-progress{ - --tw-bg-opacity: 0.8; -} - -.\[\&\:\:-moz-range-thumb\]\:h-1\.5::-moz-range-thumb{ - height: 0.375rem; -} - -.\[\&\:\:-moz-range-thumb\]\:h-2::-moz-range-thumb{ - height: 0.5rem; -} - -.\[\&\:\:-moz-range-thumb\]\:w-1\.5::-moz-range-thumb{ - width: 0.375rem; -} - -.\[\&\:\:-moz-range-thumb\]\:w-2::-moz-range-thumb{ - width: 0.5rem; -} - -.\[\&\:\:-moz-range-thumb\]\:appearance-none::-moz-range-thumb{ - -moz-appearance: none; - appearance: none; -} - -.\[\&\:\:-moz-range-thumb\]\:rounded-full::-moz-range-thumb{ - border-radius: 9999px; -} - -.\[\&\:\:-moz-range-thumb\]\:border-0::-moz-range-thumb{ - border-width: 0px; -} - -.\[\&\:\:-moz-range-thumb\]\:bg-white::-moz-range-thumb{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-moz-range-track\]\:rounded-full::-moz-range-track{ - border-radius: 9999px; -} - -.\[\&\:\:-moz-range-track\]\:bg-neutral-200::-moz-range-track{ - --tw-bg-opacity: 1; - background-color: rgb(229 229 229 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-ms-fill-lower\]\:rounded-full::-ms-fill-lower{ - border-radius: 9999px; -} - -.\[\&\:\:-ms-fill-lower\]\:bg-blue-600::-ms-fill-lower{ - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-ms-fill-lower\]\:bg-white::-ms-fill-lower{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-ms-fill-lower\]\:bg-opacity-80::-ms-fill-lower{ - --tw-bg-opacity: 0.8; -} - -.\[\&\:\:-ms-thumb\]\:h-1\.5::-ms-thumb{ - height: 0.375rem; -} - -.\[\&\:\:-ms-thumb\]\:h-2::-ms-thumb{ - height: 0.5rem; -} - -.\[\&\:\:-ms-thumb\]\:w-1\.5::-ms-thumb{ - width: 0.375rem; -} - -.\[\&\:\:-ms-thumb\]\:w-2::-ms-thumb{ - width: 0.5rem; -} - -.\[\&\:\:-ms-thumb\]\:appearance-none::-ms-thumb{ - appearance: none; -} - -.\[\&\:\:-ms-thumb\]\:rounded-full::-ms-thumb{ - border-radius: 9999px; -} - -.\[\&\:\:-ms-thumb\]\:border-0::-ms-thumb{ - border-width: 0px; -} - -.\[\&\:\:-ms-thumb\]\:bg-white::-ms-thumb{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-ms-track\]\:rounded-full::-ms-track{ - border-radius: 9999px; -} - -.\[\&\:\:-ms-track\]\:bg-neutral-200::-ms-track{ - --tw-bg-opacity: 1; - background-color: rgb(229 229 229 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-webkit-slider-runnable-track\]\:overflow-hidden::-webkit-slider-runnable-track{ - overflow: hidden; -} - -.\[\&\:\:-webkit-slider-runnable-track\]\:rounded-full::-webkit-slider-runnable-track{ - border-radius: 9999px; -} - -.\[\&\:\:-webkit-slider-runnable-track\]\:bg-white::-webkit-slider-runnable-track{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-webkit-slider-runnable-track\]\:bg-opacity-30::-webkit-slider-runnable-track{ - --tw-bg-opacity: 0.3; -} - -.\[\&\:\:-webkit-slider-thumb\]\:h-1\.5::-webkit-slider-thumb{ - height: 0.375rem; -} - -.\[\&\:\:-webkit-slider-thumb\]\:h-2::-webkit-slider-thumb{ - height: 0.5rem; -} - -.\[\&\:\:-webkit-slider-thumb\]\:w-1\.5::-webkit-slider-thumb{ - width: 0.375rem; -} - -.\[\&\:\:-webkit-slider-thumb\]\:w-2::-webkit-slider-thumb{ - width: 0.5rem; -} - -.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{ - -webkit-appearance: none; - appearance: none; -} - -.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{ - border-radius: 9999px; -} - -.\[\&\:\:-webkit-slider-thumb\]\:border-0::-webkit-slider-thumb{ - border-width: 0px; -} - -.\[\&\:\:-webkit-slider-thumb\]\:bg-white::-webkit-slider-thumb{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.\[\&\:\:-webkit-slider-thumb\]\:shadow-\[-995px_0px_0px_990px_\#2463eb\]::-webkit-slider-thumb{ - --tw-shadow: -995px 0px 0px 990px #2463eb; - --tw-shadow-colored: -995px 0px 0px 990px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.\[\&\:\:-webkit-slider-thumb\]\:shadow-\[-995px_0px_0px_990px_rgba\(255\2c _255\2c _255\2c _0\.8\)\]::-webkit-slider-thumb{ - --tw-shadow: -995px 0px 0px 990px rgba(255, 255, 255, 0.8); - --tw-shadow-colored: -995px 0px 0px 990px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.\[\&\>div\]\:mx-3>div{ - margin-left: 0.75rem; - margin-right: 0.75rem; -} - -.\[\&_\.active-breadcrumb\]\:font-medium .active-breadcrumb{ - font-weight: 500; -} - -.\[\&_\.active-breadcrumb\]\:text-neutral-600 .active-breadcrumb{ - --tw-text-opacity: 1; - color: rgb(82 82 82 / var(--tw-text-opacity)); -} diff --git a/pkg/nebula/assets/fonts/ZTBrosOskon90s-BoldSemExp.woff b/pkg/nebula/assets/fonts/ZTBrosOskon90s-BoldSemExp.woff deleted file mode 100644 index 6d596368c2746283b5767d27c2c41233b0c0bb64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52736 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%0Ab=tjZi5YrEWi6rMNgqQM^6ubTrO# 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

    S@b1_*q@XLuxmy7!iqqMO_e` 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

    E6R$|@Vjs>v) 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ºzA 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 A$^ZZW diff --git a/pkg/nebula/assets/fonts/ZTBrosOskon90s-BoldSemExpIta.woff b/pkg/nebula/assets/fonts/ZTBrosOskon90s-BoldSemExpIta.woff deleted file mode 100644 index 638667898d0241b5f9d4837f7753a25e5adc499c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56220 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∾u}&8 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 WUL8|Bp%dZqoEr}tb+;0 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 Iqd5Qo0JA*Iga7~l diff --git a/pkg/nebula/assets/js/alpin-focus.min.js b/pkg/nebula/assets/js/alpin-focus.min.js deleted file mode 100644 index 5a2d18be2..000000000 --- a/pkg/nebula/assets/js/alpin-focus.min.js +++ /dev/null @@ -1,15 +0,0 @@ -(()=>{var _=["input","select","textarea","a[href]","button","[tabindex]:not(slot)","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable="false"])',"details>summary:first-of-type","details"],k=_.join(","),K=typeof Element>"u",N=K?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,B=!K&&Element.prototype.getRootNode?function(i){return i.getRootNode()}:function(i){return i.ownerDocument},V=function(e,t,a){var n=Array.prototype.slice.apply(e.querySelectorAll(k));return t&&N.call(e,k)&&n.unshift(e),n=n.filter(a),n},$=function i(e,t,a){for(var n=[],r=Array.from(e);r.length;){var s=r.shift();if(s.tagName==="SLOT"){var l=s.assignedElements(),m=l.length?l:s.children,p=i(m,!0,a);a.flatten?n.push.apply(n,p):n.push({scope:s,candidates:p})}else{var v=N.call(s,k);v&&a.filter(s)&&(t||!e.includes(s))&&n.push(s);var h=s.shadowRoot||typeof a.getShadowRoot=="function"&&a.getShadowRoot(s),y=!a.shadowRootFilter||a.shadowRootFilter(s);if(h&&y){var w=i(h===!0?s.children:h.children,!0,a);a.flatten?n.push.apply(n,w):n.push({scope:s,candidates:w})}else r.unshift.apply(r,s.children)}}return n},Y=function(e,t){return e.tabIndex<0&&(t||/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||e.isContentEditable)&&isNaN(parseInt(e.getAttribute("tabindex"),10))?0:e.tabIndex},se=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},Z=function(e){return e.tagName==="INPUT"},ce=function(e){return Z(e)&&e.type==="hidden"},le=function(e){var t=e.tagName==="DETAILS"&&Array.prototype.slice.apply(e.children).some(function(a){return a.tagName==="SUMMARY"});return t},fe=function(e,t){for(var a=0;asummary:first-of-type"),s=r?e.parentElement:e;if(N.call(s,"details:not([open]) *"))return!0;var l=B(e).host,m=l?.ownerDocument.contains(l)||e.ownerDocument.contains(e);if(!a||a==="full"){if(typeof n=="function"){for(var p=e;e;){var v=e.parentElement,h=B(e);if(v&&!v.shadowRoot&&n(v)===!0)return W(e);e.assignedSlot?e=e.assignedSlot:!v&&h!==e.ownerDocument?e=h.host:e=v}e=p}if(m)return!e.getClientRects().length}else if(a==="non-zero-area")return W(e);return!1},pe=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName==="FIELDSET"&&t.disabled){for(var a=0;a=0)},me=function i(e){var t=[],a=[];return e.forEach(function(n,r){var s=!!n.scope,l=s?n.scope:n,m=Y(l,s),p=s?i(n.candidates):l;m===0?s?t.push.apply(t,p):t.push(l):a.push({documentOrder:r,tabIndex:m,item:n,isScope:s,content:p})}),a.sort(se).reduce(function(n,r){return r.isScope?n.push.apply(n,r.content):n.push(r.content),n},[]).concat(t)},z=function(e,t){t=t||{};var a;return t.getShadowRoot?a=$([e],t.includeContainer,{filter:G.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:ge}):a=V(e,t.includeContainer,G.bind(null,t)),me(a)},x=function(e,t){t=t||{};var a;return t.getShadowRoot?a=$([e],t.includeContainer,{filter:I.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):a=V(e,t.includeContainer,I.bind(null,t)),a},A=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return N.call(e,k)===!1?!1:G(t,e)},ye=_.concat("iframe").join(","),R=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return N.call(e,ye)===!1?!1:I(t,e)};function Q(i,e){var t=Object.keys(i);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(i);e&&(a=a.filter(function(n){return Object.getOwnPropertyDescriptor(i,n).enumerable})),t.push.apply(t,a)}return t}function X(i){for(var e=1;e0){var a=i[i.length-1];a!==t&&a.pause()}var n=i.indexOf(t);n===-1||i.splice(n,1),i.push(t)},deactivateTrap:function(t){var a=i.indexOf(t);a!==-1&&i.splice(a,1),i.length>0&&i[i.length-1].unpause()}}}(),Te=function(e){return e.tagName&&e.tagName.toLowerCase()==="input"&&typeof e.select=="function"},Fe=function(e){return e.key==="Escape"||e.key==="Esc"||e.keyCode===27},Se=function(e){return e.key==="Tab"||e.keyCode===9},ee=function(e){return setTimeout(e,0)},te=function(e,t){var a=-1;return e.every(function(n,r){return t(n)?(a=r,!1):!0}),a},O=function(e){for(var t=arguments.length,a=new Array(t>1?t-1:0),n=1;n1?c-1:0),f=1;f=0)o=a.activeElement;else{var u=r.tabbableGroups[0],c=u&&u.firstTabbableNode;o=c||p("fallbackFocus")}if(!o)throw new Error("Your focus-trap needs to have at least one focusable element");return o},h=function(){if(r.containerGroups=r.containers.map(function(o){var u=z(o,n.tabbableOptions),c=x(o,n.tabbableOptions);return{container:o,tabbableNodes:u,focusableNodes:c,firstTabbableNode:u.length>0?u[0]:null,lastTabbableNode:u.length>0?u[u.length-1]:null,nextTabbableNode:function(f){var g=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,F=c.findIndex(function(E){return E===f});if(!(F<0))return g?c.slice(F+1).find(function(E){return A(E,n.tabbableOptions)}):c.slice(0,F).reverse().find(function(E){return A(E,n.tabbableOptions)})}}}),r.tabbableGroups=r.containerGroups.filter(function(o){return o.tabbableNodes.length>0}),r.tabbableGroups.length<=0&&!p("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times")},y=function d(o){if(o!==!1&&o!==a.activeElement){if(!o||!o.focus){d(v());return}o.focus({preventScroll:!!n.preventScroll}),r.mostRecentlyFocusedNode=o,Te(o)&&o.select()}},w=function(o){var u=p("setReturnFocus",o);return u||(u===!1?!1:o)},S=function(o){var u=L(o);if(!(m(u)>=0)){if(O(n.clickOutsideDeactivates,o)){s.deactivate({returnFocus:n.returnFocusOnDeactivate&&!R(u,n.tabbableOptions)});return}O(n.allowOutsideClick,o)||o.preventDefault()}},D=function(o){var u=L(o),c=m(u)>=0;c||u instanceof Document?c&&(r.mostRecentlyFocusedNode=u):(o.stopImmediatePropagation(),y(r.mostRecentlyFocusedNode||v()))},T=function(o){var u=L(o);h();var c=null;if(r.tabbableGroups.length>0){var b=m(u),f=b>=0?r.containerGroups[b]:void 0;if(b<0)o.shiftKey?c=r.tabbableGroups[r.tabbableGroups.length-1].lastTabbableNode:c=r.tabbableGroups[0].firstTabbableNode;else if(o.shiftKey){var g=te(r.tabbableGroups,function(P){var j=P.firstTabbableNode;return u===j});if(g<0&&(f.container===u||R(u,n.tabbableOptions)&&!A(u,n.tabbableOptions)&&!f.nextTabbableNode(u,!1))&&(g=b),g>=0){var F=g===0?r.tabbableGroups.length-1:g-1,E=r.tabbableGroups[F];c=E.lastTabbableNode}}else{var C=te(r.tabbableGroups,function(P){var j=P.lastTabbableNode;return u===j});if(C<0&&(f.container===u||R(u,n.tabbableOptions)&&!A(u,n.tabbableOptions)&&!f.nextTabbableNode(u))&&(C=b),C>=0){var oe=C===r.tabbableGroups.length-1?0:C+1,ue=r.tabbableGroups[oe];c=ue.firstTabbableNode}}}else c=p("fallbackFocus");c&&(o.preventDefault(),y(c))},M=function(o){if(Fe(o)&&O(n.escapeDeactivates,o)!==!1){o.preventDefault(),s.deactivate();return}if(Se(o)){T(o);return}},q=function(o){var u=L(o);m(u)>=0||O(n.clickOutsideDeactivates,o)||O(n.allowOutsideClick,o)||(o.preventDefault(),o.stopImmediatePropagation())},H=function(){if(r.active)return J.activateTrap(s),r.delayInitialFocusTimer=n.delayInitialFocus?ee(function(){y(v())}):y(v()),a.addEventListener("focusin",D,!0),a.addEventListener("mousedown",S,{capture:!0,passive:!1}),a.addEventListener("touchstart",S,{capture:!0,passive:!1}),a.addEventListener("click",q,{capture:!0,passive:!1}),a.addEventListener("keydown",M,{capture:!0,passive:!1}),s},U=function(){if(r.active)return a.removeEventListener("focusin",D,!0),a.removeEventListener("mousedown",S,!0),a.removeEventListener("touchstart",S,!0),a.removeEventListener("click",q,!0),a.removeEventListener("keydown",M,!0),s};return s={get active(){return r.active},get paused(){return r.paused},activate:function(o){if(r.active)return this;var u=l(o,"onActivate"),c=l(o,"onPostActivate"),b=l(o,"checkCanFocusTrap");b||h(),r.active=!0,r.paused=!1,r.nodeFocusedBeforeActivation=a.activeElement,u&&u();var f=function(){b&&h(),H(),c&&c()};return b?(b(r.containers.concat()).then(f,f),this):(f(),this)},deactivate:function(o){if(!r.active)return this;var u=X({onDeactivate:n.onDeactivate,onPostDeactivate:n.onPostDeactivate,checkCanReturnFocus:n.checkCanReturnFocus},o);clearTimeout(r.delayInitialFocusTimer),r.delayInitialFocusTimer=void 0,U(),r.active=!1,r.paused=!1,J.deactivateTrap(s);var c=l(u,"onDeactivate"),b=l(u,"onPostDeactivate"),f=l(u,"checkCanReturnFocus"),g=l(u,"returnFocus","returnFocusOnDeactivate");c&&c();var F=function(){ee(function(){g&&y(w(r.nodeFocusedBeforeActivation)),b&&b()})};return g&&f?(f(w(r.nodeFocusedBeforeActivation)).then(F,F),this):(F(),this)},pause:function(){return r.paused||!r.active?this:(r.paused=!0,U(),this)},unpause:function(){return!r.paused||!r.active?this:(r.paused=!1,h(),H(),this)},updateContainerElements:function(o){var u=[].concat(o).filter(Boolean);return r.containers=u.map(function(c){return typeof c=="string"?a.querySelector(c):c}),r.active&&h(),this}},s.updateContainerElements(e),s};function ne(i){let e,t;window.addEventListener("focusin",()=>{e=t,t=document.activeElement}),i.magic("focus",a=>{let n=a;return{__noscroll:!1,__wrapAround:!1,within(r){return n=r,this},withoutScrolling(){return this.__noscroll=!0,this},noscroll(){return this.__noscroll=!0,this},withWrapAround(){return this.__wrapAround=!0,this},wrap(){return this.withWrapAround()},focusable(r){return R(r)},previouslyFocused(){return e},lastFocused(){return e},focused(){return t},focusables(){return Array.isArray(n)?n:x(n,{displayCheck:"none"})},all(){return this.focusables()},isFirst(r){let s=this.all();return s[0]&&s[0].isSameNode(r)},isLast(r){let s=this.all();return s.length&&s.slice(-1)[0].isSameNode(r)},getFirst(){return this.all()[0]},getLast(){return this.all().slice(-1)[0]},getNext(){let r=this.all(),s=document.activeElement;if(r.indexOf(s)!==-1)return this.__wrapAround&&r.indexOf(s)===r.length-1?r[0]:r[r.indexOf(s)+1]},getPrevious(){let r=this.all(),s=document.activeElement;if(r.indexOf(s)!==-1)return this.__wrapAround&&r.indexOf(s)===0?r.slice(-1)[0]:r[r.indexOf(s)-1]},first(){this.focus(this.getFirst())},last(){this.focus(this.getLast())},next(){this.focus(this.getNext())},previous(){this.focus(this.getPrevious())},prev(){return this.previous()},focus(r){r&&setTimeout(()=>{r.hasAttribute("tabindex")||r.setAttribute("tabindex","0"),r.focus({preventScroll:this.__noscroll})})}}}),i.directive("trap",i.skipDuringClone((a,{expression:n,modifiers:r},{effect:s,evaluateLater:l,cleanup:m})=>{let p=l(n),v=!1,h={escapeDeactivates:!1,allowOutsideClick:!0,fallbackFocus:()=>a};if(r.includes("noautofocus"))h.initialFocus=!1;else{let T=a.querySelector("[autofocus]");T&&(h.initialFocus=T)}let y=re(a,h),w=()=>{},S=()=>{},D=()=>{w(),w=()=>{},S(),S=()=>{},y.deactivate({returnFocus:!r.includes("noreturn")})};s(()=>p(T=>{v!==T&&(T&&!v&&(r.includes("noscroll")&&(S=Ee()),r.includes("inert")&&(w=ae(a)),setTimeout(()=>{y.activate()},15)),!T&&v&&D(),v=!!T)})),m(D)},(a,{expression:n,modifiers:r},{evaluate:s})=>{r.includes("inert")&&s(n)&&ae(a)}))}function ae(i){let e=[];return ie(i,t=>{let a=t.hasAttribute("aria-hidden");t.setAttribute("aria-hidden","true"),e.push(()=>a||t.removeAttribute("aria-hidden"))}),()=>{for(;e.length;)e.pop()()}}function ie(i,e){i.isSameNode(document.body)||!i.parentNode||Array.from(i.parentNode.children).forEach(t=>{t.isSameNode(i)?ie(i.parentNode,e):e(t)})}function Ee(){let i=document.documentElement.style.overflow,e=document.documentElement.style.paddingRight,t=window.innerWidth-document.documentElement.clientWidth;return document.documentElement.style.overflow="hidden",document.documentElement.style.paddingRight=`${t}px`,()=>{document.documentElement.style.overflow=i,document.documentElement.style.paddingRight=e}}document.addEventListener("alpine:init",()=>{window.Alpine.plugin(ne)});})(); -/*! Bundled license information: - -tabbable/dist/index.esm.js: - (*! - * tabbable 5.3.3 - * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE - *) - -focus-trap/dist/focus-trap.esm.js: - (*! - * focus-trap 6.9.4 - * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE - *) -*/ diff --git a/pkg/nebula/assets/js/alpine.min.js b/pkg/nebula/assets/js/alpine.min.js deleted file mode 100644 index 2ca48278f..000000000 --- a/pkg/nebula/assets/js/alpine.min.js +++ /dev/null @@ -1,5 +0,0 @@ -(()=>{var rt=!1,nt=!1,U=[],it=-1;function qt(e){Cn(e)}function Cn(e){U.includes(e)||U.push(e),Tn()}function Ee(e){let t=U.indexOf(e);t!==-1&&t>it&&U.splice(t,1)}function Tn(){!nt&&!rt&&(rt=!0,queueMicrotask(Rn))}function Rn(){rt=!1,nt=!0;for(let e=0;ee.effect(t,{scheduler:r=>{ot?qt(r):r()}}),st=e.raw}function at(e){D=e}function Gt(e){let t=()=>{};return[n=>{let i=D(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),L(i))},i},()=>{t()}]}function ve(e,t){let r=!0,n,i=D(()=>{let o=e();JSON.stringify(o),r?n=o:queueMicrotask(()=>{t(o,n),n=o}),r=!1});return()=>L(i)}var Jt=[],Yt=[],Xt=[];function Zt(e){Xt.push(e)}function ee(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Yt.push(t))}function Ae(e){Jt.push(e)}function Oe(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function ct(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}function Qt(e){if(e._x_cleanups)for(;e._x_cleanups.length;)e._x_cleanups.pop()()}var lt=new MutationObserver(pt),ut=!1;function le(){lt.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ut=!0}function ft(){Mn(),lt.disconnect(),ut=!1}var ce=[];function Mn(){let e=lt.takeRecords();ce.push(()=>e.length>0&&pt(e));let t=ce.length;queueMicrotask(()=>{if(ce.length===t)for(;ce.length>0;)ce.shift()()})}function _(e){if(!ut)return e();ft();let t=e();return le(),t}var dt=!1,Se=[];function er(){dt=!0}function tr(){dt=!1,pt(Se),Se=[]}function pt(e){if(dt){Se=Se.concat(e);return}let t=new Set,r=new Set,n=new Map,i=new Map;for(let o=0;os.nodeType===1&&t.add(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.add(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{ct(s,o)}),n.forEach((o,s)=>{Jt.forEach(a=>a(s,o))});for(let o of r)t.has(o)||Yt.forEach(s=>s(o));t.forEach(o=>{o._x_ignoreSelf=!0,o._x_ignore=!0});for(let o of t)r.has(o)||o.isConnected&&(delete o._x_ignoreSelf,delete o._x_ignore,Xt.forEach(s=>s(o)),o._x_ignore=!0,o._x_ignoreSelf=!0);t.forEach(o=>{delete o._x_ignoreSelf,delete o._x_ignore}),t=null,r=null,n=null,i=null}function Ce(e){return F(j(e))}function P(e,t,r){return e._x_dataStack=[t,...j(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function j(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?j(e.host):e.parentNode?j(e.parentNode):[]}function F(e){return new Proxy({objects:e},Nn)}var Nn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?Dn:Reflect.get(e.find(n=>Reflect.has(n,t))||{},t,r)},set({objects:e},t,r,n){let i=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],o=Object.getOwnPropertyDescriptor(i,t);return o?.set&&o?.get?o.set.call(n,r)||!0:Reflect.set(i,t,r)}};function Dn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function Te(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Re(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>Pn(n,i),s=>mt(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function Pn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function mt(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),mt(e[t[0]],t.slice(1),r)}}var rr={};function y(e,t){rr[e]=t}function ue(e,t){return Object.entries(rr).forEach(([r,n])=>{let i=null;function o(){if(i)return i;{let[s,a]=_t(t);return i={interceptor:Re,...s},ee(t,a),i}}Object.defineProperty(e,`$${r}`,{get(){return n(t,o())},enumerable:!1})}),e}function nr(e,t,r,...n){try{return r(...n)}catch(i){te(i,e,t)}}function te(e,t,r=void 0){e=Object.assign(e??{message:"No error message given."},{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message} - -${r?'Expression: "'+r+`" - -`:""}`,t),setTimeout(()=>{throw e},0)}var Me=!0;function De(e){let t=Me;Me=!1;let r=e();return Me=t,r}function M(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return ir(...e)}var ir=gt;function or(e){ir=e}function gt(e,t){let r={};ue(r,e);let n=[r,...j(e)],i=typeof t=="function"?In(n,t):Ln(n,t,e);return nr.bind(null,e,t,i)}function In(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(F([n,...e]),i);Ne(r,o)}}var ht={};function kn(e,t){if(ht[e])return ht[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e.trim())||/^(let|const)\s/.test(e.trim())?`(async()=>{ ${e} })()`:e,o=(()=>{try{let s=new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`);return Object.defineProperty(s,"name",{value:`[Alpine] ${e}`}),s}catch(s){return te(s,t,e),Promise.resolve()}})();return ht[e]=o,o}function Ln(e,t,r){let n=kn(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=F([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>te(l,r,t));n.finished?(Ne(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Ne(i,l,a,s,r)}).catch(l=>te(l,r,t)).finally(()=>n.result=void 0)}}}function Ne(e,t,r,n,i){if(Me&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Ne(e,s,r,n)).catch(s=>te(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var bt="x-";function C(e=""){return bt+e}function sr(e){bt=e}var Pe={};function d(e,t){return Pe[e]=t,{before(r){if(!Pe[r]){console.warn(String.raw`Cannot find directive \`${r}\`. \`${e}\` will use the default order of execution`);return}let n=W.indexOf(r);W.splice(n>=0?n:W.indexOf("DEFAULT"),0,e)}}}function ar(e){return Object.keys(Pe).includes(e)}function de(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=wt(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(ur((o,s)=>n[o]=s)).filter(dr).map(jn(n,r)).sort(Fn).map(o=>$n(e,o))}function wt(e){return Array.from(e).map(ur()).filter(t=>!dr(t))}var xt=!1,fe=new Map,cr=Symbol();function lr(e){xt=!0;let t=Symbol();cr=t,fe.set(t,[]);let r=()=>{for(;fe.get(t).length;)fe.get(t).shift()();fe.delete(t)},n=()=>{xt=!1,r()};e(r),n()}function _t(e){let t=[],r=a=>t.push(a),[n,i]=Gt(e);return t.push(i),[{Alpine:B,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:M.bind(M,e)},()=>t.forEach(a=>a())]}function $n(e,t){let r=()=>{},n=Pe[t.type]||r,[i,o]=_t(e);Oe(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),xt?fe.get(cr).push(n):n())};return s.runCleanups=o,s}var Ie=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),ke=e=>e;function ur(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=fr.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var fr=[];function re(e){fr.push(e)}function dr({name:e}){return pr().test(e)}var pr=()=>new RegExp(`^${bt}([^:^.]+)\\b`);function jn(e,t){return({name:r,value:n})=>{let i=r.match(pr()),o=r.match(/:([a-zA-Z0-9\-_:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var yt="DEFAULT",W=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",yt,"teleport"];function Fn(e,t){let r=W.indexOf(e.type)===-1?yt:e.type,n=W.indexOf(t.type)===-1?yt:t.type;return W.indexOf(r)-W.indexOf(n)}function G(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function T(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>T(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)T(n,t,!1),n=n.nextElementSibling}function E(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var mr=!1;function _r(){mr&&E("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),mr=!0,document.body||E("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` -} - -templ InsertCredential(credentialName string) { - -} diff --git a/pkg/nebula/global/state/database_templ.go b/pkg/nebula/global/state/database_templ.go deleted file mode 100644 index 07c237348..000000000 --- a/pkg/nebula/global/state/database_templ.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.778 -package state - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func InsertAccount(accountName string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func InsertCredential(credentialName string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/global/state/worker.templ b/pkg/nebula/global/state/worker.templ deleted file mode 100644 index 2fd285c00..000000000 --- a/pkg/nebula/global/state/worker.templ +++ /dev/null @@ -1,25 +0,0 @@ -package state - -var ( - serviceWorkerInstall = templ.NewOnceHandle() -) - -templ RegisterServiceWorker() { - @serviceWorkerInstall.Once() { - - } -} diff --git a/pkg/nebula/global/ui/button.templ b/pkg/nebula/global/ui/button.templ deleted file mode 100644 index 4f145f0bd..000000000 --- a/pkg/nebula/global/ui/button.templ +++ /dev/null @@ -1,234 +0,0 @@ -package ui - -import "github.com/onsonr/sonr/pkg/nebula/global/styles" - -templ PrimaryButton(href string, text string) { -

    -} - -templ SecondaryButton(href string, text string) { -
    -
    { text }
    -
    -} - -type button struct { - variant styles.Variant - hxGet string - hxPost string - hxTarget string - hxTrigger string - hxSwap string -} - -type ButtonOpt func(button *button) - -func PrimaryButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantPrimary - } -} - -func InfoButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantInfo - } -} - -func ErrorButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantError - } -} - -func SuccessButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantSuccess - } -} - -func WarningButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantWarning - } -} - -func GET(action string, target string) ButtonOpt { - return func(button *button) { - button.hxGet = action - button.hxTarget = target - button.hxTrigger = "click" - button.hxSwap = "outerHTML" - } -} - -func POST(action string, target string) ButtonOpt { - return func(button *button) { - button.hxPost = action - button.hxTarget = target - button.hxTrigger = "click" - button.hxSwap = "outerHTML" - } -} - -func Button(opts ...ButtonOpt) templ.Component { - button := button{ - variant: ButtonVariantDefault, - } - for _, opt := range opts { - opt(&button) - } - if button.hxGet != "" { - return renderHxGetButton(&button, button.variant.Attributes()) - } - - if button.hxPost != "" { - return renderHxPostButton(&button, button.variant.Attributes()) - } - return renderButton(button.variant.Attributes()) -} - -templ renderButton(attrs templ.Attributes) { - -} - -templ renderHxGetButton(c *button, attrs templ.Attributes) { - -} - -templ renderHxPostButton(c *button, attrs templ.Attributes) { - -} - -type ButtonVariant int - -const ( - ButtonVariantDefault ButtonVariant = iota - ButtonVariantPrimary - ButtonVariantInfo - ButtonVariantError - ButtonVariantSuccess - ButtonVariantWarning -) - -func (v ButtonVariant) Attributes() templ.Attributes { - switch v { - case ButtonVariantPrimary: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none", - "type": "button", - } - case ButtonVariantInfo: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 bg-blue-600 rounded-md hover:bg-blue-700 focus:ring-2 focus:ring-offset-2 focus:ring-blue-700 focus:shadow-outline focus:outline-none", - "type": "button", - } - case ButtonVariantError: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-red-600 hover:bg-red-700 focus:ring-2 focus:ring-offset-2 focus:ring-red-700 focus:shadow-outline focus:outline-none", - "type": "button", - } - case ButtonVariantSuccess: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-green-600 hover:bg-green-700 focus:ring-2 focus:ring-offset-2 focus:ring-green-700 focus:shadow-outline focus:outline-none", - "type": "button", - } - case ButtonVariantWarning: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-yellow-600 hover:bg-yellow-700 focus:ring-2 focus:ring-offset-2 focus:ring-yellow-700 focus:shadow-outline focus:outline-none", - "type": "button", - } - } - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide transition-colors duration-200 bg-white border rounded-md text-neutral-500 hover:text-neutral-700 border-neutral-200/70 hover:bg-neutral-100 active:bg-white focus:bg-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-200/60 focus:shadow-outline", - "type": "button", - } -} - -type SubtleButtonVariant int - -const ( - SubtleButtonVariantDefault SubtleButtonVariant = iota - SubtleButtonVariantInfo - SubtleButtonVariantError - SubtleButtonVariantSuccess - SubtleButtonVariantWarning -) - -func (v SubtleButtonVariant) Attributes() templ.Attributes { - switch v { - case SubtleButtonVariantInfo: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-blue-500 transition-colors duration-100 rounded-md focus:ring-2 focus:ring-offset-2 focus:ring-blue-100 bg-blue-50 hover:text-blue-600 hover:bg-blue-100", - "type": "button", - } - case SubtleButtonVariantError: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-red-500 transition-colors duration-100 rounded-md focus:ring-2 focus:ring-offset-2 focus:ring-red-100 bg-red-50 hover:text-red-600 hover:bg-red-100", - "type": "button", - } - case SubtleButtonVariantSuccess: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-green-500 transition-colors duration-100 rounded-md focus:ring-2 focus:ring-offset-2 focus:ring-green-100 bg-green-50 hover:text-green-600 hover:bg-green-100", - "type": "button", - } - case SubtleButtonVariantWarning: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-yellow-600 transition-colors duration-100 rounded-md focus:ring-2 focus:ring-offset-2 focus:ring-yellow-100 bg-yellow-50 hover:text-yellow-700 hover:bg-yellow-100", - "type": "button", - } - } - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide transition-colors duration-100 rounded-md text-neutral-500 bg-neutral-50 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-100 hover:text-neutral-600 hover:bg-neutral-100", - "type": "button", - } -} - -type OutlineButtonVariant int - -const ( - OutlineButtonVariantDefault OutlineButtonVariant = iota - OutlineButtonVariantInfo - OutlineButtonVariantError - OutlineButtonVariantSuccess - OutlineButtonVariantWarning -) - -func (v OutlineButtonVariant) Attributes() templ.Attributes { - switch v { - case OutlineButtonVariantInfo: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-blue-600 transition-colors duration-100 bg-white border-2 border-blue-600 rounded-md hover:text-white hover:bg-blue-600", - "type": "button", - } - case OutlineButtonVariantError: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-red-600 transition-colors duration-100 bg-white border-2 border-red-600 rounded-md hover:text-white hover:bg-red-600", - "type": "button", - } - case OutlineButtonVariantSuccess: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-green-600 transition-colors duration-100 bg-white border-2 border-green-600 rounded-md hover:text-white hover:bg-green-600", - "type": "button", - } - case OutlineButtonVariantWarning: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-yellow-600 transition-colors duration-100 bg-white border-2 border-yellow-500 rounded-md hover:text-white hover:bg-yellow-500", - "type": "button", - } - } - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide transition-colors duration-100 bg-white border-2 rounded-md text-neutral-900 hover:text-white border-neutral-900 hover:bg-neutral-900", - "type": "button", - } -} diff --git a/pkg/nebula/global/ui/button_templ.go b/pkg/nebula/global/ui/button_templ.go deleted file mode 100644 index 8a6e13fec..000000000 --- a/pkg/nebula/global/ui/button_templ.go +++ /dev/null @@ -1,548 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.778 -package ui - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "github.com/onsonr/sonr/pkg/nebula/global/styles" - -func PrimaryButton(href string, text string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/ui/button.templ`, Line: 7, Col: 133} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func SecondaryButton(href string, text string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var4 := templ.GetChildren(ctx) - if templ_7745c5c3_Var4 == nil { - templ_7745c5c3_Var4 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/ui/button.templ`, Line: 13, Col: 175} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -type button struct { - variant styles.Variant - hxGet string - hxPost string - hxTarget string - hxTrigger string - hxSwap string -} - -type ButtonOpt func(button *button) - -func PrimaryButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantPrimary - } -} - -func InfoButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantInfo - } -} - -func ErrorButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantError - } -} - -func SuccessButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantSuccess - } -} - -func WarningButtonStyle() ButtonOpt { - return func(button *button) { - button.variant = ButtonVariantWarning - } -} - -func GET(action string, target string) ButtonOpt { - return func(button *button) { - button.hxGet = action - button.hxTarget = target - button.hxTrigger = "click" - button.hxSwap = "outerHTML" - } -} - -func POST(action string, target string) ButtonOpt { - return func(button *button) { - button.hxPost = action - button.hxTarget = target - button.hxTrigger = "click" - button.hxSwap = "outerHTML" - } -} - -func Button(opts ...ButtonOpt) templ.Component { - button := button{ - variant: ButtonVariantDefault, - } - for _, opt := range opts { - opt(&button) - } - if button.hxGet != "" { - return renderHxGetButton(&button, button.variant.Attributes()) - } - - if button.hxPost != "" { - return renderHxPostButton(&button, button.variant.Attributes()) - } - return renderButton(button.variant.Attributes()) -} - -func renderButton(attrs templ.Attributes) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var6 := templ.GetChildren(ctx) - if templ_7745c5c3_Var6 == nil { - templ_7745c5c3_Var6 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ_7745c5c3_Var6.Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func renderHxGetButton(c *button, attrs templ.Attributes) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var7 := templ.GetChildren(ctx) - if templ_7745c5c3_Var7 == nil { - templ_7745c5c3_Var7 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func renderHxPostButton(c *button, attrs templ.Attributes) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var12 := templ.GetChildren(ctx) - if templ_7745c5c3_Var12 == nil { - templ_7745c5c3_Var12 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -type ButtonVariant int - -const ( - ButtonVariantDefault ButtonVariant = iota - ButtonVariantPrimary - ButtonVariantInfo - ButtonVariantError - ButtonVariantSuccess - ButtonVariantWarning -) - -func (v ButtonVariant) Attributes() templ.Attributes { - switch v { - case ButtonVariantPrimary: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-900 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none", - "type": "button", - } - case ButtonVariantInfo: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 bg-blue-600 rounded-md hover:bg-blue-700 focus:ring-2 focus:ring-offset-2 focus:ring-blue-700 focus:shadow-outline focus:outline-none", - "type": "button", - } - case ButtonVariantError: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-red-600 hover:bg-red-700 focus:ring-2 focus:ring-offset-2 focus:ring-red-700 focus:shadow-outline focus:outline-none", - "type": "button", - } - case ButtonVariantSuccess: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-green-600 hover:bg-green-700 focus:ring-2 focus:ring-offset-2 focus:ring-green-700 focus:shadow-outline focus:outline-none", - "type": "button", - } - case ButtonVariantWarning: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-yellow-600 hover:bg-yellow-700 focus:ring-2 focus:ring-offset-2 focus:ring-yellow-700 focus:shadow-outline focus:outline-none", - "type": "button", - } - } - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide transition-colors duration-200 bg-white border rounded-md text-neutral-500 hover:text-neutral-700 border-neutral-200/70 hover:bg-neutral-100 active:bg-white focus:bg-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-200/60 focus:shadow-outline", - "type": "button", - } -} - -type SubtleButtonVariant int - -const ( - SubtleButtonVariantDefault SubtleButtonVariant = iota - SubtleButtonVariantInfo - SubtleButtonVariantError - SubtleButtonVariantSuccess - SubtleButtonVariantWarning -) - -func (v SubtleButtonVariant) Attributes() templ.Attributes { - switch v { - case SubtleButtonVariantInfo: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-blue-500 transition-colors duration-100 rounded-md focus:ring-2 focus:ring-offset-2 focus:ring-blue-100 bg-blue-50 hover:text-blue-600 hover:bg-blue-100", - "type": "button", - } - case SubtleButtonVariantError: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-red-500 transition-colors duration-100 rounded-md focus:ring-2 focus:ring-offset-2 focus:ring-red-100 bg-red-50 hover:text-red-600 hover:bg-red-100", - "type": "button", - } - case SubtleButtonVariantSuccess: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-green-500 transition-colors duration-100 rounded-md focus:ring-2 focus:ring-offset-2 focus:ring-green-100 bg-green-50 hover:text-green-600 hover:bg-green-100", - "type": "button", - } - case SubtleButtonVariantWarning: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-yellow-600 transition-colors duration-100 rounded-md focus:ring-2 focus:ring-offset-2 focus:ring-yellow-100 bg-yellow-50 hover:text-yellow-700 hover:bg-yellow-100", - "type": "button", - } - } - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide transition-colors duration-100 rounded-md text-neutral-500 bg-neutral-50 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-100 hover:text-neutral-600 hover:bg-neutral-100", - "type": "button", - } -} - -type OutlineButtonVariant int - -const ( - OutlineButtonVariantDefault OutlineButtonVariant = iota - OutlineButtonVariantInfo - OutlineButtonVariantError - OutlineButtonVariantSuccess - OutlineButtonVariantWarning -) - -func (v OutlineButtonVariant) Attributes() templ.Attributes { - switch v { - case OutlineButtonVariantInfo: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-blue-600 transition-colors duration-100 bg-white border-2 border-blue-600 rounded-md hover:text-white hover:bg-blue-600", - "type": "button", - } - case OutlineButtonVariantError: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-red-600 transition-colors duration-100 bg-white border-2 border-red-600 rounded-md hover:text-white hover:bg-red-600", - "type": "button", - } - case OutlineButtonVariantSuccess: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-green-600 transition-colors duration-100 bg-white border-2 border-green-600 rounded-md hover:text-white hover:bg-green-600", - "type": "button", - } - case OutlineButtonVariantWarning: - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-yellow-600 transition-colors duration-100 bg-white border-2 border-yellow-500 rounded-md hover:text-white hover:bg-yellow-500", - "type": "button", - } - } - return templ.Attributes{ - "class": "inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide transition-colors duration-100 bg-white border-2 rounded-md text-neutral-900 hover:text-white border-neutral-900 hover:bg-neutral-900", - "type": "button", - } -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/global/ui/icons.templ b/pkg/nebula/global/ui/icons.templ deleted file mode 100644 index f7854fc31..000000000 --- a/pkg/nebula/global/ui/icons.templ +++ /dev/null @@ -1,32 +0,0 @@ -package ui - - -type Icons int - -const ( - Icons_Info Icons = iota - Icons_Error - Icons_Success - Icons_Warning -) - -func (v Icons) Render() templ.Component { - return renderIconVariant(v) -} - -templ renderIconVariant(v Icons) { - switch v { - case Icons_Info: - - case Icons_Error: - - case Icons_Success: - - case Icons_Warning: - - } - -} - -templ SonrIcon() { -} diff --git a/pkg/nebula/global/ui/icons_templ.go b/pkg/nebula/global/ui/icons_templ.go deleted file mode 100644 index 122a9b311..000000000 --- a/pkg/nebula/global/ui/icons_templ.go +++ /dev/null @@ -1,100 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.778 -package ui - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -type Icons int - -const ( - Icons_Info Icons = iota - Icons_Error - Icons_Success - Icons_Warning -) - -func (v Icons) Render() templ.Component { - return renderIconVariant(v) -} - -func renderIconVariant(v Icons) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - switch v { - case Icons_Info: - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case Icons_Error: - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case Icons_Success: - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case Icons_Warning: - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func SonrIcon() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/marketing/nav_header.templ b/pkg/nebula/marketing/nav_header.templ deleted file mode 100644 index c18642e8a..000000000 --- a/pkg/nebula/marketing/nav_header.templ +++ /dev/null @@ -1,32 +0,0 @@ -package marketing - -templ Header() { - -
    -
    -
    -
    - - - - -
    -
    -
    -
    -} diff --git a/pkg/nebula/marketing/nav_header_templ.go b/pkg/nebula/marketing/nav_header_templ.go deleted file mode 100644 index 1f5e9be04..000000000 --- a/pkg/nebula/marketing/nav_header_templ.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.778 -package marketing - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func Header() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    \"Logo\"
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/modals/authentication.templ b/pkg/nebula/modals/authentication.templ deleted file mode 100644 index 8e49f70a5..000000000 --- a/pkg/nebula/modals/authentication.templ +++ /dev/null @@ -1,28 +0,0 @@ -package modals - -import ( - "github.com/labstack/echo/v4" - "github.com/onsonr/sonr/pkg/nebula/auth" - "github.com/onsonr/sonr/pkg/nebula/global/styles" -) - -// RegisterModal returns the Register Modal. -templ RegisterModal(c echo.Context) { - @styles.OpenModal("Account Registration", "Enter your account information below to create your account.") { - @auth.RegisterStart() - } -} - -// LoginModal returns the Login Modal. -templ LoginModal(c echo.Context) { - @styles.OpenModal("Account Registration", "Enter your account information below to create your account.") { - @auth.LoginStart() - } -} - -// AuthorizeModal returns the Authorize Modal. -templ AuthorizeModal(c echo.Context) { - @styles.OpenModal("Account Registration", "Enter your account information below to create your account.") { - @auth.AuthorizeStart() - } -} diff --git a/pkg/nebula/modals/intro_video.templ b/pkg/nebula/modals/intro_video.templ deleted file mode 100644 index 4a4a7cd5a..000000000 --- a/pkg/nebula/modals/intro_video.templ +++ /dev/null @@ -1,283 +0,0 @@ -package modals - -templ IntroVideo() { -
    - -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    - - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -} diff --git a/pkg/nebula/modals/intro_video_templ.go b/pkg/nebula/modals/intro_video_templ.go deleted file mode 100644 index 9643e7820..000000000 --- a/pkg/nebula/modals/intro_video_templ.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.778 -package modals - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func IntroVideo() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/routes/auth.go b/pkg/nebula/routes/auth.go deleted file mode 100644 index 17a179b60..000000000 --- a/pkg/nebula/routes/auth.go +++ /dev/null @@ -1,44 +0,0 @@ -package routes - -import ( - "log" - - "github.com/labstack/echo/v4" - - "github.com/onsonr/sonr/pkg/common/ctx" - "github.com/onsonr/sonr/pkg/nebula/modals" - "github.com/onsonr/sonr/pkg/nebula/views" -) - -// ╭───────────────────────────────────────────────────────────╮ -// │ DWN Routes - Authentication │ -// ╰───────────────────────────────────────────────────────────╯ - -// CurrentViewRoute returns the current view route. -func CurrentViewRoute(c echo.Context) error { - s, err := ctx.GetDWNContext(c) - if err != nil { - return err - } - log.Printf("Session ID: %s", s.ID()) - return ctx.RenderTempl(c, views.CurrentView(c)) -} - -// ╭───────────────────────────────────────────────────────────╮ -// │ Hway Routes - Authentication │ -// ╰───────────────────────────────────────────────────────────╯ - -// AuthorizeModalRoute returns the Authorize Modal route. -func AuthorizeModalRoute(c echo.Context) error { - return ctx.RenderTempl(c, modals.AuthorizeModal(c)) -} - -// LoginModalRoute returns the Login Modal route. -func LoginModalRoute(c echo.Context) error { - return ctx.RenderTempl(c, modals.LoginModal(c)) -} - -// RegisterModalRoute returns the Register Modal route. -func RegisterModalRoute(c echo.Context) error { - return ctx.RenderTempl(c, modals.RegisterModal(c)) -} diff --git a/pkg/nebula/routes/home.go b/pkg/nebula/routes/home.go deleted file mode 100644 index 0525b9dfd..000000000 --- a/pkg/nebula/routes/home.go +++ /dev/null @@ -1,23 +0,0 @@ -package routes - -import ( - "log" - - "github.com/labstack/echo/v4" - - "github.com/onsonr/sonr/pkg/common/ctx" - "github.com/onsonr/sonr/pkg/nebula/marketing" -) - -// ╭───────────────────────────────────────────────────────────╮ -// │ Home Routes - Marketing │ -// ╰───────────────────────────────────────────────────────────╯ - -func HomeRoute(c echo.Context) error { - s, err := ctx.GetHWAYContext(c) - if err != nil { - return err - } - log.Printf("Session ID: %s", s.ID()) - return ctx.RenderTempl(c, marketing.View()) -} diff --git a/pkg/nebula/views/current.templ b/pkg/nebula/views/current.templ deleted file mode 100644 index d8a8028ab..000000000 --- a/pkg/nebula/views/current.templ +++ /dev/null @@ -1,23 +0,0 @@ -package views - -import echo "github.com/labstack/echo/v4" - -// CurrentView checks if the user is logged in. -templ CurrentView(c echo.Context) { -
    -
    -
    -
    -
    -

    Current Account

    -
    -
    -

    - Logout -

    -
    -
    -
    -
    -
    -} diff --git a/pkg/nebula/views/index.templ b/pkg/nebula/views/index.templ deleted file mode 100644 index 23250c06c..000000000 --- a/pkg/nebula/views/index.templ +++ /dev/null @@ -1,29 +0,0 @@ -package views - -import ( - "github.com/onsonr/sonr/pkg/nebula/global/state" - "github.com/onsonr/sonr/pkg/nebula/global/styles" -) - -templ VaultIndexFile() { - - - - @styles.Styles() - @styles.Alpine() - @styles.Htmx() - - - - Sonr DWN - @state.RegisterServiceWorker() - - @styles.Toaster() { - -
    -
    Loading...
    -
    - - } - -} diff --git a/pkg/nebula/views/index_templ.go b/pkg/nebula/views/index_templ.go deleted file mode 100644 index 8127aba92..000000000 --- a/pkg/nebula/views/index_templ.go +++ /dev/null @@ -1,95 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.778 -package views - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import ( - "github.com/onsonr/sonr/pkg/nebula/global/state" - "github.com/onsonr/sonr/pkg/nebula/global/styles" -) - -func VaultIndexFile() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = styles.Styles().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = styles.Alpine().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = styles.Htmx().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Sonr DWN") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = state.RegisterServiceWorker().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    Loading...
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) - templ_7745c5c3_Err = styles.Toaster().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/services/credentials/credentials.go b/pkg/services/credentials/credentials.go new file mode 100644 index 000000000..fc4c1ddfb --- /dev/null +++ b/pkg/services/credentials/credentials.go @@ -0,0 +1,47 @@ +package credentials + +import ( + "github.com/labstack/echo/v4" +) + +// CreateCredentials initiates the credential creation process +func CreateCredentials(c echo.Context, options PublicKeyCredentialCreationOptions) error { + return CreateCredential(options).Render(c.Request().Context(), c.Response().Writer) +} + +// GetCredentials initiates the credential retrieval process +func GetCredentials(c echo.Context, options PublicKeyCredentialRequestOptions) error { + return GetCredential(options).Render(c.Request().Context(), c.Response().Writer) +} + +// Example usage: +func RegisterHandler(c echo.Context) error { + options := PublicKeyCredentialCreationOptions{ + Challenge: "your-challenge-base64url", + RpName: "Your App", + RpID: "yourdomain.com", + UserID: "user-id-base64url", + UserName: "username", + UserDisplayName: "User Display Name", + Timeout: 60000, + AttestationType: "none", + } + + return CreateCredentials(c, options) +} + +func LoginHandler(c echo.Context) error { + options := PublicKeyCredentialRequestOptions{ + Challenge: "your-challenge-base64url", + RpID: "yourdomain.com", + Timeout: 60000, + AllowCredentials: []CredentialDescriptor{ + { + Type: "public-key", + ID: "credential-id-base64url", + }, + }, + } + + return GetCredentials(c, options) +} diff --git a/pkg/services/credentials/manager.go b/pkg/services/credentials/manager.go new file mode 100644 index 000000000..bf3d9faae --- /dev/null +++ b/pkg/services/credentials/manager.go @@ -0,0 +1,10 @@ +package credentials + +import "github.com/labstack/echo/v4" + +type CredentialsManager interface { + Create(c echo.Context) error + Get(c echo.Context) error + List(c echo.Context) error + HasWebAuthn(c echo.Context) error +} diff --git a/pkg/services/credentials/options.go b/pkg/services/credentials/options.go new file mode 100644 index 000000000..9996cf127 --- /dev/null +++ b/pkg/services/credentials/options.go @@ -0,0 +1,6 @@ +package credentials + +type Config struct { + RpName string + RpID string +} diff --git a/pkg/services/credentials/scripts.templ b/pkg/services/credentials/scripts.templ new file mode 100644 index 000000000..e3fc92ccf --- /dev/null +++ b/pkg/services/credentials/scripts.templ @@ -0,0 +1,191 @@ +package credentials + +var credentialsHandle = templ.NewOnceHandle() + +// Types for credential data +type PublicKeyCredentialCreationOptions struct { + Challenge string `json:"challenge"` + RpName string `json:"rpName"` + RpID string `json:"rpId"` + UserID string `json:"userId"` + UserName string `json:"userName"` + UserDisplayName string `json:"userDisplayName"` + Timeout int `json:"timeout,omitempty"` + AttestationType string `json:"attestationType,omitempty"` +} + +type PublicKeyCredentialRequestOptions struct { + Challenge string `json:"challenge"` + RpID string `json:"rpId"` + Timeout int `json:"timeout,omitempty"` + UserVerification string `json:"userVerification,omitempty"` + AllowCredentials []CredentialDescriptor `json:"allowCredentials,omitempty"` +} + +type CredentialDescriptor struct { + Type string `json:"type"` + ID string `json:"id"` +} + +// Base credentials script template +templ CredentialsScripts() { + @credentialsHandle.Once() { + + } +} + +// Template for creating credentials +templ CreateCredential(options PublicKeyCredentialCreationOptions) { + @CredentialsScripts() + +} + +// Template for getting credentials +templ GetCredential(options PublicKeyCredentialRequestOptions) { + @CredentialsScripts() + +} diff --git a/pkg/services/credentials/scripts_templ.go b/pkg/services/credentials/scripts_templ.go new file mode 100644 index 000000000..a6646451f --- /dev/null +++ b/pkg/services/credentials/scripts_templ.go @@ -0,0 +1,154 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package credentials + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +var credentialsHandle = templ.NewOnceHandle() + +// Types for credential data +type PublicKeyCredentialCreationOptions struct { + Challenge string `json:"challenge"` + RpName string `json:"rpName"` + RpID string `json:"rpId"` + UserID string `json:"userId"` + UserName string `json:"userName"` + UserDisplayName string `json:"userDisplayName"` + Timeout int `json:"timeout,omitempty"` + AttestationType string `json:"attestationType,omitempty"` +} + +type PublicKeyCredentialRequestOptions struct { + Challenge string `json:"challenge"` + RpID string `json:"rpId"` + Timeout int `json:"timeout,omitempty"` + UserVerification string `json:"userVerification,omitempty"` + AllowCredentials []CredentialDescriptor `json:"allowCredentials,omitempty"` +} + +type CredentialDescriptor struct { + Type string `json:"type"` + ID string `json:"id"` +} + +// Base credentials script template +func CredentialsScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = credentialsHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +// Template for creating credentials +func CreateCredential(options PublicKeyCredentialCreationOptions) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = CredentialsScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +// Template for getting credentials +func GetCredential(options PublicKeyCredentialRequestOptions) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = CredentialsScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/services/payments/payments.go b/pkg/services/payments/payments.go new file mode 100644 index 000000000..008dbfc88 --- /dev/null +++ b/pkg/services/payments/payments.go @@ -0,0 +1,94 @@ +// payments/payments.go + +package payments + +import ( + "github.com/labstack/echo/v4" +) + +// Constants for supported payment methods +const ( + MethodCard = "basic-card" + MethodGooglePay = "https://google.com/pay" + MethodApplePay = "https://apple.com/apple-pay" + MethodSonrWallet = "https://sonr.id/wallet" +) + +// InitiatePayment starts the payment request flow +func InitiatePayment(c echo.Context, request PaymentRequest) error { + return StartPayment(request).Render(c.Request().Context(), c.Response().Writer) +} + +// Helper functions to create payment requests +func NewBasicCardPayment(amount float64, currency string, label string) PaymentRequest { + return PaymentRequest{ + MethodData: []PaymentMethodData{ + { + SupportedMethods: MethodCard, + Data: map[string]any{ + "supportedNetworks": []string{"visa", "mastercard"}, + "supportedTypes": []string{"credit", "debit"}, + }, + }, + }, + Details: PaymentDetails{ + Total: PaymentItem{ + Label: label, + Amount: Money{ + Currency: currency, + Value: formatAmount(amount), + }, + }, + }, + Options: PaymentOptions{ + RequestPayerName: true, + RequestPayerEmail: true, + }, + } +} + +// Example usage: +func PaymentHandler(c echo.Context) error { + request := NewBasicCardPayment(99.99, "USD", "Product Purchase") + + // Add display items + request.Details.DisplayItems = []PaymentItem{ + { + Label: "Product Price", + Amount: Money{ + Currency: "USD", + Value: "89.99", + }, + }, + { + Label: "Tax", + Amount: Money{ + Currency: "USD", + Value: "10.00", + }, + }, + } + + // Add shipping options + request.Details.ShippingOptions = []ShippingOption{ + { + ID: "standard", + Label: "Standard Shipping", + Amount: Money{ + Currency: "USD", + Value: "0.00", + }, + Selected: true, + }, + { + ID: "express", + Label: "Express Shipping", + Amount: Money{ + Currency: "USD", + Value: "10.00", + }, + }, + } + + return InitiatePayment(c, request) +} diff --git a/pkg/services/payments/scripts.templ b/pkg/services/payments/scripts.templ new file mode 100644 index 000000000..1488ca3dd --- /dev/null +++ b/pkg/services/payments/scripts.templ @@ -0,0 +1,150 @@ + +package payments + +var paymentsHandle = templ.NewOnceHandle() + +// Payment types +type PaymentMethodData struct { + SupportedMethods string `json:"supportedMethods"` + Data map[string]any `json:"data,omitempty"` +} + +type PaymentItem struct { + Label string `json:"label"` + Amount Money `json:"amount"` +} + +type Money struct { + Currency string `json:"currency"` + Value string `json:"value"` // Decimal as string for precision +} + +type PaymentOptions struct { + RequestPayerName bool `json:"requestPayerName,omitempty"` + RequestPayerEmail bool `json:"requestPayerEmail,omitempty"` + RequestPayerPhone bool `json:"requestPayerPhone,omitempty"` + RequestShipping bool `json:"requestShipping,omitempty"` +} + +type PaymentDetails struct { + Total PaymentItem `json:"total"` + DisplayItems []PaymentItem `json:"displayItems,omitempty"` + ShippingOptions []ShippingOption `json:"shippingOptions,omitempty"` +} + +type ShippingOption struct { + ID string `json:"id"` + Label string `json:"label"` + Amount Money `json:"amount"` + Selected bool `json:"selected,omitempty"` +} + +type PaymentRequest struct { + MethodData []PaymentMethodData `json:"methodData"` + Details PaymentDetails `json:"details"` + Options PaymentOptions `json:"options,omitempty"` +} + +// Base payments script template +templ PaymentsScripts() { + @paymentsHandle.Once() { + + } +} + +// StartPayment for initiating payment request +templ StartPayment(request PaymentRequest) { + @PaymentsScripts() + +} diff --git a/pkg/services/payments/scripts_templ.go b/pkg/services/payments/scripts_templ.go new file mode 100644 index 000000000..d75fc7134 --- /dev/null +++ b/pkg/services/payments/scripts_templ.go @@ -0,0 +1,138 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 + +package payments + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +var paymentsHandle = templ.NewOnceHandle() + +// Payment types +type PaymentMethodData struct { + SupportedMethods string `json:"supportedMethods"` + Data map[string]any `json:"data,omitempty"` +} + +type PaymentItem struct { + Label string `json:"label"` + Amount Money `json:"amount"` +} + +type Money struct { + Currency string `json:"currency"` + Value string `json:"value"` // Decimal as string for precision +} + +type PaymentOptions struct { + RequestPayerName bool `json:"requestPayerName,omitempty"` + RequestPayerEmail bool `json:"requestPayerEmail,omitempty"` + RequestPayerPhone bool `json:"requestPayerPhone,omitempty"` + RequestShipping bool `json:"requestShipping,omitempty"` +} + +type PaymentDetails struct { + Total PaymentItem `json:"total"` + DisplayItems []PaymentItem `json:"displayItems,omitempty"` + ShippingOptions []ShippingOption `json:"shippingOptions,omitempty"` +} + +type ShippingOption struct { + ID string `json:"id"` + Label string `json:"label"` + Amount Money `json:"amount"` + Selected bool `json:"selected,omitempty"` +} + +type PaymentRequest struct { + MethodData []PaymentMethodData `json:"methodData"` + Details PaymentDetails `json:"details"` + Options PaymentOptions `json:"options,omitempty"` +} + +// Base payments script template +func PaymentsScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = paymentsHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +// StartPayment for initiating payment request +func StartPayment(request PaymentRequest) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = PaymentsScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/services/payments/utils.go b/pkg/services/payments/utils.go new file mode 100644 index 000000000..1915e303d --- /dev/null +++ b/pkg/services/payments/utils.go @@ -0,0 +1,7 @@ +package payments + +import "fmt" + +func formatAmount(amount float64) string { + return fmt.Sprintf("%.2f", amount) +} diff --git a/pkg/services/storage/scripts.templ b/pkg/services/storage/scripts.templ new file mode 100644 index 000000000..bff5ba2d8 --- /dev/null +++ b/pkg/services/storage/scripts.templ @@ -0,0 +1,82 @@ +package storage + +var storageHandle = templ.NewOnceHandle() + +// Internal script templates for storage operations + +script setLocalStorage(key string, value string) { + localStorage.setItem(key, value) +} + +script getLocalStorage(key string) { + return localStorage.getItem(key) +} + +script removeLocalStorage(key string) { + localStorage.removeItem(key) +} + +script setSessionStorage(key string, value string) { + sessionStorage.setItem(key, value) +} + +script getSessionStorage(key string) { + return sessionStorage.getItem(key) +} + +script removeSessionStorage(key string) { + sessionStorage.removeItem(key) +} + +// Storage component that includes all storage-related scripts +templ StorageScripts() { + @storageHandle.Once() { + + } +} + +// Public components for storage operations +templ SetLocalStorageItem(key string, value any) { + @StorageScripts() + +} + +templ SetSessionStorageItem(key string, value any) { + @StorageScripts() + +} diff --git a/pkg/services/storage/scripts_templ.go b/pkg/services/storage/scripts_templ.go new file mode 100644 index 000000000..b413849b6 --- /dev/null +++ b/pkg/services/storage/scripts_templ.go @@ -0,0 +1,189 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package storage + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +var storageHandle = templ.NewOnceHandle() + +// Internal script templates for storage operations +func setLocalStorage(key string, value string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_setLocalStorage_13ae`, + Function: `function __templ_setLocalStorage_13ae(key, value){localStorage.setItem(key, value) +}`, + Call: templ.SafeScript(`__templ_setLocalStorage_13ae`, key, value), + CallInline: templ.SafeScriptInline(`__templ_setLocalStorage_13ae`, key, value), + } +} + +func getLocalStorage(key string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_getLocalStorage_3450`, + Function: `function __templ_getLocalStorage_3450(key){return localStorage.getItem(key) +}`, + Call: templ.SafeScript(`__templ_getLocalStorage_3450`, key), + CallInline: templ.SafeScriptInline(`__templ_getLocalStorage_3450`, key), + } +} + +func removeLocalStorage(key string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_removeLocalStorage_64b1`, + Function: `function __templ_removeLocalStorage_64b1(key){localStorage.removeItem(key) +}`, + Call: templ.SafeScript(`__templ_removeLocalStorage_64b1`, key), + CallInline: templ.SafeScriptInline(`__templ_removeLocalStorage_64b1`, key), + } +} + +func setSessionStorage(key string, value string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_setSessionStorage_0b44`, + Function: `function __templ_setSessionStorage_0b44(key, value){sessionStorage.setItem(key, value) +}`, + Call: templ.SafeScript(`__templ_setSessionStorage_0b44`, key, value), + CallInline: templ.SafeScriptInline(`__templ_setSessionStorage_0b44`, key, value), + } +} + +func getSessionStorage(key string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_getSessionStorage_66b8`, + Function: `function __templ_getSessionStorage_66b8(key){return sessionStorage.getItem(key) +}`, + Call: templ.SafeScript(`__templ_getSessionStorage_66b8`, key), + CallInline: templ.SafeScriptInline(`__templ_getSessionStorage_66b8`, key), + } +} + +func removeSessionStorage(key string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_removeSessionStorage_a2e3`, + Function: `function __templ_removeSessionStorage_a2e3(key){sessionStorage.removeItem(key) +}`, + Call: templ.SafeScript(`__templ_removeSessionStorage_a2e3`, key), + CallInline: templ.SafeScriptInline(`__templ_removeSessionStorage_a2e3`, key), + } +} + +// Storage component that includes all storage-related scripts +func StorageScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = storageHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +// Public components for storage operations +func SetLocalStorageItem(key string, value any) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = StorageScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func SetSessionStorageItem(key string, value any) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = StorageScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/services/storage/storage.go b/pkg/services/storage/storage.go new file mode 100644 index 000000000..83897e395 --- /dev/null +++ b/pkg/services/storage/storage.go @@ -0,0 +1,15 @@ +package storage + +import ( + "github.com/labstack/echo/v4" +) + +// SetLocal sets a value in localStorage +func SetLocal(c echo.Context, key string, value any) error { + return SetLocalStorageItem(key, value).Render(c.Request().Context(), c.Response().Writer) +} + +// SetSession sets a value in sessionStorage +func SetSession(c echo.Context, key string, value any) error { + return SetSessionStorageItem(key, value).Render(c.Request().Context(), c.Response().Writer) +} diff --git a/pkg/webapp/bun.lockb b/pkg/webapp/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..8f3a1229b7226e632aa1c3f292150fd125c37edc GIT binary patch literal 119323 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 literal 0 HcmV?d00001 diff --git a/pkg/webapp/components/auth/authorize.templ b/pkg/webapp/components/auth/authorize.templ new file mode 100644 index 000000000..758bd68ed --- /dev/null +++ b/pkg/webapp/components/auth/authorize.templ @@ -0,0 +1,12 @@ +package auth + +import ( + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/webapp/components/ui" +) + +templ AuthorizeView(c session.Context) { + @ui.OpenModal(c.ID(), "Enter your account information below to create your account.") { + @loginStart() + } +} diff --git a/pkg/nebula/global/state/worker_templ.go b/pkg/webapp/components/auth/authorize_templ.go similarity index 66% rename from pkg/nebula/global/state/worker_templ.go rename to pkg/webapp/components/auth/authorize_templ.go index c1c923ccf..ad2c23bf7 100644 --- a/pkg/nebula/global/state/worker_templ.go +++ b/pkg/webapp/components/auth/authorize_templ.go @@ -1,18 +1,19 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package state +// templ: version: v0.2.793 +package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -var ( - serviceWorkerInstall = templ.NewOnceHandle() +import ( + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/webapp/components/ui" ) -func RegisterServiceWorker() templ.Component { +func AuthorizeView(c session.Context) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -45,13 +46,13 @@ func RegisterServiceWorker() templ.Component { }() } ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + templ_7745c5c3_Err = loginStart().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return templ_7745c5c3_Err }) - templ_7745c5c3_Err = serviceWorkerInstall.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = ui.OpenModal(c.ID(), "Enter your account information below to create your account.").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/nebula/forms/credential_register.templ b/pkg/webapp/components/auth/create_credential.templ similarity index 99% rename from pkg/nebula/forms/credential_register.templ rename to pkg/webapp/components/auth/create_credential.templ index a221b14b4..65f99c078 100644 --- a/pkg/nebula/forms/credential_register.templ +++ b/pkg/webapp/components/auth/create_credential.templ @@ -1,4 +1,4 @@ -package forms +package auth import "github.com/labstack/echo/v4" diff --git a/pkg/nebula/forms/credential_register_templ.go b/pkg/webapp/components/auth/create_credential_templ.go similarity index 99% rename from pkg/nebula/forms/credential_register_templ.go rename to pkg/webapp/components/auth/create_credential_templ.go index a41ba1cdf..11f0103ea 100644 --- a/pkg/nebula/forms/credential_register_templ.go +++ b/pkg/webapp/components/auth/create_credential_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package forms +// templ: version: v0.2.793 +package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/nebula/forms/credential_assert.templ b/pkg/webapp/components/auth/get_credential.templ similarity index 99% rename from pkg/nebula/forms/credential_assert.templ rename to pkg/webapp/components/auth/get_credential.templ index d40eba567..ed684b025 100644 --- a/pkg/nebula/forms/credential_assert.templ +++ b/pkg/webapp/components/auth/get_credential.templ @@ -1,4 +1,4 @@ -package forms +package auth import "github.com/labstack/echo/v4" diff --git a/pkg/nebula/forms/credential_assert_templ.go b/pkg/webapp/components/auth/get_credential_templ.go similarity index 98% rename from pkg/nebula/forms/credential_assert_templ.go rename to pkg/webapp/components/auth/get_credential_templ.go index ff593b240..bfb597672 100644 --- a/pkg/nebula/forms/credential_assert_templ.go +++ b/pkg/webapp/components/auth/get_credential_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package forms +// templ: version: v0.2.793 +package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/nebula/auth/login.templ b/pkg/webapp/components/auth/login.templ similarity index 67% rename from pkg/nebula/auth/login.templ rename to pkg/webapp/components/auth/login.templ index 83fde80b9..bfd1ecca7 100644 --- a/pkg/nebula/auth/login.templ +++ b/pkg/webapp/components/auth/login.templ @@ -1,15 +1,21 @@ package auth import ( - "github.com/onsonr/sonr/pkg/nebula/forms" - "github.com/onsonr/sonr/pkg/nebula/global/styles" - "github.com/onsonr/sonr/pkg/nebula/global/ui" + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/webapp/components/ui" ) -templ LoginStart() { +// LoginModal returns the Login Modal. +templ LoginModal() { + @ui.OpenModal(session.GetData(ctx).Id, "Enter your account information below to create your account.") { + @loginStart() + } +} + +templ loginStart() { @ui.Breadcrumbs() - @forms.BasicDetailsForm() - @styles.Spacer() + @BasicDetailsForm() + @ui.Spacer()
    diff --git a/pkg/nebula/auth/register_templ.go b/pkg/webapp/components/auth/login_templ.go similarity index 62% rename from pkg/nebula/auth/register_templ.go rename to pkg/webapp/components/auth/login_templ.go index d83307755..f7251cb92 100644 --- a/pkg/nebula/auth/register_templ.go +++ b/pkg/webapp/components/auth/login_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,9 +8,13 @@ package auth import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import "github.com/onsonr/sonr/pkg/nebula/forms" +import ( + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/webapp/components/ui" +) -func RegisterStart() templ.Component { +// LoginModal returns the Login Modal. +func LoginModal() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -31,11 +35,25 @@ func RegisterStart() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = forms.BasicDetailsForm().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Err = loginStart().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } return templ_7745c5c3_Err - } - templ_7745c5c3_Err = registerStartFooter().Render(ctx, templ_7745c5c3_Buffer) + }) + templ_7745c5c3_Err = ui.OpenModal(session.GetData(ctx).Id, "Enter your account information below to create your account.").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -43,7 +61,7 @@ func RegisterStart() templ.Component { }) } -func registerStartFooter() templ.Component { +func loginStart() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -59,11 +77,23 @@ func registerStartFooter() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent + templ_7745c5c3_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = ui.Breadcrumbs().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = BasicDetailsForm().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = ui.Spacer().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err diff --git a/pkg/webapp/components/auth/register.templ b/pkg/webapp/components/auth/register.templ new file mode 100644 index 000000000..d1e7c65fb --- /dev/null +++ b/pkg/webapp/components/auth/register.templ @@ -0,0 +1,41 @@ +package auth + +import ( + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/webapp/components/ui" +) + +// RegisterModal returns the Register Modal. +templ RegisterModal() { + @ui.OpenModal(session.GetData(ctx).Id, "Sign up") { + @BasicDetailsForm() +
    + + +
    + } +} + +// RedirectModal returns the Modal with a QR code to scan. +templ RedirectModal() { + @ui.FullScreenModal() { +
    +
    +
    +

    Continue with your phone

    +

    Creating a Sonr Vault requires a smartphone with W3C compliant biometrics enabled.

    +
    +
    + + + @ui.Separator("Or Scan QR Code") + +
    +
    +

    Already have an account? Login here

    +

    By continuing, you agree to our Terms and Policy.

    +
    + } +} diff --git a/pkg/nebula/forms/details_basic.templ b/pkg/webapp/components/auth/register_start.templ similarity index 98% rename from pkg/nebula/forms/details_basic.templ rename to pkg/webapp/components/auth/register_start.templ index 47fc53747..08ead730c 100644 --- a/pkg/nebula/forms/details_basic.templ +++ b/pkg/webapp/components/auth/register_start.templ @@ -1,11 +1,9 @@ -package forms +package auth templ BasicDetailsForm() {
    @roleSelectInput() - @nameInput() - @usernameInput()
    } diff --git a/pkg/nebula/forms/details_basic_templ.go b/pkg/webapp/components/auth/register_start_templ.go similarity index 95% rename from pkg/nebula/forms/details_basic_templ.go rename to pkg/webapp/components/auth/register_start_templ.go index 73da245c6..35ee1d9f5 100644 --- a/pkg/nebula/forms/details_basic_templ.go +++ b/pkg/webapp/components/auth/register_start_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package forms +// templ: version: v0.2.793 +package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -37,14 +37,6 @@ func BasicDetailsForm() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = nameInput().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = usernameInput().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err diff --git a/pkg/nebula/modals/authentication_templ.go b/pkg/webapp/components/auth/register_templ.go similarity index 51% rename from pkg/nebula/modals/authentication_templ.go rename to pkg/webapp/components/auth/register_templ.go index 4c2e9d1c7..231cc7bcf 100644 --- a/pkg/nebula/modals/authentication_templ.go +++ b/pkg/webapp/components/auth/register_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package modals +// templ: version: v0.2.793 +package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -9,13 +9,12 @@ import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import ( - "github.com/labstack/echo/v4" - "github.com/onsonr/sonr/pkg/nebula/auth" - "github.com/onsonr/sonr/pkg/nebula/global/styles" + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/webapp/components/ui" ) // RegisterModal returns the Register Modal. -func RegisterModal(c echo.Context) templ.Component { +func RegisterModal() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -48,13 +47,17 @@ func RegisterModal(c echo.Context) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = auth.RegisterStart().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = BasicDetailsForm().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return templ_7745c5c3_Err }) - templ_7745c5c3_Err = styles.OpenModal("Account Registration", "Enter your account information below to create your account.").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = ui.OpenModal(session.GetData(ctx).Id, "Sign up").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -62,8 +65,8 @@ func RegisterModal(c echo.Context) templ.Component { }) } -// LoginModal returns the Login Modal. -func LoginModal(c echo.Context) templ.Component { +// RedirectModal returns the Modal with a QR code to scan. +func RedirectModal() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -96,61 +99,21 @@ func LoginModal(c echo.Context) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = auth.LoginStart().Render(ctx, templ_7745c5c3_Buffer) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    Continue with your phone

    Creating a Sonr Vault requires a smartphone with W3C compliant biometrics enabled.

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = ui.Separator("Or Scan QR Code").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    Already have an account? Login here

    By continuing, you agree to our Terms and Policy.

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return templ_7745c5c3_Err }) - templ_7745c5c3_Err = styles.OpenModal("Account Registration", "Enter your account information below to create your account.").Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -// AuthorizeModal returns the Authorize Modal. -func AuthorizeModal(c echo.Context) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var5 := templ.GetChildren(ctx) - if templ_7745c5c3_Var5 == nil { - templ_7745c5c3_Var5 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = auth.AuthorizeStart().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) - templ_7745c5c3_Err = styles.OpenModal("Account Registration", "Enter your account information below to create your account.").Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = ui.FullScreenModal().Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/nebula/global/styles/globals.css b/pkg/webapp/components/globals.css similarity index 87% rename from pkg/nebula/global/styles/globals.css rename to pkg/webapp/components/globals.css index 40e044a5f..ed929e5e0 100644 --- a/pkg/nebula/global/styles/globals.css +++ b/pkg/webapp/components/globals.css @@ -10,25 +10,6 @@ display: none; } -@layer base { - @font-face { - font-family: "ZT Bros Oskon 90s"; - font-style: italic; - font-weight: bold; - font-display: swap; - src: url(https://cdn.sonr.id/fonts/ZTBrosOskon90s-BoldSemExpIta.woff2) - format("woff2"); - } - @font-face { - font-family: "ZT Bros Oskon 90s"; - font-style: normal; - font-weight: bold; - font-display: swap; - src: url(https://cdn.sonr.id/fonts/ZTBrosOskon90s-BoldSemExp.woff2) - format("woff2"); - } -} - /* Custom styles */ .form-input:focus, .form-textarea:focus, diff --git a/pkg/nebula/marketing/section_arch.templ b/pkg/webapp/components/landing/arch.templ similarity index 96% rename from pkg/nebula/marketing/section_arch.templ rename to pkg/webapp/components/landing/arch.templ index ce51901cd..39e2747a6 100644 --- a/pkg/nebula/marketing/section_arch.templ +++ b/pkg/webapp/components/landing/arch.templ @@ -1,9 +1,6 @@ -package marketing +package landing -import ( - "github.com/onsonr/sonr/pkg/nebula/global" - models "github.com/onsonr/sonr/pkg/nebula/types" -) +import models "github.com/onsonr/sonr/pkg/webapp/models" // ╭───────────────────────────────────────────────────────────╮ // │ Data Model │ @@ -17,7 +14,7 @@ var arch = &models.Architecture{ Title: "Decentralized Identity", Desc: "Sonr leverages the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.", Image: &models.Image{ - Src: global.HardwareWallet.Src(), + Src: models.HardwareWallet.Src(), Width: "721", Height: "280", }, @@ -26,7 +23,7 @@ var arch = &models.Architecture{ Title: "IPFS Vaults", Desc: "Completely distributed, encrypted, and decentralized storage for your data.", Image: &models.Image{ - Src: global.DecentralizedNetwork.Src(), + Src: models.DecentralizedNetwork.Src(), Width: "342", Height: "280", }, @@ -35,7 +32,7 @@ var arch = &models.Architecture{ Title: "Service Records", Desc: "On-chain validated services created by Developers for secure transmission of user data.", Image: &models.Image{ - Src: global.DefiDashboard.Src(), + Src: models.DefiDashboard.Src(), Width: "342", Height: "280", }, @@ -44,7 +41,7 @@ var arch = &models.Architecture{ Title: "Authentication & Authorization", Desc: "Sonr leverages decentralized Macaroons and Multi-Party Computation to provide a secure and decentralized authentication and authorization system.", Image: &models.Image{ - Src: global.PrivateKey.Src(), + Src: models.PrivateKey.Src(), Width: "342", Height: "280", }, @@ -53,7 +50,7 @@ var arch = &models.Architecture{ Title: "First-Class Exchange", Desc: "Sonr integrates with the IBC protocol allowing for seamless integration with popular exchanges such as OKX, Binance, and Osmosis.", Image: &models.Image{ - Src: global.CrossChainBridge.Src(), + Src: models.CrossChainBridge.Src(), Width: "342", Height: "280", }, diff --git a/pkg/nebula/marketing/section_arch_templ.go b/pkg/webapp/components/landing/arch_templ.go similarity index 87% rename from pkg/nebula/marketing/section_arch_templ.go rename to pkg/webapp/components/landing/arch_templ.go index 538845904..81225c9f9 100644 --- a/pkg/nebula/marketing/section_arch_templ.go +++ b/pkg/webapp/components/landing/arch_templ.go @@ -1,17 +1,14 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package marketing +// templ: version: v0.2.793 +package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import ( - "github.com/onsonr/sonr/pkg/nebula/global" - models "github.com/onsonr/sonr/pkg/nebula/types" -) +import models "github.com/onsonr/sonr/pkg/webapp/models" // ╭───────────────────────────────────────────────────────────╮ // │ Data Model │ @@ -25,7 +22,7 @@ var arch = &models.Architecture{ Title: "Decentralized Identity", Desc: "Sonr leverages the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.", Image: &models.Image{ - Src: global.HardwareWallet.Src(), + Src: models.HardwareWallet.Src(), Width: "721", Height: "280", }, @@ -34,7 +31,7 @@ var arch = &models.Architecture{ Title: "IPFS Vaults", Desc: "Completely distributed, encrypted, and decentralized storage for your data.", Image: &models.Image{ - Src: global.DecentralizedNetwork.Src(), + Src: models.DecentralizedNetwork.Src(), Width: "342", Height: "280", }, @@ -43,7 +40,7 @@ var arch = &models.Architecture{ Title: "Service Records", Desc: "On-chain validated services created by Developers for secure transmission of user data.", Image: &models.Image{ - Src: global.DefiDashboard.Src(), + Src: models.DefiDashboard.Src(), Width: "342", Height: "280", }, @@ -52,7 +49,7 @@ var arch = &models.Architecture{ Title: "Authentication & Authorization", Desc: "Sonr leverages decentralized Macaroons and Multi-Party Computation to provide a secure and decentralized authentication and authorization system.", Image: &models.Image{ - Src: global.PrivateKey.Src(), + Src: models.PrivateKey.Src(), Width: "342", Height: "280", }, @@ -61,7 +58,7 @@ var arch = &models.Architecture{ Title: "First-Class Exchange", Desc: "Sonr integrates with the IBC protocol allowing for seamless integration with popular exchanges such as OKX, Binance, and Osmosis.", Image: &models.Image{ - Src: global.CrossChainBridge.Src(), + Src: models.CrossChainBridge.Src(), Width: "342", Height: "280", }, @@ -101,7 +98,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Heading) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 79, Col: 20} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 76, Col: 20} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -114,7 +111,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Subtitle) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 82, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 79, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -127,7 +124,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Primary.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 104, Col: 29} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 101, Col: 29} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -140,7 +137,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Primary.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 108, Col: 27} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 105, Col: 27} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -153,7 +150,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Primary.Image.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 114, Col: 36} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 111, Col: 36} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -166,7 +163,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Secondary.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 137, Col: 31} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 134, Col: 31} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -179,7 +176,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Secondary.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 141, Col: 29} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 138, Col: 29} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -192,7 +189,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Secondary.Image.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 147, Col: 38} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 144, Col: 38} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -205,7 +202,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var10 string templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Tertiary.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 170, Col: 30} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 167, Col: 30} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) if templ_7745c5c3_Err != nil { @@ -218,7 +215,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Tertiary.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 174, Col: 28} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 171, Col: 28} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { @@ -231,7 +228,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var12 string templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Tertiary.Image.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 180, Col: 37} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 177, Col: 37} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { @@ -244,7 +241,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var13 string templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Quaternary.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 203, Col: 32} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 200, Col: 32} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { @@ -257,7 +254,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var14 string templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Quaternary.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 207, Col: 30} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 204, Col: 30} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { @@ -270,7 +267,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var15 string templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Quaternary.Image.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 213, Col: 39} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 210, Col: 39} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { @@ -283,7 +280,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var16 string templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Quinary.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 236, Col: 29} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 233, Col: 29} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { @@ -296,7 +293,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var17 string templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Quinary.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 240, Col: 27} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 237, Col: 27} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil { @@ -309,7 +306,7 @@ func Architecture() templ.Component { var templ_7745c5c3_Var18 string templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(arch.Quinary.Image.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_arch.templ`, Line: 246, Col: 36} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/arch.templ`, Line: 243, Col: 36} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) if templ_7745c5c3_Err != nil { diff --git a/pkg/nebula/marketing/section_cta.templ b/pkg/webapp/components/landing/cta.templ similarity index 99% rename from pkg/nebula/marketing/section_cta.templ rename to pkg/webapp/components/landing/cta.templ index 07d87b740..fcaed73a8 100644 --- a/pkg/nebula/marketing/section_cta.templ +++ b/pkg/webapp/components/landing/cta.templ @@ -1,6 +1,6 @@ -package marketing +package landing -import models "github.com/onsonr/sonr/pkg/nebula/types" +import models "github.com/onsonr/sonr/pkg/webapp/models" // ╭───────────────────────────────────────────────────────────╮ // │ Data Model │ diff --git a/pkg/nebula/marketing/section_cta_templ.go b/pkg/webapp/components/landing/cta_templ.go similarity index 99% rename from pkg/nebula/marketing/section_cta_templ.go rename to pkg/webapp/components/landing/cta_templ.go index 9ccb79420..8414bbef0 100644 --- a/pkg/nebula/marketing/section_cta_templ.go +++ b/pkg/webapp/components/landing/cta_templ.go @@ -1,14 +1,14 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package marketing +// templ: version: v0.2.793 +package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import models "github.com/onsonr/sonr/pkg/nebula/types" +import models "github.com/onsonr/sonr/pkg/webapp/models" // ╭───────────────────────────────────────────────────────────╮ // │ Data Model │ diff --git a/pkg/nebula/marketing/nav_footer.templ b/pkg/webapp/components/landing/footer.templ similarity index 99% rename from pkg/nebula/marketing/nav_footer.templ rename to pkg/webapp/components/landing/footer.templ index 926bd0b83..8ca98b74a 100644 --- a/pkg/nebula/marketing/nav_footer.templ +++ b/pkg/webapp/components/landing/footer.templ @@ -1,4 +1,5 @@ -package marketing + +package landing templ Footer() { diff --git a/pkg/nebula/marketing/nav_footer_templ.go b/pkg/webapp/components/landing/footer_templ.go similarity index 99% rename from pkg/nebula/marketing/nav_footer_templ.go rename to pkg/webapp/components/landing/footer_templ.go index 9545d0f6a..2621849e4 100644 --- a/pkg/nebula/marketing/nav_footer_templ.go +++ b/pkg/webapp/components/landing/footer_templ.go @@ -1,7 +1,8 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package marketing +// templ: version: v0.2.793 + +package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/header.templ b/pkg/webapp/components/landing/header.templ new file mode 100644 index 000000000..f4b7fbfc2 --- /dev/null +++ b/pkg/webapp/components/landing/header.templ @@ -0,0 +1,76 @@ +package landing + +import models "github.com/onsonr/sonr/pkg/webapp/models" + +var header = &models.NavHeader{ + Logo: &models.Image{ + Src: "https://cdn.sonr.id/logo-ivory.svg", + Width: "20", + Height: "20", + }, + Primary: &models.NavItem{ + Text: "Get Access", + Href: "/register", + }, + Items: []*models.NavItem{ + { + Text: "Docs", + Href: "#", + }, + { + Text: "Blog", + Href: "#", + }, + { + Text: "Changelog", + Href: "#", + }, + { + Text: "About", + Href: "#", + }, + }, +} + +templ Header() { + +
    +
    +
    +
    + +
    + + + Logo + +
    + + +
    +
    +
    +
    +} + +templ navButton(item *models.NavItem, isPrimary bool) { + if isPrimary { +
    { item.Text }
    + } else { + { item.Text } + } +} diff --git a/pkg/webapp/components/landing/header_templ.go b/pkg/webapp/components/landing/header_templ.go new file mode 100644 index 000000000..2a948dbb9 --- /dev/null +++ b/pkg/webapp/components/landing/header_templ.go @@ -0,0 +1,221 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package landing + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import models "github.com/onsonr/sonr/pkg/webapp/models" + +var header = &models.NavHeader{ + Logo: &models.Image{ + Src: "https://cdn.sonr.id/logo-ivory.svg", + Width: "20", + Height: "20", + }, + Primary: &models.NavItem{ + Text: "Get Access", + Href: "/register", + }, + Items: []*models.NavItem{ + { + Text: "Docs", + Href: "#", + }, + { + Text: "Blog", + Href: "#", + }, + { + Text: "Changelog", + Href: "#", + }, + { + Text: "About", + Href: "#", + }, + }, +} + +func Header() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    \"Logo\"
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func navButton(item *models.NavItem, isPrimary bool) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + if isPrimary { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(item.Text) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/header.templ`, Line: 72, Col: 146} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(item.Text) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/header.templ`, Line: 74, Col: 189} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/marketing/section_hero.templ b/pkg/webapp/components/landing/hero.templ similarity index 98% rename from pkg/nebula/marketing/section_hero.templ rename to pkg/webapp/components/landing/hero.templ index 816dbf74a..0c12b1e29 100644 --- a/pkg/nebula/marketing/section_hero.templ +++ b/pkg/webapp/components/landing/hero.templ @@ -1,9 +1,9 @@ -package marketing +package landing import ( "fmt" - "github.com/onsonr/sonr/pkg/nebula/global/ui" - models "github.com/onsonr/sonr/pkg/nebula/types" + "github.com/onsonr/sonr/pkg/webapp/components/ui" + models "github.com/onsonr/sonr/pkg/webapp/models" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_hero_templ.go b/pkg/webapp/components/landing/hero_templ.go similarity index 93% rename from pkg/nebula/marketing/section_hero_templ.go rename to pkg/webapp/components/landing/hero_templ.go index e3a284a0a..d3cd16ae9 100644 --- a/pkg/nebula/marketing/section_hero_templ.go +++ b/pkg/webapp/components/landing/hero_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package marketing +// templ: version: v0.2.793 +package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -10,8 +10,8 @@ import templruntime "github.com/a-h/templ/runtime" import ( "fmt" - "github.com/onsonr/sonr/pkg/nebula/global/ui" - models "github.com/onsonr/sonr/pkg/nebula/types" + "github.com/onsonr/sonr/pkg/webapp/components/ui" + models "github.com/onsonr/sonr/pkg/webapp/models" ) // ╭───────────────────────────────────────────────────────────╮ @@ -80,7 +80,7 @@ func Hero() templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Subtitle) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 49, Col: 22} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 49, Col: 22} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -146,7 +146,7 @@ func heroTitle(first string, emphasis string, second string) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(first) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 66, Col: 9} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 66, Col: 9} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -159,7 +159,7 @@ func heroTitle(first string, emphasis string, second string) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(emphasis) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 68, Col: 13} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 68, Col: 13} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -172,7 +172,7 @@ func heroTitle(first string, emphasis string, second string) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(second) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 73, Col: 10} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 73, Col: 10} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -214,7 +214,7 @@ func heroImage(hero *models.Hero) templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 82, Col: 23} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 82, Col: 23} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -227,7 +227,7 @@ func heroImage(hero *models.Hero) templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Width) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 83, Col: 27} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 83, Col: 27} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -240,7 +240,7 @@ func heroImage(hero *models.Hero) templ.Component { var templ_7745c5c3_Var10 string templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(hero.Image.Height) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 84, Col: 29} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 84, Col: 29} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) if templ_7745c5c3_Err != nil { @@ -287,7 +287,7 @@ func stats(stats []*models.Stat) templ.Component { var templ_7745c5c3_Var12 string templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(counterXData(item.Value)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 96, Col: 122} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 96, Col: 122} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { @@ -300,7 +300,7 @@ func stats(stats []*models.Stat) templ.Component { var templ_7745c5c3_Var13 string templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(item.Value) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 96, Col: 159} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 96, Col: 159} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { @@ -313,7 +313,7 @@ func stats(stats []*models.Stat) templ.Component { var templ_7745c5c3_Var14 string templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(item.Denom) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 96, Col: 180} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 96, Col: 180} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { @@ -326,7 +326,7 @@ func stats(stats []*models.Stat) templ.Component { var templ_7745c5c3_Var15 string templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_hero.templ`, Line: 97, Col: 50} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/hero.templ`, Line: 97, Col: 50} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { diff --git a/pkg/nebula/marketing/section_highlights.templ b/pkg/webapp/components/landing/highlights.templ similarity index 98% rename from pkg/nebula/marketing/section_highlights.templ rename to pkg/webapp/components/landing/highlights.templ index 7ed4496b1..841a52b87 100644 --- a/pkg/nebula/marketing/section_highlights.templ +++ b/pkg/webapp/components/landing/highlights.templ @@ -1,8 +1,8 @@ -package marketing +package landing import ( "fmt" - models "github.com/onsonr/sonr/pkg/nebula/types" + models "github.com/onsonr/sonr/pkg/webapp/models" ) // ╭───────────────────────────────────────────────────────────╮ diff --git a/pkg/nebula/marketing/section_highlights_templ.go b/pkg/webapp/components/landing/highlights_templ.go similarity index 89% rename from pkg/nebula/marketing/section_highlights_templ.go rename to pkg/webapp/components/landing/highlights_templ.go index 7db4c2961..753f3be5f 100644 --- a/pkg/nebula/marketing/section_highlights_templ.go +++ b/pkg/webapp/components/landing/highlights_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package marketing +// templ: version: v0.2.793 +package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -10,7 +10,7 @@ import templruntime "github.com/a-h/templ/runtime" import ( "fmt" - models "github.com/onsonr/sonr/pkg/nebula/types" + models "github.com/onsonr/sonr/pkg/webapp/models" ) // ╭───────────────────────────────────────────────────────────╮ @@ -76,7 +76,7 @@ func Highlights() templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(highlights.Heading) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 52, Col: 26} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 52, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -89,7 +89,7 @@ func Highlights() templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(highlights.Subtitle) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 55, Col: 27} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 55, Col: 27} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -151,7 +151,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(getSelectedClass(index)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 74, Col: 34} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 74, Col: 34} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -164,7 +164,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(getClickPrevent(index)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 76, Col: 41} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 76, Col: 41} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -177,7 +177,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 80, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 80, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -190,7 +190,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(getShowBorder(index)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 83, Col: 33} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 83, Col: 33} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -203,7 +203,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 95, Col: 19} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 95, Col: 19} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -245,7 +245,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(getXShow(index)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 103, Col: 26} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 103, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { @@ -258,7 +258,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var12 string templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 114, Col: 29} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 114, Col: 29} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { @@ -271,7 +271,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var13 string templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Width) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 115, Col: 33} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 115, Col: 33} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { @@ -284,7 +284,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var14 string templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Height) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 116, Col: 35} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 116, Col: 35} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { @@ -297,7 +297,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var15 string templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_highlights.templ`, Line: 117, Col: 25} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 117, Col: 25} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { diff --git a/pkg/nebula/marketing/section_lowlights.templ b/pkg/webapp/components/landing/lowlights.templ similarity index 93% rename from pkg/nebula/marketing/section_lowlights.templ rename to pkg/webapp/components/landing/lowlights.templ index f2e3d08cd..3b41b9c91 100644 --- a/pkg/nebula/marketing/section_lowlights.templ +++ b/pkg/webapp/components/landing/lowlights.templ @@ -1,9 +1,6 @@ -package marketing +package landing -import ( - global "github.com/onsonr/sonr/pkg/nebula/global" - models "github.com/onsonr/sonr/pkg/nebula/types" -) +import models "github.com/onsonr/sonr/pkg/webapp/models" // ╭───────────────────────────────────────────────────────────╮ // │ Data Model │ @@ -16,7 +13,7 @@ var lowlights = &models.Lowlights{ FullName: "0xDesigner", Username: "@0xDesigner", Avatar: &models.Image{ - Src: global.Avatar0xDesigner.Src(), + Src: models.Avatar0xDesigner.Src(), Width: "44", Height: "44", }, @@ -26,7 +23,7 @@ var lowlights = &models.Lowlights{ FullName: "Alex Recouso", Username: "@alexrecouso", Avatar: &models.Image{ - Src: global.AvatarAlexRecouso.Src(), + Src: models.AvatarAlexRecouso.Src(), Width: "44", Height: "44", }, @@ -36,7 +33,7 @@ var lowlights = &models.Lowlights{ FullName: "Chjango Unchained", Username: "@chjango", Avatar: &models.Image{ - Src: global.AvatarChjango.Src(), + Src: models.AvatarChjango.Src(), Width: "44", Height: "44", }, @@ -46,7 +43,7 @@ var lowlights = &models.Lowlights{ FullName: "Gwart", Username: "@GwartyGwart", Avatar: &models.Image{ - Src: global.AvatarGwart.Src(), + Src: models.AvatarGwart.Src(), Width: "44", Height: "44", }, @@ -58,7 +55,7 @@ var lowlights = &models.Lowlights{ FullName: "winnie", Username: "@winnielaux_", Avatar: &models.Image{ - Src: global.AvatarWinnieLaux.Src(), + Src: models.AvatarWinnieLaux.Src(), Width: "44", Height: "44", }, @@ -68,7 +65,7 @@ var lowlights = &models.Lowlights{ FullName: "Jelena", Username: "@jelena_noble", Avatar: &models.Image{ - Src: global.AvatarJelenaNoble.Src(), + Src: models.AvatarJelenaNoble.Src(), Width: "44", Height: "44", }, @@ -78,7 +75,7 @@ var lowlights = &models.Lowlights{ FullName: "accountless", Username: "@alexanderchopan", Avatar: &models.Image{ - Src: global.AvatarAccountless.Src(), + Src: models.AvatarAccountless.Src(), Width: "44", Height: "44", }, @@ -88,7 +85,7 @@ var lowlights = &models.Lowlights{ FullName: "Unusual Whales", Username: "@unusual_whales", Avatar: &models.Image{ - Src: global.AvatarUnusualWhales.Src(), + Src: models.AvatarUnusualWhales.Src(), Width: "44", Height: "44", }, diff --git a/pkg/nebula/marketing/section_lowlights_templ.go b/pkg/webapp/components/landing/lowlights_templ.go similarity index 90% rename from pkg/nebula/marketing/section_lowlights_templ.go rename to pkg/webapp/components/landing/lowlights_templ.go index e3ac78ced..1bd2e3dfb 100644 --- a/pkg/nebula/marketing/section_lowlights_templ.go +++ b/pkg/webapp/components/landing/lowlights_templ.go @@ -1,17 +1,14 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package marketing +// templ: version: v0.2.793 +package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import ( - global "github.com/onsonr/sonr/pkg/nebula/global" - models "github.com/onsonr/sonr/pkg/nebula/types" -) +import models "github.com/onsonr/sonr/pkg/webapp/models" // ╭───────────────────────────────────────────────────────────╮ // │ Data Model │ @@ -24,7 +21,7 @@ var lowlights = &models.Lowlights{ FullName: "0xDesigner", Username: "@0xDesigner", Avatar: &models.Image{ - Src: global.Avatar0xDesigner.Src(), + Src: models.Avatar0xDesigner.Src(), Width: "44", Height: "44", }, @@ -34,7 +31,7 @@ var lowlights = &models.Lowlights{ FullName: "Alex Recouso", Username: "@alexrecouso", Avatar: &models.Image{ - Src: global.AvatarAlexRecouso.Src(), + Src: models.AvatarAlexRecouso.Src(), Width: "44", Height: "44", }, @@ -44,7 +41,7 @@ var lowlights = &models.Lowlights{ FullName: "Chjango Unchained", Username: "@chjango", Avatar: &models.Image{ - Src: global.AvatarChjango.Src(), + Src: models.AvatarChjango.Src(), Width: "44", Height: "44", }, @@ -54,7 +51,7 @@ var lowlights = &models.Lowlights{ FullName: "Gwart", Username: "@GwartyGwart", Avatar: &models.Image{ - Src: global.AvatarGwart.Src(), + Src: models.AvatarGwart.Src(), Width: "44", Height: "44", }, @@ -66,7 +63,7 @@ var lowlights = &models.Lowlights{ FullName: "winnie", Username: "@winnielaux_", Avatar: &models.Image{ - Src: global.AvatarWinnieLaux.Src(), + Src: models.AvatarWinnieLaux.Src(), Width: "44", Height: "44", }, @@ -76,7 +73,7 @@ var lowlights = &models.Lowlights{ FullName: "Jelena", Username: "@jelena_noble", Avatar: &models.Image{ - Src: global.AvatarJelenaNoble.Src(), + Src: models.AvatarJelenaNoble.Src(), Width: "44", Height: "44", }, @@ -86,7 +83,7 @@ var lowlights = &models.Lowlights{ FullName: "accountless", Username: "@alexanderchopan", Avatar: &models.Image{ - Src: global.AvatarAccountless.Src(), + Src: models.AvatarAccountless.Src(), Width: "44", Height: "44", }, @@ -96,7 +93,7 @@ var lowlights = &models.Lowlights{ FullName: "Unusual Whales", Username: "@unusual_whales", Avatar: &models.Image{ - Src: global.AvatarUnusualWhales.Src(), + Src: models.AvatarUnusualWhales.Src(), Width: "44", Height: "44", }, @@ -138,7 +135,7 @@ func Lowlights() templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(lowlights.Heading) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_lowlights.templ`, Line: 111, Col: 25} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/lowlights.templ`, Line: 108, Col: 25} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -200,7 +197,7 @@ func quoteItem(quote *models.Testimonial) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(quote.Avatar.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_lowlights.templ`, Line: 156, Col: 65} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/lowlights.templ`, Line: 153, Col: 65} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -213,7 +210,7 @@ func quoteItem(quote *models.Testimonial) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(quote.Avatar.Width) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_lowlights.templ`, Line: 156, Col: 94} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/lowlights.templ`, Line: 153, Col: 94} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -226,7 +223,7 @@ func quoteItem(quote *models.Testimonial) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(quote.Avatar.Height) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_lowlights.templ`, Line: 156, Col: 125} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/lowlights.templ`, Line: 153, Col: 125} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -239,7 +236,7 @@ func quoteItem(quote *models.Testimonial) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(quote.FullName) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_lowlights.templ`, Line: 158, Col: 74} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/lowlights.templ`, Line: 155, Col: 74} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -252,7 +249,7 @@ func quoteItem(quote *models.Testimonial) templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(quote.Username) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_lowlights.templ`, Line: 160, Col: 107} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/lowlights.templ`, Line: 157, Col: 107} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -265,7 +262,7 @@ func quoteItem(quote *models.Testimonial) templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(quote.Quote) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_lowlights.templ`, Line: 165, Col: 16} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/lowlights.templ`, Line: 162, Col: 16} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { diff --git a/pkg/nebula/marketing/section_mission.templ b/pkg/webapp/components/landing/mission.templ similarity index 99% rename from pkg/nebula/marketing/section_mission.templ rename to pkg/webapp/components/landing/mission.templ index a48e9296b..b1c64ec58 100644 --- a/pkg/nebula/marketing/section_mission.templ +++ b/pkg/webapp/components/landing/mission.templ @@ -1,6 +1,6 @@ -package marketing +package landing -import models "github.com/onsonr/sonr/pkg/nebula/types" +import models "github.com/onsonr/sonr/pkg/webapp/models" // mission is the (3rd) home page mission section var mission = &models.Mission{ diff --git a/pkg/nebula/marketing/section_mission_templ.go b/pkg/webapp/components/landing/mission_templ.go similarity index 94% rename from pkg/nebula/marketing/section_mission_templ.go rename to pkg/webapp/components/landing/mission_templ.go index f5c2da36e..2fccf7548 100644 --- a/pkg/nebula/marketing/section_mission_templ.go +++ b/pkg/webapp/components/landing/mission_templ.go @@ -1,14 +1,14 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package marketing +// templ: version: v0.2.793 +package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import models "github.com/onsonr/sonr/pkg/nebula/types" +import models "github.com/onsonr/sonr/pkg/webapp/models" // mission is the (3rd) home page mission section var mission = &models.Mission{ @@ -60,7 +60,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Eyebrow) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 45, Col: 25} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 45, Col: 25} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -73,7 +73,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Heading) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 50, Col: 25} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 50, Col: 25} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -86,7 +86,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Subtitle) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 53, Col: 26} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 53, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -99,7 +99,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Experience.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 77, Col: 36} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 77, Col: 36} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -112,7 +112,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Experience.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 80, Col: 35} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 80, Col: 35} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -125,7 +125,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Compliance.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 103, Col: 36} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 103, Col: 36} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -138,7 +138,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Compliance.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 106, Col: 35} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 106, Col: 35} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -151,7 +151,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Interoperability.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 129, Col: 42} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 129, Col: 42} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -164,7 +164,7 @@ func Mission() templ.Component { var templ_7745c5c3_Var10 string templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(mission.Interoperability.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marketing/section_mission.templ`, Line: 132, Col: 41} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/mission.templ`, Line: 132, Col: 41} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) if templ_7745c5c3_Err != nil { diff --git a/pkg/nebula/global/ui/badge.templ b/pkg/webapp/components/ui/badges.templ similarity index 100% rename from pkg/nebula/global/ui/badge.templ rename to pkg/webapp/components/ui/badges.templ diff --git a/pkg/nebula/global/ui/badge_templ.go b/pkg/webapp/components/ui/badges_templ.go similarity index 99% rename from pkg/nebula/global/ui/badge_templ.go rename to pkg/webapp/components/ui/badges_templ.go index 606c77c21..ffc481bfa 100644 --- a/pkg/nebula/global/ui/badge_templ.go +++ b/pkg/webapp/components/ui/badges_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/buttons.templ b/pkg/webapp/components/ui/buttons.templ new file mode 100644 index 000000000..b4f23e3ef --- /dev/null +++ b/pkg/webapp/components/ui/buttons.templ @@ -0,0 +1,31 @@ +package ui + +templ PrimaryButton(href string, text string) { +
    +
    + { text } +
    +
    +} + +templ SecondaryButton(href string, text string) { +
    +
    { text }
    +
    +} + +type button struct { + variant Variant + hxGet string + hxPost string + hxTarget string + hxTrigger string + hxSwap string +} + +templ GithubLoginButton() { + +} diff --git a/pkg/webapp/components/ui/buttons_templ.go b/pkg/webapp/components/ui/buttons_templ.go new file mode 100644 index 000000000..e53fd6e65 --- /dev/null +++ b/pkg/webapp/components/ui/buttons_templ.go @@ -0,0 +1,146 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package ui + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func PrimaryButton(href string, text string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(text) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/buttons.templ`, Line: 6, Col: 9} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func SecondaryButton(href string, text string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(text) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/buttons.templ`, Line: 13, Col: 175} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +type button struct { + variant Variant + hxGet string + hxPost string + hxTarget string + hxTrigger string + hxSwap string +} + +func GithubLoginButton() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var6 := templ.GetChildren(ctx) + if templ_7745c5c3_Var6 == nil { + templ_7745c5c3_Var6 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/global/ui/card.templ b/pkg/webapp/components/ui/cards.templ similarity index 95% rename from pkg/nebula/global/ui/card.templ rename to pkg/webapp/components/ui/cards.templ index 7e70704f2..127b92bb9 100644 --- a/pkg/nebula/global/ui/card.templ +++ b/pkg/webapp/components/ui/cards.templ @@ -1,8 +1,6 @@ package ui -import "github.com/onsonr/sonr/pkg/nebula/global/styles" - -func Card(id string, size styles.Size) templ.Component { +func Card(id string, size Size) templ.Component { return renderCard(id, size.CardAttributes()) } diff --git a/pkg/nebula/global/ui/card_templ.go b/pkg/webapp/components/ui/cards_templ.go similarity index 95% rename from pkg/nebula/global/ui/card_templ.go rename to pkg/webapp/components/ui/cards_templ.go index 1a3134242..ca641cded 100644 --- a/pkg/nebula/global/ui/card_templ.go +++ b/pkg/webapp/components/ui/cards_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,9 +8,7 @@ package ui import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import "github.com/onsonr/sonr/pkg/nebula/global/styles" - -func Card(id string, size styles.Size) templ.Component { +func Card(id string, size Size) templ.Component { return renderCard(id, size.CardAttributes()) } @@ -42,7 +40,7 @@ func renderCard(id string, attrs templ.Attributes) templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(id) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/ui/card.templ`, Line: 10, Col: 13} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/cards.templ`, Line: 8, Col: 13} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { diff --git a/pkg/webapp/components/ui/icon.templ b/pkg/webapp/components/ui/icon.templ new file mode 100644 index 000000000..f1ba979a7 --- /dev/null +++ b/pkg/webapp/components/ui/icon.templ @@ -0,0 +1,53 @@ +package ui + +import "fmt" + +type FontAwesome string + +type IconFunc func(name string) templ.Component + +const ( + FaSolid FontAwesome = "fa-solid" + FaRegular FontAwesome = "fa-regular" + FaLight FontAwesome = "fa-light" + FaThin FontAwesome = "fa-thin" + FaDuotone FontAwesome = "fa-duotone fa-solid" + + FaSharpSolid FontAwesome = "fa-sharp fa-solid" + FaSharpRegular FontAwesome = "fa-sharp fa-regular" + FaSharpLight FontAwesome = "fa-sharp fa-light" + FaSharpThin FontAwesome = "fa-sharp fa-thin" + FaSharpDuotone FontAwesome = "fa-sharp-duotone fa-solid" + + FaBrands FontAwesome = "fa-brands" +) + +func Icon(s FontAwesome) IconFunc { + return func(name string) templ.Component { + return renderIcon(s, name) + } +} + +func renderIcon(s FontAwesome, name string) templ.Component { + return faIcon(formatIconClass(s, name)) +} + +func formatIconClass(s FontAwesome, name string) string { + return fmt.Sprintf("%s %s", string(s), name) +} + +templ faIcon(class string) { + +} + +templ RegularIcon() { +} + +templ LightIcon() { +} + +templ ThinIcon() { +} + +templ BrandsIcon() { +} diff --git a/pkg/webapp/components/ui/icon_templ.go b/pkg/webapp/components/ui/icon_templ.go new file mode 100644 index 000000000..040e75f23 --- /dev/null +++ b/pkg/webapp/components/ui/icon_templ.go @@ -0,0 +1,194 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package ui + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "fmt" + +type FontAwesome string + +type IconFunc func(name string) templ.Component + +const ( + FaSolid FontAwesome = "fa-solid" + FaRegular FontAwesome = "fa-regular" + FaLight FontAwesome = "fa-light" + FaThin FontAwesome = "fa-thin" + FaDuotone FontAwesome = "fa-duotone fa-solid" + + FaSharpSolid FontAwesome = "fa-sharp fa-solid" + FaSharpRegular FontAwesome = "fa-sharp fa-regular" + FaSharpLight FontAwesome = "fa-sharp fa-light" + FaSharpThin FontAwesome = "fa-sharp fa-thin" + FaSharpDuotone FontAwesome = "fa-sharp-duotone fa-solid" + + FaBrands FontAwesome = "fa-brands" +) + +func Icon(s FontAwesome) IconFunc { + return func(name string) templ.Component { + return renderIcon(s, name) + } +} + +func renderIcon(s FontAwesome, name string) templ.Component { + return faIcon(formatIconClass(s, name)) +} + +func formatIconClass(s FontAwesome, name string) string { + return fmt.Sprintf("%s %s", string(s), name) +} + +func faIcon(class string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + var templ_7745c5c3_Var2 = []any{class} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func RegularIcon() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return templ_7745c5c3_Err + }) +} + +func LightIcon() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return templ_7745c5c3_Err + }) +} + +func ThinIcon() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var6 := templ.GetChildren(ctx) + if templ_7745c5c3_Var6 == nil { + templ_7745c5c3_Var6 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return templ_7745c5c3_Err + }) +} + +func BrandsIcon() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var7 := templ.GetChildren(ctx) + if templ_7745c5c3_Var7 == nil { + templ_7745c5c3_Var7 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/global/styles/layout.templ b/pkg/webapp/components/ui/layout.templ similarity index 56% rename from pkg/nebula/global/styles/layout.templ rename to pkg/webapp/components/ui/layout.templ index 52c108f9e..d7d1b9ae3 100644 --- a/pkg/nebula/global/styles/layout.templ +++ b/pkg/webapp/components/ui/layout.templ @@ -1,9 +1,4 @@ -package styles - -// Icon is a component that renders an icon -type Icon interface { - Render() templ.Component -} +package ui // Variant is a component that has attributes type Variant interface { @@ -26,10 +21,10 @@ templ Layout(title string, remote bool) { - @Fonts() @Styles() @Htmx() @Alpine() + @WebAwesome() @@ -54,10 +49,10 @@ templ LayoutNoBody(title string, remote bool) { - @Fonts() @Styles() @Htmx() @Alpine() + @WebAwesome() @@ -127,6 +122,50 @@ templ OpenModal(title, description string) { } +templ FullScreenModal() { +
    + +
    +} + // Rows is a component that renders a flex container with a gap of 2 and a max width of 100% templ Rows() {
    @@ -138,3 +177,12 @@ templ Rows() { templ Spacer() {
    } + +templ Separator(text string) { +
    +
    +
    + { text } +
    +
    +} diff --git a/pkg/nebula/global/styles/layout_templ.go b/pkg/webapp/components/ui/layout_templ.go similarity index 70% rename from pkg/nebula/global/styles/layout_templ.go rename to pkg/webapp/components/ui/layout_templ.go index e53834494..8aa496d19 100644 --- a/pkg/nebula/global/styles/layout_templ.go +++ b/pkg/webapp/components/ui/layout_templ.go @@ -1,18 +1,13 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package styles +// templ: version: v0.2.793 +package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -// Icon is a component that renders an icon -type Icon interface { - Render() templ.Component -} - // Variant is a component that has attributes type Variant interface { Attributes() templ.Attributes @@ -86,10 +81,6 @@ func Layout(title string, remote bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = Fonts().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } templ_7745c5c3_Err = Styles().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -102,6 +93,10 @@ func Layout(title string, remote bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + templ_7745c5c3_Err = WebAwesome().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -109,7 +104,7 @@ func Layout(title string, remote bool) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/layout.templ`, Line: 36, Col: 17} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/layout.templ`, Line: 31, Col: 17} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -183,10 +178,6 @@ func LayoutNoBody(title string, remote bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = Fonts().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } templ_7745c5c3_Err = Styles().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -199,6 +190,10 @@ func LayoutNoBody(title string, remote bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + templ_7745c5c3_Err = WebAwesome().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -206,7 +201,7 @@ func LayoutNoBody(title string, remote bool) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/layout.templ`, Line: 64, Col: 17} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/layout.templ`, Line: 59, Col: 17} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -283,7 +278,7 @@ func OpenModal(title, description string) templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/layout.templ`, Line: 115, Col: 47} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/layout.templ`, Line: 110, Col: 47} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -296,7 +291,7 @@ func OpenModal(title, description string) templ.Component { var templ_7745c5c3_Var10 string templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(description) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/layout.templ`, Line: 121, Col: 22} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/layout.templ`, Line: 116, Col: 22} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) if templ_7745c5c3_Err != nil { @@ -318,6 +313,43 @@ func OpenModal(title, description string) templ.Component { }) } +func FullScreenModal() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var11 := templ.GetChildren(ctx) + if templ_7745c5c3_Var11 == nil { + templ_7745c5c3_Var11 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-data=\"{ fullscreenModal: true }\" x-init=\"\n$watch('fullscreenModal', function(value){\nif(value === true){\ndocument.body.classList.add('overflow-hidden');\n}else{\ndocument.body.classList.remove('overflow-hidden');\n}\n})\n\" @keydown.escape=\"fullscreenModal=false\"><template x-teleport=\"body\"><div x-show=\"fullscreenModal\" x-transition:enter=\"transition ease-out duration-150\" x-transition:enter-start=\"opacity-0\" x-transition:enter-end=\"opacity-100\" x-transition:leave=\"transition ease-in duration-150\" x-transition:leave-start=\"opacity-100\" x-transition:leave-end=\"opacity-0\" class=\"flex fixed inset-0 z-[99] w-screen h-screen bg-white\"><button @click=\"fullscreenModal=false\" class=\"absolute top-0 right-0 z-30 flex items-center justify-center px-3 py-3 mt-5 mr-3 space-x-1 text-xs font-medium uppercase rounded-full text-zinc-500 hover:bg-zinc-200\"><svg class=\"w-8 h-8\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></button><div class=\"relative top-0 bottom-0 right-0 flex-shrink-0 hidden w-1/3 overflow-hidden bg-cover lg:block\"><a href=\"#_\" class=\"absolute bottom-0 left-0 z-30 inline-flex items-end mb-4 ml-3 font-sans text-2xl font-extrabold text-left text-white no-underline bg-transparent cursor-pointer group focus:no-underline\"><svg class=\"w-auto h-4 text-white fill-current lg:h-5\" viewBox=\"0 0 355 99\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><defs><path d=\"M119.1 87V66.4h19.8c34.3 0 34.2-49.5 0-49.5-11 0-22 .1-33 .1v70h13.2zm19.8-32.7h-19.8V29.5h19.8c16.8 0 16.9 24.8 0 24.8zm32.6-30.5c0 9.5 14.4 9.5 14.4 0s-14.4-9.5-14.4 0zM184.8 87V37.5h-12.2V87h12.2zm22.8 0V61.8c0-7.5 5.1-13.8 12.6-13.8 7.8 0 11.9 5.7 11.9 13.2V87h12.2V61.1c0-15.5-9.3-24.2-20.9-24.2-6.2 0-11.2 2.5-16.2 7.4l-.8-6.7h-10.9V87h12.1zm72.1 1.3c7.5 0 16-2.6 21.2-8l-7.8-7.7c-2.8 2.9-8.7 4.6-13.2 4.6-8.6 0-13.9-4.4-14.7-10.5h38.5c1.9-20.3-8.4-30.5-24.9-30.5-16 0-26.2 10.8-26.2 25.8 0 15.8 10.1 26.3 27.1 26.3zM292 56.6h-26.6c1.8-6.4 7.2-9.6 13.8-9.6 7 0 12 3.2 12.8 9.6zm41.2 32.1c14.1 0 21.2-7.5 21.2-16.2 0-13.1-11.8-15.2-21.1-15.8-6.3-.4-9.2-2.2-9.2-5.4 0-3.1 3.2-4.9 9-4.9 4.7 0 8.7 1.1 12.2 4.4l6.8-8c-5.7-5-11.5-6.5-19.2-6.5-9 0-20.8 4-20.8 15.4 0 11.2 11.1 14.6 20.4 15.3 7 .4 9.8 1.8 9.8 5.2 0 3.6-4.3 6-8.9 5.9-5.5-.1-13.5-3-17-6.9l-6 8.7c7.2 7.5 15 8.8 22.8 8.8z\" id=\"a\"></path></defs><g fill=\"none\" fill-rule=\"evenodd\"><g fill=\"currentColor\"><path d=\"M19.742 49h28.516L68 83H0l19.742-34z\"></path><path d=\"M26 69h14v30H26V69zM4 50L33.127 0 63 50H4z\"></path></g><g fill-rule=\"nonzero\"><use fill=\"currentColor\" xlink:href=\"#a\"></use><use fill=\"currentColor\" xlink:href=\"#a\"></use></g></g></svg> <span class=\"flex opacity-90 group-hover:scale-150 group-hover:opacity-100 items-center h-full group-hover:-rotate-6 ease-out duration-500 px-0.5 py-px ml-2 -translate-x-px text-[0.6rem] font-bold leading-none border-[2px] rounded border-white -translate-y-px\">UI</span></a><div class=\"absolute inset-0 z-20 w-full h-full opacity-70 bg-gradient-to-t from-black\"></div><img src=\"https://cdn.devdojo.com/images/may2023/pines-bg-1.png\" class=\"z-10 object-cover w-full h-full\"></div><div class=\"relative flex flex-wrap items-center w-full h-full px-8\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var11.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></template></div>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + // Rows is a component that renders a flex container with a gap of 2 and a max width of 100% func Rows() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { @@ -335,16 +367,16 @@ func Rows() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var11 := templ.GetChildren(ctx) - if templ_7745c5c3_Var11 == nil { - templ_7745c5c3_Var11 = templ.NopComponent + templ_7745c5c3_Var12 := templ.GetChildren(ctx) + if templ_7745c5c3_Var12 == nil { + templ_7745c5c3_Var12 = templ.NopComponent } ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex flex-row w-full gap-2 md:gap-4\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templ_7745c5c3_Var11.Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = templ_7745c5c3_Var12.Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -373,9 +405,9 @@ func Spacer() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var12 := templ.GetChildren(ctx) - if templ_7745c5c3_Var12 == nil { - templ_7745c5c3_Var12 = templ.NopComponent + templ_7745c5c3_Var13 := templ.GetChildren(ctx) + if templ_7745c5c3_Var13 == nil { + templ_7745c5c3_Var13 = templ.NopComponent } ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<br>") @@ -386,4 +418,46 @@ func Spacer() templ.Component { }) } +func Separator(text string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var14 := templ.GetChildren(ctx) + if templ_7745c5c3_Var14 == nil { + templ_7745c5c3_Var14 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative py-6\"><div class=\"absolute inset-0 flex items-center\"><span class=\"w-full border-t\"></span></div><div class=\"relative flex justify-center text-xs uppercase\"><span class=\"px-2 bg-white text-neutral-500\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(text) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/layout.templ`, Line: 185, Col: 54} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span></div></div>") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/global/ui/panel.templ b/pkg/webapp/components/ui/panels.templ similarity index 97% rename from pkg/nebula/global/ui/panel.templ rename to pkg/webapp/components/ui/panels.templ index dee59aaa1..a705a938d 100644 --- a/pkg/nebula/global/ui/panel.templ +++ b/pkg/webapp/components/ui/panels.templ @@ -1,8 +1,5 @@ package ui - -import "github.com/labstack/echo/v4" - templ Breadcrumbs() { <nav class="flex justify-between px-3.5 py-1 rounded-md pb-3"> <ol class="inline-flex items-center mb-3 space-x-1 text-xs text-neutral-500 [&_.active-breadcrumb]:text-neutral-600 [&_.active-breadcrumb]:font-medium sm:mb-0"> @@ -36,5 +33,3 @@ templ breadcrumbIcon() { <path d="M55.603 76.6744L76.6993 55.5798C79.6327 52.6465 84.3888 52.6465 87.3223 55.5797L108.419 76.6744C111.352 79.6077 111.352 84.3634 108.419 87.2966L87.3223 108.391C84.3888 111.325 79.6327 111.325 76.6993 108.391L55.603 87.2966C52.6696 84.3634 52.6696 79.6077 55.603 76.6744Z" fill="currentColor"></path> </svg> } -templ Panel(c echo.Context, id string) { -} diff --git a/pkg/nebula/global/ui/panel_templ.go b/pkg/webapp/components/ui/panels_templ.go similarity index 88% rename from pkg/nebula/global/ui/panel_templ.go rename to pkg/webapp/components/ui/panels_templ.go index 544c0c6e3..a7df7e25c 100644 --- a/pkg/nebula/global/ui/panel_templ.go +++ b/pkg/webapp/components/ui/panels_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,8 +8,6 @@ package ui import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import "github.com/labstack/echo/v4" - func Breadcrumbs() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -100,7 +98,7 @@ func breadcrumbItem(title string, active bool) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/ui/panel.templ`, Line: 26, Col: 126} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/panels.templ`, Line: 23, Col: 126} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -118,7 +116,7 @@ func breadcrumbItem(title string, active bool) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/ui/panel.templ`, Line: 28, Col: 118} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/panels.templ`, Line: 25, Col: 118} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -162,29 +160,4 @@ func breadcrumbIcon() templ.Component { }) } -func Panel(c echo.Context, id string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var6 := templ.GetChildren(ctx) - if templ_7745c5c3_Var6 == nil { - templ_7745c5c3_Var6 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - return templ_7745c5c3_Err - }) -} - var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/global/styles/scripts.templ b/pkg/webapp/components/ui/scripts.templ similarity index 84% rename from pkg/nebula/global/styles/scripts.templ rename to pkg/webapp/components/ui/scripts.templ index 18f463e7b..38dafe6da 100644 --- a/pkg/nebula/global/styles/scripts.templ +++ b/pkg/webapp/components/ui/scripts.templ @@ -1,4 +1,4 @@ -package styles +package ui const ( PublicOrigin = "https://cdn.sonr.id" @@ -11,13 +11,9 @@ var ( htmxHandle = templ.NewOnceHandle() ) -templ Fonts() { - <link rel="preload" href="https://cdn.sonr.id/fonts/ZTBrosOskon90s-BoldSemExp.woff2" as="font" type="font/woff2" crossorigin/> - <link rel="preload" href="https://cdn.sonr.id/fonts/ZTBrosOskon90s-BoldSemExpIta.woff2" as="font" type="font/woff2" crossorigin/> -} - templ Styles() { <link href={ "https://cdn.sonr.id/css/styles.css" } rel="stylesheet"/> + <script src="https://kit.fontawesome.com/9909219bb5.js" crossorigin="anonymous"></script> } templ Alpine() { @@ -33,6 +29,11 @@ templ Htmx() { <script src={ "https://cdn.sonr.id/js/htmx.min.js" }></script> } +templ WebAwesome() { + <script type="module" src="https://early.webawesome.com/webawesome@3.0.0-alpha.4/dist/webawesome.loader.js"></script> + <link rel="stylesheet" href="https://early.webawesome.com/webawesome@3.0.0-alpha.4/dist/themes/default.css"/> +} + templ Toaster() { <div x-data="{ diff --git a/pkg/nebula/global/styles/scripts_templ.go b/pkg/webapp/components/ui/scripts_templ.go similarity index 81% rename from pkg/nebula/global/styles/scripts_templ.go rename to pkg/webapp/components/ui/scripts_templ.go index 221115f0b..86e24b9d6 100644 --- a/pkg/nebula/global/styles/scripts_templ.go +++ b/pkg/webapp/components/ui/scripts_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package styles +// templ: version: v0.2.793 +package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -19,7 +19,7 @@ var ( htmxHandle = templ.NewOnceHandle() ) -func Fonts() templ.Component { +func Styles() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -40,49 +40,20 @@ func Fonts() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"preload\" href=\"https://cdn.sonr.id/fonts/ZTBrosOskon90s-BoldSemExp.woff2\" as=\"font\" type=\"font/woff2\" crossorigin><link rel=\"preload\" href=\"https://cdn.sonr.id/fonts/ZTBrosOskon90s-BoldSemExpIta.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func Styles() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link href=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/css/styles.css") + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/css/styles.css") if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/scripts.templ`, Line: 20, Col: 50} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/scripts.templ`, Line: 15, Col: 50} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" rel=\"stylesheet\">") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" rel=\"stylesheet\"><script src=\"https://kit.fontawesome.com/9909219bb5.js\" crossorigin=\"anonymous\"></script>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -106,21 +77,21 @@ func Alpine() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var4 := templ.GetChildren(ctx) - if templ_7745c5c3_Var4 == nil { - templ_7745c5c3_Var4 = templ.NopComponent + templ_7745c5c3_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script src=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/js/alpine-focus.min.js") + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/js/alpine-focus.min.js") if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/scripts.templ`, Line: 24, Col: 59} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/scripts.templ`, Line: 20, Col: 59} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -128,12 +99,12 @@ func Alpine() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/js/alpine.min.js") + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/js/alpine.min.js") if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/scripts.templ`, Line: 25, Col: 53} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/scripts.templ`, Line: 21, Col: 53} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -161,21 +132,21 @@ func Dexie() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var7 := templ.GetChildren(ctx) - if templ_7745c5c3_Var7 == nil { - templ_7745c5c3_Var7 = templ.NopComponent + templ_7745c5c3_Var6 := templ.GetChildren(ctx) + if templ_7745c5c3_Var6 == nil { + templ_7745c5c3_Var6 = templ.NopComponent } ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script src=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var8 string - templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/js/dexie.min.js") + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/js/dexie.min.js") if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/scripts.templ`, Line: 29, Col: 52} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/scripts.templ`, Line: 25, Col: 52} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -203,21 +174,21 @@ func Htmx() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var9 := templ.GetChildren(ctx) - if templ_7745c5c3_Var9 == nil { - templ_7745c5c3_Var9 = templ.NopComponent + templ_7745c5c3_Var8 := templ.GetChildren(ctx) + if templ_7745c5c3_Var8 == nil { + templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script src=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var10 string - templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/js/htmx.min.js") + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs("https://cdn.sonr.id/js/htmx.min.js") if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/scripts.templ`, Line: 33, Col: 51} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/scripts.templ`, Line: 29, Col: 51} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -229,6 +200,35 @@ func Htmx() templ.Component { }) } +func WebAwesome() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var10 := templ.GetChildren(ctx) + if templ_7745c5c3_Var10 == nil { + templ_7745c5c3_Var10 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script type=\"module\" src=\"https://early.webawesome.com/webawesome@3.0.0-alpha.4/dist/webawesome.loader.js\"></script><link rel=\"stylesheet\" href=\"https://early.webawesome.com/webawesome@3.0.0-alpha.4/dist/themes/default.css\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + func Toaster() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context diff --git a/pkg/nebula/global/styles/sizes.templ b/pkg/webapp/components/ui/sizes.templ similarity index 98% rename from pkg/nebula/global/styles/sizes.templ rename to pkg/webapp/components/ui/sizes.templ index 1059a817c..a12063c4d 100644 --- a/pkg/nebula/global/styles/sizes.templ +++ b/pkg/webapp/components/ui/sizes.templ @@ -1,4 +1,4 @@ -package styles +package ui type Size int diff --git a/pkg/nebula/global/styles/sizes_templ.go b/pkg/webapp/components/ui/sizes_templ.go similarity index 96% rename from pkg/nebula/global/styles/sizes_templ.go rename to pkg/webapp/components/ui/sizes_templ.go index 4e9555a0c..52047ba52 100644 --- a/pkg/nebula/global/styles/sizes_templ.go +++ b/pkg/webapp/components/ui/sizes_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package styles +// templ: version: v0.2.793 +package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/nebula/global/styles/typography.templ b/pkg/webapp/components/ui/typography.templ similarity index 98% rename from pkg/nebula/global/styles/typography.templ rename to pkg/webapp/components/ui/typography.templ index f75c3e699..bd3a26146 100644 --- a/pkg/nebula/global/styles/typography.templ +++ b/pkg/webapp/components/ui/typography.templ @@ -1,4 +1,4 @@ -package styles +package ui func H1(content string) templ.Component { return renderText(1, content) diff --git a/pkg/nebula/global/styles/typography_templ.go b/pkg/webapp/components/ui/typography_templ.go similarity index 91% rename from pkg/nebula/global/styles/typography_templ.go rename to pkg/webapp/components/ui/typography_templ.go index 7c924ef49..c0ac9d207 100644 --- a/pkg/nebula/global/styles/typography_templ.go +++ b/pkg/webapp/components/ui/typography_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package styles +// templ: version: v0.2.793 +package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -54,7 +54,7 @@ func renderText(level int, text string) templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/typography.templ`, Line: 23, Col: 10} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/typography.templ`, Line: 23, Col: 10} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -72,7 +72,7 @@ func renderText(level int, text string) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/typography.templ`, Line: 27, Col: 10} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/typography.templ`, Line: 27, Col: 10} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -90,7 +90,7 @@ func renderText(level int, text string) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/typography.templ`, Line: 31, Col: 10} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/typography.templ`, Line: 31, Col: 10} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -108,7 +108,7 @@ func renderText(level int, text string) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/typography.templ`, Line: 35, Col: 10} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/typography.templ`, Line: 35, Col: 10} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -159,7 +159,7 @@ func renderLink(attrs templ.Attributes, text string) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/typography.templ`, Line: 42, Col: 8} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/typography.templ`, Line: 42, Col: 8} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -209,7 +209,7 @@ func renderStrong(attrs templ.Attributes, text string) templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/typography.templ`, Line: 48, Col: 8} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/typography.templ`, Line: 48, Col: 8} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -259,7 +259,7 @@ func renderEmphasis(attrs templ.Attributes, text string) templ.Component { var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/typography.templ`, Line: 54, Col: 8} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/typography.templ`, Line: 54, Col: 8} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { @@ -309,7 +309,7 @@ func renderCode(attrs templ.Attributes, text string) templ.Component { var templ_7745c5c3_Var13 string templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(text) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `global/styles/typography.templ`, Line: 60, Col: 8} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/ui/typography.templ`, Line: 60, Col: 8} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { diff --git a/pkg/webapp/models/base.go b/pkg/webapp/models/base.go new file mode 100644 index 000000000..3e60cfc19 --- /dev/null +++ b/pkg/webapp/models/base.go @@ -0,0 +1,12 @@ +package models + +type NavHeader struct { + Logo *Image + Primary *NavItem + Items []*NavItem +} + +type NavItem struct { + Text string + Href string +} diff --git a/pkg/nebula/global/images.go b/pkg/webapp/models/cdn.go similarity index 66% rename from pkg/nebula/global/images.go rename to pkg/webapp/models/cdn.go index 847f20ede..51c67d37b 100644 --- a/pkg/nebula/global/images.go +++ b/pkg/webapp/models/cdn.go @@ -1,4 +1,4 @@ -package global +package models import "fmt" @@ -27,7 +27,7 @@ func (a Avatar) Src() string { } // ╭───────────────────────────────────────────────────────────╮ -// │ SVG CDN Illustrations │ +// │ General Illustrations │ // ╰───────────────────────────────────────────────────────────╯ type Illustration string @@ -68,3 +68,34 @@ const ( func (i Illustration) Src() string { return fmt.Sprintf("https://cdn.sonr.id/img/illustrations/%s.svg", string(i)) } + +// ╭───────────────────────────────────────────────────────────╮ +// │ Empty State Illustrations │ +// ╰───────────────────────────────────────────────────────────╯ + +type ErrorIllustration string + +const ( + ErrorIllustration404 ErrorIllustration = "404" + ErrorIllustrationEmptyCart ErrorIllustration = "empty-cart" + ErrorIllustrationEmptyMessages ErrorIllustration = "empty-messages" + ErrorIllustrationEmptyNotifications ErrorIllustration = "empty-notifications" + ErrorIllustrationEmptySearch ErrorIllustration = "empty-search" + ErrorIllustrationFileNotFound ErrorIllustration = "file-not-found" + ErrorIllustratinInternalError ErrorIllustration = "internal-error" + ErrorIllustrationNoConnection ErrorIllustration = "no-connection" + ErrorIllustrationOrderNotFound ErrorIllustration = "order-not-found" + ErrorIllustrationPaymentFailed ErrorIllustration = "payment-failed" +) + +func (e ErrorIllustration) SrcDefault() string { + return fmt.Sprintf("https://cdn.sonr.id/img/empty-state/default/%s.svg", string(e)) +} + +func (e ErrorIllustration) SrcMono() string { + return fmt.Sprintf("https://cdn.sonr.id/img/empty-state/mono/%s.svg", string(e)) +} + +func (e ErrorIllustration) SrcRetro() string { + return fmt.Sprintf("https://cdn.sonr.id/img/empty-state/retro/%s.svg", string(e)) +} diff --git a/pkg/webapp/models/forms.go b/pkg/webapp/models/forms.go new file mode 100644 index 000000000..6ed7bdf8b --- /dev/null +++ b/pkg/webapp/models/forms.go @@ -0,0 +1,8 @@ +package models + +type BasicDetails struct { + FirstName string `json:"firstName" form:"firstName"` + LastName string `json:"lastName" form:"lastName"` + Email string `json:"email" form:"email"` + Password string `json:"password" form:"password"` +} diff --git a/pkg/nebula/types/marketing.go b/pkg/webapp/models/marketing.go similarity index 99% rename from pkg/nebula/types/marketing.go rename to pkg/webapp/models/marketing.go index e035f71f0..a9f92c184 100644 --- a/pkg/nebula/types/marketing.go +++ b/pkg/webapp/models/marketing.go @@ -1,4 +1,4 @@ -package types +package models type Button struct { Text string diff --git a/pkg/webapp/models/page.go b/pkg/webapp/models/page.go new file mode 100644 index 000000000..1c4004cb5 --- /dev/null +++ b/pkg/webapp/models/page.go @@ -0,0 +1,12 @@ +package models + +type Metadata struct { + Title string `json:"title"` + Description string `json:"description"` + OpenGraphImage string `json:"openGraphImage"` + TwitterImage string `json:"twitterImage"` + Tags string `json:"tags"` + Category string `json:"category"` + Favicon string `json:"favicon"` + URL string `json:"url"` +} diff --git a/pkg/nebula/package.json b/pkg/webapp/package.json similarity index 50% rename from pkg/nebula/package.json rename to pkg/webapp/package.json index 04e124ec2..88e2d0810 100644 --- a/pkg/nebula/package.json +++ b/pkg/webapp/package.json @@ -2,15 +2,11 @@ "name": "@onsonr/nebula", "version": "0.0.2", "scripts": { - "fetch:deps": "bun run deps.mjs", - "build:css": "bunx tailwindcss -i ./global/styles/globals.css -o ./assets/css/styles.css", - "build": "bun run fetch:deps && bun run build:css" + "build": "bunx tailwindcss -i ./components/globals.css -o ./components/styles/styles.css" }, "dependencies": { - "node-fetch": "^3.3.2", "@tailwindcss/forms": "^0.5.7", "@tailwindcss/typography": "^0.5.15", - "sonr-es": "^0.5.3", "tailwindcss": "^3.3.0", "tailwindcss-motion": "^0.3.0-beta" } diff --git a/pkg/webapp/pages/auth.templ b/pkg/webapp/pages/auth.templ new file mode 100644 index 000000000..13cb94b8a --- /dev/null +++ b/pkg/webapp/pages/auth.templ @@ -0,0 +1,16 @@ +package pages + +import ( + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/webapp/components/auth" +) + +templ AuthPage() { + if session.GetData(ctx).IsMobile { + if session.GetData(ctx).Challenge == "" { + @auth.LoginModal() + } + @auth.RegisterModal() + } + @auth.RedirectModal() +} diff --git a/pkg/nebula/views/current_templ.go b/pkg/webapp/pages/auth_templ.go similarity index 60% rename from pkg/nebula/views/current_templ.go rename to pkg/webapp/pages/auth_templ.go index d03fbab4d..79fcf26db 100644 --- a/pkg/nebula/views/current_templ.go +++ b/pkg/webapp/pages/auth_templ.go @@ -1,17 +1,19 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package views +// templ: version: v0.2.793 +package pages //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import echo "github.com/labstack/echo/v4" +import ( + "github.com/onsonr/sonr/pkg/common/middleware/session" + "github.com/onsonr/sonr/pkg/webapp/components/auth" +) -// CurrentView checks if the user is logged in. -func CurrentView(c echo.Context) templ.Component { +func AuthPage() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -32,7 +34,23 @@ func CurrentView(c echo.Context) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"container\"><div class=\"row\"><div class=\"col-md-12\"><div class=\"card\"><div class=\"card-header\"><h3 class=\"card-title\">Current Account</h3></div><div class=\"card-body\"><p class=\"card-text\"><a href=\"/logout\">Logout</a></p></div></div></div></div></div>") + if session.GetData(ctx).IsMobile { + if session.GetData(ctx).Challenge == "" { + templ_7745c5c3_Err = auth.LoginModal().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = auth.RegisterModal().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = auth.RedirectModal().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/webapp/pages/dashboard.templ b/pkg/webapp/pages/dashboard.templ new file mode 100644 index 000000000..76652d8d9 --- /dev/null +++ b/pkg/webapp/pages/dashboard.templ @@ -0,0 +1,8 @@ +package pages + +import "github.com/onsonr/sonr/pkg/webapp/components/ui" + +templ DashboardPage() { + @ui.LayoutNoBody("Sonr.ID", true) { + } +} diff --git a/pkg/webapp/pages/dashboard_templ.go b/pkg/webapp/pages/dashboard_templ.go new file mode 100644 index 000000000..ed2ca5ca4 --- /dev/null +++ b/pkg/webapp/pages/dashboard_templ.go @@ -0,0 +1,56 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package pages + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "github.com/onsonr/sonr/pkg/webapp/components/ui" + +func DashboardPage() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = ui.LayoutNoBody("Sonr.ID", true).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/nebula/marketing/page.templ b/pkg/webapp/pages/landing.templ similarity index 55% rename from pkg/nebula/marketing/page.templ rename to pkg/webapp/pages/landing.templ index 5a13b678e..a6399fed8 100644 --- a/pkg/nebula/marketing/page.templ +++ b/pkg/webapp/pages/landing.templ @@ -1,21 +1,25 @@ -package marketing -import "github.com/onsonr/sonr/pkg/nebula/global/styles" +package pages + +import ( + "github.com/onsonr/sonr/pkg/webapp/components/landing" + "github.com/onsonr/sonr/pkg/webapp/components/ui" +) // ╭─────────────────────────────────────────────────────────╮ // │ Final Rendering │ // ╰─────────────────────────────────────────────────────────╯ // View renders the home page -templ View() { - @styles.LayoutNoBody("Sonr.ID", true) { - @Header() - @Hero() - @Highlights() - @Mission() - @Architecture() - @Lowlights() - @CallToAction() - @Footer() +templ HomePage() { + @ui.LayoutNoBody("Sonr.ID", true) { + @landing.Header() + @landing.Hero() + @landing.Highlights() + @landing.Mission() + @landing.Architecture() + @landing.Lowlights() + @landing.CallToAction() + @landing.Footer() } } diff --git a/pkg/nebula/marketing/page_templ.go b/pkg/webapp/pages/landing_templ.go similarity index 80% rename from pkg/nebula/marketing/page_templ.go rename to pkg/webapp/pages/landing_templ.go index dc08a6768..4efb12569 100644 --- a/pkg/nebula/marketing/page_templ.go +++ b/pkg/webapp/pages/landing_templ.go @@ -1,21 +1,25 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 -package marketing +// templ: version: v0.2.793 + +package pages //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import "github.com/onsonr/sonr/pkg/nebula/global/styles" +import ( + "github.com/onsonr/sonr/pkg/webapp/components/landing" + "github.com/onsonr/sonr/pkg/webapp/components/ui" +) // ╭─────────────────────────────────────────────────────────╮ // │ Final Rendering │ // ╰─────────────────────────────────────────────────────────╯ // View renders the home page -func View() templ.Component { +func HomePage() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -48,7 +52,7 @@ func View() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = Header().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = landing.Header().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -56,7 +60,7 @@ func View() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = Hero().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = landing.Hero().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -64,7 +68,7 @@ func View() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = Highlights().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = landing.Highlights().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -72,7 +76,7 @@ func View() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = Mission().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = landing.Mission().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -80,7 +84,7 @@ func View() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = Architecture().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = landing.Architecture().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -88,7 +92,7 @@ func View() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = Lowlights().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = landing.Lowlights().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -96,7 +100,7 @@ func View() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = CallToAction().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = landing.CallToAction().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -104,13 +108,13 @@ func View() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = Footer().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = landing.Footer().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return templ_7745c5c3_Err }) - templ_7745c5c3_Err = styles.LayoutNoBody("Sonr.ID", true).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = ui.LayoutNoBody("Sonr.ID", true).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/nebula/tailwind.config.js b/pkg/webapp/tailwind.config.js similarity index 96% rename from pkg/nebula/tailwind.config.js rename to pkg/webapp/tailwind.config.js index 15fc39803..75f8dc08f 100644 --- a/pkg/nebula/tailwind.config.js +++ b/pkg/webapp/tailwind.config.js @@ -1,9 +1,8 @@ // tailwind.config.js module.exports = { content: [ - "./**/*.{templ,html}", "./components/**/*.{templ,html}", - "./global/**/*.{templ,html}", + "./pages/**/*.{templ,html}", ], theme: { extend: { diff --git a/pkl/README.md b/pkl/README.md new file mode 100644 index 000000000..e32b62034 --- /dev/null +++ b/pkl/README.md @@ -0,0 +1,4 @@ +# pkl + +This is a project to generate a language-agnostic, type-safe, and idiomatic +Go code from a [Pkl](https://pkl-lang.org) file. diff --git a/pkl/base.types/Ctx.pkl b/pkl/base.types/Ctx.pkl new file mode 100644 index 000000000..9feef81b7 --- /dev/null +++ b/pkl/base.types/Ctx.pkl @@ -0,0 +1,36 @@ +@go.Package { name = "github.com/onsonr/sonr/pkg/common/types" } + +module common.types.Ctx + +import "package://pkg.pkl-lang.org/pkl-go/pkl.golang@0.5.0#/go.pkl" +import "./DWN.pkl" + +class JsonField extends go.Field { + structTags { + ["json"] = "%{name},omitempty" + } +} + +class Session { + @JsonField + id: String + @JsonField + challenge: String + @JsonField + browserName: String + @JsonField + browserVersion: String + @JsonField + userArchitecture: String + @JsonField + platform: String + @JsonField + platformVersion: String + @JsonField + deviceModel: String + @JsonField + isMobile: Boolean + @JsonField + vaultAddress: String +} + diff --git a/third_party/pkl/src/sonr.configs.v1/DWN.pkl b/pkl/base.types/DWN.pkl similarity index 71% rename from third_party/pkl/src/sonr.configs.v1/DWN.pkl rename to pkl/base.types/DWN.pkl index 546b7da85..055035559 100644 --- a/third_party/pkl/src/sonr.configs.v1/DWN.pkl +++ b/pkl/base.types/DWN.pkl @@ -1,6 +1,6 @@ -@go.Package { name = "github.com/onsonr/sonr/pkg/motr/config" } +@go.Package { name = "github.com/onsonr/sonr/pkg/core/dwn" } -module dwn +module common.types.DWN import "package://pkg.pkl-lang.org/pkl-go/pkl.golang@0.5.0#/go.pkl" @@ -35,6 +35,23 @@ class Config { vaultSchema: Schema } +class Environment { + @JsonField + isDevelopment: Boolean + + @JsonField + cacheVersion: String + + @JsonField + httpserverPath: String + + @JsonField + wasmExecPath: String + + @JsonField + wasmPath: String +} + class Schema { version: Int diff --git a/third_party/pkl/src/sonr.models.v1/ORM.pkl b/pkl/base.types/ORM.pkl similarity index 97% rename from third_party/pkl/src/sonr.models.v1/ORM.pkl rename to pkl/base.types/ORM.pkl index c074e3619..d6a59b1b5 100644 --- a/third_party/pkl/src/sonr.models.v1/ORM.pkl +++ b/pkl/base.types/ORM.pkl @@ -1,9 +1,31 @@ -@go.Package { name = "github.com/onsonr/sonr/pkg/motr/types/orm" } +@go.Package { name = "github.com/onsonr/sonr/pkg/common/models" } -module orm +module common.types.ORM import "package://pkg.pkl-lang.org/pkl-go/pkl.golang@0.5.0#/go.pkl" + +// Enums +typealias AssetType = "native"|"wrapped"|"staking"|"pool"|"ibc"|"cw20" + +typealias DIDMethod = "ipfs"|"sonr"|"bitcoin"|"ethereum"|"ibc"|"webauthn"|"dwn"|"service" + +typealias KeyAlgorithm = "es256"|"es384"|"es512"|"eddsa"|"es256k"|"ecdsa" + +typealias KeyCurve = "p256"|"p384"|"p521"|"x25519"|"x448"|"ed25519"|"ed448"|"secp256k1"|"bls12381"|"keccak256" + +typealias KeyEncoding = "raw"|"hex"|"multibase" + +typealias KeyRole = "authentication"|"assertion"|"delegation"|"invocation" + +typealias KeyType = "octet"|"elliptic"|"rsa"|"symmetric"|"hmac"|"mpc"|"zk"|"webauthn"|"bip32" + +typealias KeyShareRole = "user"|"validator" + +typealias PermissionGrant = "none"|"read"|"write"|"verify"|"broadcast"|"admin" + +typealias PermissionScope = "profile"|"metadata"|"permissions"|"wallets"|"transactions"|"user"|"validator" + typealias Base58 = String typealias Base64 = String @@ -28,27 +50,6 @@ class JsonField extends go.Field { } } -// Enums -typealias AssetType = "native"|"wrapped"|"staking"|"pool"|"ibc"|"cw20" - -typealias DIDMethod = "ipfs"|"sonr"|"bitcoin"|"ethereum"|"ibc"|"webauthn"|"dwn"|"service" - -typealias KeyAlgorithm = "es256"|"es384"|"es512"|"eddsa"|"es256k"|"ecdsa" - -typealias KeyCurve = "p256"|"p384"|"p521"|"x25519"|"x448"|"ed25519"|"ed448"|"secp256k1"|"bls12381"|"keccak256" - -typealias KeyEncoding = "raw"|"hex"|"multibase" - -typealias KeyRole = "authentication"|"assertion"|"delegation"|"invocation" - -typealias KeyType = "octet"|"elliptic"|"rsa"|"symmetric"|"hmac"|"mpc"|"zk"|"webauthn"|"bip32" - -typealias KeyShareRole = "user"|"validator" - -typealias PermissionGrant = "none"|"read"|"write"|"verify"|"broadcast"|"admin" - -typealias PermissionScope = "profile"|"metadata"|"permissions"|"wallets"|"transactions"|"user"|"validator" - class Account { @PrimaryKey diff --git a/pkl/base.types/PklProject b/pkl/base.types/PklProject new file mode 100644 index 000000000..f5363cc8e --- /dev/null +++ b/pkl/base.types/PklProject @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//===----------------------------------------------------------------------===// +/// Common types for operations across the sonr ecosystem +amends "../basePklProject.pkl" + +package { + name = "base.types" + version = "0.0.1" +} diff --git a/pkl/base.types/PklProject.deps.json b/pkl/base.types/PklProject.deps.json new file mode 100644 index 000000000..836079aad --- /dev/null +++ b/pkl/base.types/PklProject.deps.json @@ -0,0 +1,4 @@ +{ + "schemaVersion": 1, + "resolvedDependencies": {} +} \ No newline at end of file diff --git a/pkl/basePklProject.pkl b/pkl/basePklProject.pkl new file mode 100644 index 000000000..0b63c4cc8 --- /dev/null +++ b/pkl/basePklProject.pkl @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//===----------------------------------------------------------------------===// +module basePklProject + +amends "pkl:Project" + +import "pkl:reflect" + +local myModule = reflect.Module(module) + +local packageName: String = + findRootModule(reflect.Module(module)) + .relativePathTo(module) + .last + +local function findRootModule(mod: reflect.Module): Module = + let (supermodule = mod.supermodule) + if (supermodule == null || !supermodule.isAmend) mod.reflectee + else findRootModule(supermodule) + +package { + baseUri = "package://pkl.sh/\(name)@\(version)" + packageZipUrl = "https://github.com/onsonr/sonr/releases/download/\(name)@\(version).zip" + license = "Apache-2.0" + authors { + "Prad N <prad@sonr.email>" + } + description = myModule.docComment + issueTracker = "https://github.com/onsonr/sonr/issues" + sourceCode = "https://github.com/onsonr/sonr/tree/third_party/pkl/packages/\(name)" +} diff --git a/pkl/chain.sonr/App.pkl b/pkl/chain.sonr/App.pkl new file mode 100644 index 000000000..ca9188e55 --- /dev/null +++ b/pkl/chain.sonr/App.pkl @@ -0,0 +1,89 @@ +module config.sonr.App + +import "package://pkg.pkl-lang.org/pkl-pantry/pkl.toml@1.0.0#/toml.pkl" + +class Chain { + `minimum-gas-prices`: String = "0stake" + `query-gas-limit`: String = "0" + pruning: String = "default" + `pruning-keep-recent`: String = "0" + `pruning-interval`: String = "0" + `halt-height`: Int = 0 + `halt-time`: Int = 0 + `min-retain-blocks`: Int = 0 + `inter-block-cache`: Boolean = true + `index-events`: Listing<String> = new {} + `iavl-cache-size`: Int = 781250 + `iavl-disable-fastnode`: Boolean = false + `app-db-backend`: String = "" + telemetry: Telemetry = new {} + api: Api = new {} + grpc: Grpc = new {} + `grpc-web`: GrpcWeb = new {} + `state-sync`: StateSync = new {} + streaming: Streaming = new {} + mempool: Mempool = new {} +} + +class Telemetry { + `service-name`: String = "" + enabled: Boolean = true + `enable-hostname`: Boolean = false + `enable-hostname-label`: Boolean = false + `enable-service-label`: Boolean = false + `prometheus-retention-time`: Int = 60 + `global-labels`: Listing<Listing<String>> = new { + new { + "chain_id" + "chain-NKlMbx" + } + } + `metrics-sink`: String = "" + `statsd-addr`: String = "" + `datadog-hostname`: String = "" +} + +class Api { + enable: Boolean = true + swagger: Boolean = false + address: String = "tcp://0.0.0.0:1317" + `max-open-connections`: Int = 1000 + `rpc-read-timeout`: Int = 10 + `rpc-write-timeout`: Int = 0 + `rpc-max-body-bytes`: Int = 1000000 + `enabled-unsafe-cors`: Boolean = false +} + +class Grpc { + enable: Boolean = true + address: String = "0.0.0.0:9090" + `max-recv-msg-size`: String = "10485760" + `max-send-msg-size`: String = "2147483647" +} + +class GrpcWeb { + enable: Boolean = true +} + +class StateSync { + `snapshot-interval`: Int = 0 + `snapshot-keep-recent`: Int = 2 +} + +class Streaming { + abci: Abci = new {} +} + +class Abci { + keys: Listing<String> = new {} + plugin: String = "" + `stop-node-on-err`: Boolean = true +} + +class Mempool { + `max-txs`: Int = 5000 +} + +output { + renderer = new toml.Renderer {} +} diff --git a/pkl/chain.sonr/Chain.pkl b/pkl/chain.sonr/Chain.pkl new file mode 100644 index 000000000..dc136a8cf --- /dev/null +++ b/pkl/chain.sonr/Chain.pkl @@ -0,0 +1,154 @@ +module config.sonr.Chain + +import "package://pkg.pkl-lang.org/pkl-pantry/pkl.toml@1.0.0#/toml.pkl" + +class Chain { + version: String = "0.38.5" + proxy_app: String = "tcp://127.0.0.1:26658" + moniker: String = "node0" + db_backend: String = "goleveldb" + db_dir: String = "data" + log_level: String = "info" + log_format: String = "plain" + genesis_file: String = "config/genesis.json" + priv_validator_key_file: String = "config/priv_validator_key.json" + priv_validator_state_file: String = "data/priv_validator_state.json" + priv_validator_laddr: String = "" + node_key_file: String = "config/node_key.json" + abci: String = "socket" + filter_peers: Boolean = false + + rpc: Rpc = new {} + p2p: P2p = new {} + mempool: Mempool = new {} + statesync: StateSync = new {} + blocksync: BlockSync = new {} + consensus: Consensus = new {} + storage: Storage = new {} + tx_index: TxIndex = new {} + instrumentation: Instrumentation = new {} +} + +class Rpc { + laddr: String = "tcp://0.0.0.0:26657" + cors_allowed_origins: Listing<String> = new {} + cors_allowed_methods: Listing<String> = new { + "HEAD" + "GET" + "POST" + } + cors_allowed_headers: Listing<String> = new { + "Origin" + "Accept" + "Content-Type" + "X-Requested-With" + "X-Server-Time" + } + grpc_laddr: String = "" + grpc_max_open_connections: Int = 900 + unsafe: Boolean = false + max_open_connections: Int = 900 + max_subscription_clients: Int = 100 + max_subscriptions_per_client: Int = 5 + experimental_subscription_buffer_size: Int = 200 + experimental_websocket_write_buffer_size: Int = 200 + experimental_close_on_slow_client: Boolean = false + timeout_broadcast_tx_commit: String = "10s" + max_body_bytes: Int = 1000000 + max_header_bytes: Int = 1048576 + tls_cert_file: String = "" + tls_key_file: String = "" + pprof_laddr: String = "localhost:6060" +} + +class P2p { + laddr: String = "tcp://0.0.0.0:26656" + external_address: String = "" + seeds: String = "" + persistent_peers: String = "7698b304905ac4459e8bf5fe8f8373aa46a528a5@192.168.0.2:26656,b1aee1db2ac83c57ffe561624ba169bdcd80dc1a@192.168.0.4:26656,cda55214016021246cd26f8991bd842a0c1dc3fb@192.168.0.3:26656" + addr_book_file: String = "config/addrbook.json" + addr_book_strict: Boolean = true + max_num_inbound_peers: Int = 40 + max_num_outbound_peers: Int = 10 + unconditional_peer_ids: String = "" + persistent_peers_max_dial_period: String = "0s" + flush_throttle_timeout: String = "100ms" + max_packet_msg_payload_size: Int = 1024 + send_rate: Int = 5120000 + recv_rate: Int = 5120000 + pex: Boolean = true + seed_mode: Boolean = false + private_peer_ids: String = "" + allow_duplicate_ip: Boolean = false + handshake_timeout: String = "20s" + dial_timeout: String = "3s" +} + +class Mempool { + type: String = "flood" + recheck: Boolean = true + broadcast: Boolean = true + wal_dir: String = "" + size: Int = 5000 + max_txs_bytes: Int = 1073741824 + cache_size: Int = 10000 + `keep-invalid-txs-in-cache`: Boolean = false + max_tx_bytes: Int = 1048576 + max_batch_bytes: Int = 0 + experimental_max_gossip_connections_to_persistent_peers: Int = 0 + experimental_max_gossip_connections_to_non_persistent_peers: Int = 0 +} + +class StateSync { + enable: Boolean = false + rpc_servers: String = "" + trust_height: Int = 0 + trust_hash: String = "" + trust_period: String = "168h0m0s" + discovery_time: String = "15s" + temp_dir: String = "" + chunk_request_timeout: String = "10s" + chunk_fetchers: String = "4" +} + +class BlockSync { + version: String = "v0" +} + +class Consensus { + wal_file: String = "data/cs.wal/wal" + timeout_propose: String = "3s" + timeout_propose_delta: String = "500ms" + timeout_prevote: String = "1s" + timeout_prevote_delta: String = "500ms" + timeout_precommit: String = "1s" + timeout_precommit_delta: String = "500ms" + timeout_commit: String = "5s" + double_sign_check_height: Int = 0 + skip_timeout_commit: Boolean = false + create_empty_blocks: Boolean = true + create_empty_blocks_interval: String = "0s" + peer_gossip_sleep_duration: String = "100ms" + peer_query_maj23_sleep_duration: String = "2s" +} + +class Storage { + discard_abci_responses: Boolean = false +} + +class TxIndex { + indexer: String = "kv" + `psql-conn`: String = "" +} + +class Instrumentation { + prometheus: Boolean = false + prometheus_listen_addr: String = ":26660" + max_open_connections: Int = 3 + namespace: String = "cometbft" +} + + +output { + renderer = new toml.Renderer {} +} diff --git a/pkl/chain.sonr/Genesis.pkl b/pkl/chain.sonr/Genesis.pkl new file mode 100644 index 000000000..814d12ece --- /dev/null +++ b/pkl/chain.sonr/Genesis.pkl @@ -0,0 +1,3 @@ +module config.sonr.Genesis + + diff --git a/pkl/chain.sonr/PklProject b/pkl/chain.sonr/PklProject new file mode 100644 index 000000000..5ecf072e1 --- /dev/null +++ b/pkl/chain.sonr/PklProject @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//===----------------------------------------------------------------------===// +/// Base configuration files for initializing a sonr chain +amends "../basePklProject.pkl" + +package { + name = "chain.sonr" + version = "0.0.1" +} diff --git a/pkl/chain.sonr/PklProject.deps.json b/pkl/chain.sonr/PklProject.deps.json new file mode 100644 index 000000000..836079aad --- /dev/null +++ b/pkl/chain.sonr/PklProject.deps.json @@ -0,0 +1,4 @@ +{ + "schemaVersion": 1, + "resolvedDependencies": {} +} \ No newline at end of file diff --git a/pkl/net.matrix/Homeserver.pkl b/pkl/net.matrix/Homeserver.pkl new file mode 100644 index 000000000..a6f74951e --- /dev/null +++ b/pkl/net.matrix/Homeserver.pkl @@ -0,0 +1,198 @@ +module net.svcs.Homeserver + +version = 2 + +global = new { +server_name = read("env:MATRIX_SERVER_NAME") ?? "" +private_key = "matrix_key.pem" +old_private_keys = new Listing {} +key_validity_period = "168h0m0s" +} + +database = new { +connection_string = read("env:MATRIX_PSQL_CONN") ?? "" +max_open_conns = 90 +max_idle_conns = 5 +conn_max_lifetime = -1 +} + +cache = new { +max_size_estimated = "1gb" +max_age = "1h" +} + +well_known_server_name = "" +well_known_client_name = read("env:MATRIX_CLIENT_NAME") ?? "" +well_known_sliding_sync_proxy = "" + +trusted_third_party_id_servers = new Listing { +"matrix.org" +"vector.im" +} + +disable_federation = false + +presence = new { +enable_inbound = false +enable_outbound = false +} + +report_stats = new { +enabled = false +endpoint = "https://panopticon.matrix.org/push" +} + +server_notices = new { +enabled = false +local_part = "_server" +display_name = "Server Alerts" +avatar_url = "" +room_name = "Server Alerts" +} + +jetstream = new { +addresses = new Listing {} +disable_tls_validation = false +storage_path = "./" +topic_prefix = "Dendrite" +} + +metrics = new { +enabled = false +basic_auth = new { + username = "metrics" + password = "metrics" +} +} + +dns_cache = new { +enabled = false +cache_size = 256 +cache_lifetime = "5m" +} + +app_service_api = new { +disable_tls_validation = false +legacy_auth = false +legacy_paths = false +config_files = new Listing { + "/etc/dendrite/chat-service.yaml" +} +} + +client_api = new { +registration_disabled = true +guests_disabled = true +registration_shared_secret = read("env:MATRIX_REGISTRATION_SHARED_SECRET") ?? "" +enable_registration_captcha = (read("env:MATRIX_ENABLE_RECATCHA") ?? "false").toBoolean() +recaptcha_public_key = read("env:MATRIX_RECATCHA_PUBLIC_KEY") ?? "" +recaptcha_private_key = read("env:MATRIX_RECATCHA_PRIVATE_KEY") ?? "" +recaptcha_bypass_secret = read("env:MATRIX_RECATCHA_BYPASS_SECRET") ?? "" +} + +turn = new { +turn_user_lifetime = "5m" +turn_uris = new Listing {} +turn_shared_secret = "" +} + +rate_limiting = new { +enabled = true +threshold = 20 +cooloff_ms = 500 +exempt_user_ids = new Listing {} +} + +federation_api = new { +send_max_retries = 16 +disable_tls_validation = false +disable_http_keepalives = false +key_perspectives = new Listing { + new { + server_name = "matrix.org" + keys = new Listing { + new { + key_id = "ed25519:auto" + public_key = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw" + } + new { + key_id = "ed25519:a_RXGa" + public_key = "l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ" + } + } + } +} +prefer_direct_fetch = false +} + +media_api = new { +base_path = "./media_store" +max_file_size_bytes = 10485760 +dynamic_thumbnails = false +max_thumbnail_generators = 10 +thumbnail_sizes = new Listing { + new { + width = 32 + height = 32 + method = "crop" + } + new { + width = 96 + height = 96 + method = "crop" + } + new { + width = 640 + height = 480 + method = "scale" + } +} +} + +mscs = new { +mscs = new Listing {} +} + +sync_api = new Listing {} + +search = new { +enabled = false +index_path = "./searchindex" +language = "en" +} + +user_api = new { +bcrypt_cost = 10 +auto_join_rooms = new Listing { + // - "#main:matrix.org" +} +} + +tracing = new { +enabled = false +jaeger = new { + serviceName = "" + disabled = false + rpc_metrics = false + tags = new Listing {} + sampler = null + reporter = null + headers = null + baggage_restrictions = null + throttler = null +} +} + +logging = new Listing { +new { + type = "std" + level = "info" +} +new { + type = "file" + level = "info" + params = new { + path = "./logs" + } +} +} diff --git a/pkl/net.matrix/PklProject b/pkl/net.matrix/PklProject new file mode 100644 index 000000000..23bb2d48e --- /dev/null +++ b/pkl/net.matrix/PklProject @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//===----------------------------------------------------------------------===// +/// Configuration files for integrating the Matrix service +amends "../basePklProject.pkl" + +package { + name = "net.matrix" + version = "0.0.1" +} diff --git a/pkl/net.matrix/PklProject.deps.json b/pkl/net.matrix/PklProject.deps.json new file mode 100644 index 000000000..836079aad --- /dev/null +++ b/pkl/net.matrix/PklProject.deps.json @@ -0,0 +1,4 @@ +{ + "schemaVersion": 1, + "resolvedDependencies": {} +} \ No newline at end of file diff --git a/pkl/net.matrix/Synapse.pkl b/pkl/net.matrix/Synapse.pkl new file mode 100644 index 000000000..6f85d4f02 --- /dev/null +++ b/pkl/net.matrix/Synapse.pkl @@ -0,0 +1,198 @@ +module net.svcs.Synapse + +version = 2 + +global = new { +server_name = read("env:MATRIX_SERVER_NAME") ?? "" +private_key = "matrix_key.pem" +old_private_keys = new Listing {} +key_validity_period = "168h0m0s" +} + +database = new { +connection_string = read("env:MATRIX_PSQL_CONN") ?? "" +max_open_conns = 90 +max_idle_conns = 5 +conn_max_lifetime = -1 +} + +cache = new { +max_size_estimated = "1gb" +max_age = "1h" +} + +well_known_server_name = "" +well_known_client_name = read("env:MATRIX_CLIENT_NAME") ?? "" +well_known_sliding_sync_proxy = "" + +trusted_third_party_id_servers = new Listing { +"matrix.org" +"vector.im" +} + +disable_federation = false + +presence = new { +enable_inbound = false +enable_outbound = false +} + +report_stats = new { +enabled = false +endpoint = "https://panopticon.matrix.org/push" +} + +server_notices = new { +enabled = false +local_part = "_server" +display_name = "Server Alerts" +avatar_url = "" +room_name = "Server Alerts" +} + +jetstream = new { +addresses = new Listing {} +disable_tls_validation = false +storage_path = "./" +topic_prefix = "Dendrite" +} + +metrics = new { +enabled = false +basic_auth = new { + username = "metrics" + password = "metrics" +} +} + +dns_cache = new { +enabled = false +cache_size = 256 +cache_lifetime = "5m" +} + +app_service_api = new { +disable_tls_validation = false +legacy_auth = false +legacy_paths = false +config_files = new Listing { + "/etc/dendrite/chat-service.yaml" +} +} + +client_api = new { +registration_disabled = true +guests_disabled = true +registration_shared_secret = read("env:MATRIX_REGISTRATION_SHARED_SECRET") ?? "" +enable_registration_captcha = (read("env:MATRIX_ENABLE_RECATCHA") ?? "false").toBoolean() +recaptcha_public_key = read("env:MATRIX_RECATCHA_PUBLIC_KEY") ?? "" +recaptcha_private_key = read("env:MATRIX_RECATCHA_PRIVATE_KEY") ?? "" +recaptcha_bypass_secret = read("env:MATRIX_RECATCHA_BYPASS_SECRET") ?? "" +} + +turn = new { +turn_user_lifetime = "5m" +turn_uris = new Listing {} +turn_shared_secret = "" +} + +rate_limiting = new { +enabled = true +threshold = 20 +cooloff_ms = 500 +exempt_user_ids = new Listing {} +} + +federation_api = new { +send_max_retries = 16 +disable_tls_validation = false +disable_http_keepalives = false +key_perspectives = new Listing { + new { + server_name = "matrix.org" + keys = new Listing { + new { + key_id = "ed25519:auto" + public_key = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw" + } + new { + key_id = "ed25519:a_RXGa" + public_key = "l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ" + } + } + } +} +prefer_direct_fetch = false +} + +media_api = new { +base_path = "./media_store" +max_file_size_bytes = 10485760 +dynamic_thumbnails = false +max_thumbnail_generators = 10 +thumbnail_sizes = new Listing { + new { + width = 32 + height = 32 + method = "crop" + } + new { + width = 96 + height = 96 + method = "crop" + } + new { + width = 640 + height = 480 + method = "scale" + } +} +} + +mscs = new { +mscs = new Listing {} +} + +sync_api = new Listing {} + +search = new { +enabled = false +index_path = "./searchindex" +language = "en" +} + +user_api = new { +bcrypt_cost = 10 +auto_join_rooms = new Listing { + // - "#main:matrix.org" +} +} + +tracing = new { +enabled = false +jaeger = new { + serviceName = "" + disabled = false + rpc_metrics = false + tags = new Listing {} + sampler = null + reporter = null + headers = null + baggage_restrictions = null + throttler = null +} +} + +logging = new Listing { +new { + type = "std" + level = "info" +} +new { + type = "file" + level = "info" + params = new { + path = "./logs" + } +} +} diff --git a/process-compose.yaml b/process-compose.yaml index 6b43e945e..a75d2524b 100644 --- a/process-compose.yaml +++ b/process-compose.yaml @@ -20,10 +20,9 @@ processes: hway: namespace: testnet + command: "air" background: true - command: "task hway:dev" restart: never max_restarts: 1 depends: - - ipfs - sonr diff --git a/proto/buf.lock b/proto/buf.lock index b003e48f9..7e1aaf732 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -21,11 +21,6 @@ deps: repository: googleapis commit: c0913f24652a4cfc95f77d97443a5005 digest: shake256:0ef3248c6235d420fe61f373154adcde6b94e3297f82472b1d8d8c3747240b61b4a10405e2a6f8ac1c98816ac6e690ea7871024aa5ae0e035cd540214667ceed - - remote: buf.build - owner: onsonr - repository: thirdparty - commit: 915d759135b04de684c86d9cf5daf256 - digest: shake256:13d0254ab4884f2d47f21d229dc3b17ea859f81d8283c021956ccd0da864228a939d055c8c85a86c66307fd7bd19654da6b3fb89fccd6c6d38ee46651a5951b5 - remote: buf.build owner: protocolbuffers repository: wellknowntypes diff --git a/proto/buf.yaml b/proto/buf.yaml index d16bcb9d8..af2b76670 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -5,7 +5,6 @@ deps: - buf.build/cosmos/cosmos-proto - buf.build/cosmos/gogo-proto - buf.build/googleapis/googleapis - - buf.build/onsonr/thirdparty breaking: use: - FILE diff --git a/proto/vault/v1/tx.proto b/proto/vault/v1/tx.proto index 6b43f5aee..71a94dadb 100644 --- a/proto/vault/v1/tx.proto +++ b/proto/vault/v1/tx.proto @@ -16,6 +16,10 @@ service Msg { // // Since: cosmos-sdk 0.47 rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); + + +// Initialize spawns a new Vault + rpc Initialize(MsgInitialize) returns (MsgInitializeResponse); } // MsgUpdateParams is the Msg/UpdateParams request type. @@ -38,3 +42,25 @@ message MsgUpdateParams { // // Since: cosmos-sdk 0.47 message MsgUpdateParamsResponse {} + +// MsgInitialize spawns a New Vault with Unclaimed State. This is a one-time +// operation that must be performed interacting with the Vault. +// +// Since: cosmos-sdk 0.47 +message MsgInitialize { + option (cosmos.msg.v1.signer) = "authority"; + + // authority is the address of the governance account. + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgInitializeResponse defines the response structure for executing a +// MsgInitialize message. +// +// Since: cosmos-sdk 0.47 +message MsgInitializeResponse {} diff --git a/scripts/init_env.sh b/scripts/init_env.sh new file mode 100644 index 000000000..f1f641af1 --- /dev/null +++ b/scripts/init_env.sh @@ -0,0 +1 @@ +#!/usr/bin/env bash diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index 844cbdbaf..b1a7762ce 100644 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -61,7 +61,6 @@ cd $ROOT_DIR/github.com/onsonr/sonr/pkg cp -r hway/types/* $ROOT_DIR/pkg/hway/types cp -r common/types/* $ROOT_DIR/pkg/common/types -cp -r motr/types/* $ROOT_DIR/pkg/motr/types echo "Cleaning up" rm -rf $ROOT_DIR/github.com diff --git a/third_party/pkl/README.md b/third_party/pkl/README.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/third_party/proto/README.md b/third_party/proto/README.md deleted file mode 100644 index a8b7e3ffd..000000000 --- a/third_party/proto/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Sonr Third Party Protobuf - -## Overview - -This directory contains the protobuf definitions for packages that are not part of the Sonr blockchain. - -## Directory Structure - -### `hway` - -The `hway` directory contains the protobuf definitions for the Highway gateway. - -### `ipfs` - -The `ipfs` directory contains the protobuf definitions for the IPFS Network. - -### `motr` - -The `motr` directory contains the protobuf definitions for the Motr client. diff --git a/third_party/proto/buf.gen.yaml b/third_party/proto/buf.gen.yaml deleted file mode 100644 index 85f837e44..000000000 --- a/third_party/proto/buf.gen.yaml +++ /dev/null @@ -1,7 +0,0 @@ -version: v1 -plugins: - - name: go - out: ../.. - - name: grpc-gateway - out: ../.. - opt: logtostderr=true,allow_colon_final_segments=true diff --git a/third_party/proto/buf.lock b/third_party/proto/buf.lock deleted file mode 100644 index fdb5ceebd..000000000 --- a/third_party/proto/buf.lock +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by buf. DO NOT EDIT. -version: v1 -deps: - - remote: buf.build - owner: cosmos - repository: cosmos-proto - commit: 04467658e59e44bbb22fe568206e1f70 - digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466 - - remote: buf.build - owner: cosmos - repository: cosmos-sdk - commit: 05419252bcc241ea8023acf1ed4cadc5 - digest: shake256:1e54a48c19a8b59d35e0a7efa76402939f515f2d8005df099856f24c37c20a52800308f025abb8cffcd014d437b49707388aaca4865d9d063d8f25d5d4eb77d5 - - remote: buf.build - owner: cosmos - repository: gogo-proto - commit: 88ef6483f90f478fb938c37dde52ece3 - digest: shake256:89c45df2aa11e0cff97b0d695436713db3d993d76792e9f8dc1ae90e6ab9a9bec55503d48ceedd6b86069ab07d3041b32001b2bfe0227fa725dd515ff381e5ba - - remote: buf.build - owner: googleapis - repository: googleapis - commit: c0913f24652a4cfc95f77d97443a5005 - digest: shake256:0ef3248c6235d420fe61f373154adcde6b94e3297f82472b1d8d8c3747240b61b4a10405e2a6f8ac1c98816ac6e690ea7871024aa5ae0e035cd540214667ceed - - remote: buf.build - owner: onsonr - repository: sonr - commit: e2a05b1a59154da6be3fe148cf01a375 - digest: shake256:0714d88978fe9a1d7b438b13ee1e95aeaef24c7f3667957da60b9a9d8f2ad55f40c2fb84409e21d47738969bff02fa16682340449653508a2ce6196ac2aec36b - - remote: buf.build - owner: protocolbuffers - repository: wellknowntypes - commit: 657250e6a39648cbb169d079a60bd9ba - digest: shake256:00de25001b8dd2e29d85fc4bcc3ede7aed886d76d67f5e0f7a9b320b90f871d3eb73507d50818d823a0512f3f8db77a11c043685528403e31ff3fef18323a9fb - - remote: buf.build - owner: tendermint - repository: tendermint - commit: 33ed361a90514289beabf3189e1d7665 - digest: shake256:038267e06294714fd883610626554b04a127b576b4e253befb4206cb72d5d3c1eeccacd4b9ec8e3fb891f7c14e1cb0f770c077d2989638995b0a61c85afedb1d diff --git a/third_party/proto/buf.yaml b/third_party/proto/buf.yaml deleted file mode 100644 index 5015909eb..000000000 --- a/third_party/proto/buf.yaml +++ /dev/null @@ -1,15 +0,0 @@ -version: v1 -name: buf.build/onsonr/thirdparty -deps: - - buf.build/onsonr/sonr -lint: - use: - - DEFAULT - - COMMENTS - - FILE_LOWER_SNAKE_CASE - except: - - UNARY_RPC - - COMMENT_FIELD - - SERVICE_SUFFIX - - PACKAGE_VERSION_SUFFIX - - RPC_REQUEST_STANDARD_NAME diff --git a/third_party/proto/common/v1/ipfs.proto b/third_party/proto/common/v1/ipfs.proto deleted file mode 100644 index 65ec027a2..000000000 --- a/third_party/proto/common/v1/ipfs.proto +++ /dev/null @@ -1,5 +0,0 @@ -syntax = "proto3"; - -package common.v1; - -option go_package = "github.com/onsonr/sonr/pkg/common/types;commonv1"; diff --git a/third_party/proto/common/v1/keys.proto b/third_party/proto/common/v1/keys.proto deleted file mode 100644 index 2791c656d..000000000 --- a/third_party/proto/common/v1/keys.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; - -package common.v1; - -option go_package = "github.com/onsonr/sonr/pkg/common/types;commonv1"; - -// PubKey defines a public key for a did -message PubKey { - string role = 1; - string key_type = 2; - RawKey raw_key = 3; - JSONWebKey jwk = 4; -} - -// JWK represents a JSON Web Key -message JSONWebKey { - string kty = 1; // Key Type - string crv = 2; // Curve (for EC and OKP keys) - string x = 3; // X coordinate (for EC and OKP keys) - string y = 4; // Y coordinate (for EC keys) - string n = 5; // Modulus (for RSA keys) - string e = 6; // Exponent (for RSA keys) -} - -message RawKey { - string algorithm = 1; - string encoding = 2; - string curve = 3; - bytes key = 4; -} diff --git a/third_party/proto/common/v1/uri.proto b/third_party/proto/common/v1/uri.proto deleted file mode 100644 index 365a0e4d3..000000000 --- a/third_party/proto/common/v1/uri.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package common.v1; - -option go_package = "github.com/onsonr/sonr/pkg/common/types;commonv1"; - -message URI { - enum URIProtocol { - HTTPS = 0; - IPFS = 1; - IPNS = 2; - DID = 3; - } - URIProtocol protocol = 1; - string value = 2; -} diff --git a/third_party/proto/hway/v1/api.proto b/third_party/proto/hway/v1/api.proto deleted file mode 100644 index b473407ac..000000000 --- a/third_party/proto/hway/v1/api.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto3"; - -package hway.v1; - -option go_package = "github.com/onsonr/sonr/pkg/hway/types"; - -service Highway { - rpc GetJWKS(GetJWKSRequest) returns (GetJWKSResponse); - rpc GetToken(GetTokenRequest) returns (GetTokenResponse); - rpc GrantAuthorization(GrantAuthorizationRequest) returns (GrantAuthorizationResponse); -} - -message GetJWKSRequest {} - -message GetJWKSResponse { - string jwks = 1; -} - -message GetTokenRequest { - string subject = 1; - string origin = 2; - string key = 3; - string asset = 4; -} - -message GetTokenResponse { - string token = 1; -} - -message GrantAuthorizationRequest { - string subject = 1; - string origin = 2; - string key = 3; - string asset = 4; - string assertion = 5; -} - -message GrantAuthorizationResponse { - string token = 1; -} diff --git a/third_party/proto/hway/v1/client.proto b/third_party/proto/hway/v1/client.proto deleted file mode 100644 index a77ad48ef..000000000 --- a/third_party/proto/hway/v1/client.proto +++ /dev/null @@ -1,3 +0,0 @@ -package hway.v1; - -option go_package = "github.com/onsonr/sonr/pkg/hway/types"; diff --git a/third_party/proto/motr/v1/api.proto b/third_party/proto/motr/v1/api.proto deleted file mode 100644 index e0606f00c..000000000 --- a/third_party/proto/motr/v1/api.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; - -package motr.v1; - -option go_package = "github.com/onsonr/sonr/pkg/motr/types"; - -service Motr { - rpc Pin(PinRequest) returns (PinResponse); - rpc Unpin(UnpinRequest) returns (UnpinResponse); -} - -message PinRequest { - string cid = 1; -} - -message PinResponse { - bool success = 1; -} - -message UnpinRequest { - string cid = 1; -} - -message UnpinResponse { - bool success = 1; -} diff --git a/web/README.md b/web/README.md new file mode 100644 index 000000000..aca1f39a4 --- /dev/null +++ b/web/README.md @@ -0,0 +1,40 @@ +# `sonr` - Sonr Chain + +[![Go Reference](https://pkg.go.dev/badge/github.com/onsonr/sonr.svg)](https://pkg.go.dev/github.com/onsonr/sonr) +![GitHub commit activity](https://img.shields.io/github/commit-activity/w/onsonr/sonr) +![GitHub Release Date - Published_At](https://img.shields.io/github/release-date/onsonr/sonr) +[![Static Badge](https://img.shields.io/badge/homepage-sonr.io-blue?style=flat-square)](https://sonr.io) +[![Go Report Card](https://goreportcard.com/badge/github.com/onsonr/sonr)](https://goreportcard.com/report/github.com/onsonr/sonr) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=sonrhq_sonr&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=sonr-io_sonr) + +> Sonr is a combination of decentralized primitives. Fundamentally, it is a peer-to-peer identity and asset management system that leverages DID documents, Webauthn, and IPFS—providing users with a secure, portable decentralized identity. + +# Documentation + +1. [Quick Start](https://github.com/onsonr/sonr/wiki/1-%E2%80%90-Quick-Start) +2. [Chain Modules](https://github.com/onsonr/sonr/wiki/2-%E2%80%90-Chain-Modules) +3. [System Architecture](https://github.com/onsonr/sonr/wiki/3-%E2%80%90-System-Architecture) +4. [Token Economy](https://github.com/onsonr/sonr/wiki/4-%E2%80%90-Token-Economy) +5. [Service Mangement](https://github.com/onsonr/sonr/wiki/5-%E2%80%90-Service-Management) +6. [Design System](https://github.com/onsonr/sonr/wiki/6-%E2%80%90-Design-System) +7. [Self Custody](https://github.com/onsonr/sonr/wiki/7-%E2%80%90-Self-Custody) + +# Stats + +![Alt](https://repobeats.axiom.co/api/embed/8d0b17e889942889c5b6e632da09bd597efd84c4.svg "Repobeats analytics image") + +# Acknowledgements + +Sonr would not have been possible without the direct and indirect support of the following individuals: + +- **Juan Benet**: For the IPFS Ecosystem. +- **Satoshi Nakamoto**: For Bitcoin. +- **Steve Jobs**: For User first UX. +- **Tim Berners-Lee**: For the Internet. + +# Community & Support + +- [Forum](https://github.com/onsonr/sonr/discussions) +- [Issues](https://github.com/onsonr/sonr/issues) +- [Twitter](https://sonr.io/twitter) +- [Dev Chat](https://sonr.io/discord) diff --git a/web/Taskfile.yml b/web/Taskfile.yml new file mode 100644 index 000000000..652684c07 --- /dev/null +++ b/web/Taskfile.yml @@ -0,0 +1,86 @@ +version: "3" +vars: + ROOT_DIR: + sh: git rev-parse --show-toplevel + +tasks: + clean: + internal: true + cmds: + - rm -rf .task + - rm -rf pkg/design/node_modules + - rm -rf .out + + # ╭──────────────────────────────────────────────────╮ + # │ Generate Commands │ + # ╰──────────────────────────────────────────────────╯ + + gen:tailwind: + cmds: + - cd ./pkg/webapp && bun run build + - cp ./pkg/webapp/components/styles/styles.css ./cmd/hway/styles.css + + gen:pkl: + sources: + - pkl/base.types/Ctx.pkl + - pkl/base.types/DWN.pkl + - pkl/base.types/ORM.pkl + cmds: + - for: sources + cmd: go run github.com/apple/pkl-go/cmd/pkl-gen-go {{ .ITEM }} + - task: clean + + gen:templ: + cmds: + - templ generate + + # ╭──────────────────────────────────────────────────╮ + # │ Build Commands │ + # ╰──────────────────────────────────────────────────╯ + build:motr: + env: + GOOS: js + GOARCH: wasm + cmds: + - go build -o build/app.wasm ./cmd/motr/main.go + + build:hway: + cmds: + - task: gen:tailwind + - task: gen:templ + - go build -o build/hway ./cmd/hway/main.go + + # ╭──────────────────────────────────────────────────╮ + # │ Serve Commands │ + # ╰──────────────────────────────────────────────────╯ + + serve:hway: + cmds: + - task: build:hway + - ./build/hway + + # ╭──────────────────────────────────────────────────╮ + # │ Deploy Commands │ + # ╰──────────────────────────────────────────────────╯ + deploy:buf: + dir: proto + cmds: + - bunx buf dep update + - bunx buf build + - bunx buf push + + deploy:hway: + dir: cmd/hway + cmds: + - task: gen:design + - bunx wrangler deploy + + deploy:pkl: + cmds: + - bunx pkl project package pkl/*/ + - | + for dir in .out/*/; do + folder=$(basename "$dir") + rclone copy "$dir" "r2:pkljar/$folder" + done + - task: clean diff --git a/web/libs/noble-client b/web/libs/noble-client new file mode 160000 index 000000000..712a041f4 --- /dev/null +++ b/web/libs/noble-client @@ -0,0 +1 @@ +Subproject commit 712a041f4fa040be8c53ca0c701f961c59a22233 diff --git a/web/libs/osmosis-client b/web/libs/osmosis-client new file mode 160000 index 000000000..e9529062b --- /dev/null +++ b/web/libs/osmosis-client @@ -0,0 +1 @@ +Subproject commit e9529062bc943894e14b67a48a665b0f7e4aabb4 diff --git a/web/libs/sonr-client b/web/libs/sonr-client new file mode 160000 index 000000000..d002aa61f --- /dev/null +++ b/web/libs/sonr-client @@ -0,0 +1 @@ +Subproject commit d002aa61f0fed83c3227c146d329b58927975b5d diff --git a/x/did/controller/base.go b/x/did/controller/base.go index 43beea8bb..dfd547f76 100644 --- a/x/did/controller/base.go +++ b/x/did/controller/base.go @@ -1,44 +1,28 @@ package controller import ( - "github.com/onsonr/crypto/mpc" - - commonv1 "github.com/onsonr/sonr/pkg/common/types" - "github.com/onsonr/sonr/x/did/types" + "github.com/onsonr/sonr/pkg/crypto/mpc" ) type ControllerI interface { ChainID() string - GetPubKey() *commonv1.PubKey + // GetPubKey() *commonv1.PubKey SonrAddress() string RawPublicKey() []byte } -func New(shares []mpc.Share) (ControllerI, error) { - var ( - valKs = shares[0] - userKs = shares[1] - ) - pb, err := valKs.PublicKey() - if err != nil { - return nil, err - } - sonrAddr, err := types.ComputeSonrAddr(pb) - if err != nil { - return nil, err - } - +func New(src mpc.KeyshareSource) (ControllerI, error) { return &controller{ - valKs: valKs, - userKs: userKs, - address: sonrAddr, - publicKey: pb, + src: src, + address: src.Address(), + publicKey: src.PublicKey(), + did: src.Issuer(), + chainID: "sonr-testnet-1", }, nil } type controller struct { - userKs mpc.Share - valKs mpc.Share + src mpc.KeyshareSource address string chainID string publicKey []byte @@ -49,25 +33,22 @@ func (c *controller) ChainID() string { return c.chainID } -func (c *controller) GetPubKey() *commonv1.PubKey { - return &commonv1.PubKey{ - KeyType: "ecdsa", - RawKey: &commonv1.RawKey{ - Algorithm: "secp256k1", - Key: c.publicKey, - }, - Role: "authentication", - } -} +// +// func (c *controller) GetPubKey() *commonv1.PubKey { +// return &commonv1.PubKey{ +// KeyType: "ecdsa", +// RawKey: &commonv1.RawKey{ +// Algorithm: "secp256k1", +// Key: c.publicKey, +// }, +// Role: "authentication", +// } +// } func (c *controller) RawPublicKey() []byte { return c.publicKey } -// func (c *controller) StdPublicKey() cryptotypes.PubKey { -// return c.stdPubKey -// } - func (c *controller) SonrAddress() string { return c.address } diff --git a/x/did/controller/signer/actor.go b/x/did/controller/signer/actor.go deleted file mode 100644 index f158c30fa..000000000 --- a/x/did/controller/signer/actor.go +++ /dev/null @@ -1 +0,0 @@ -package signer diff --git a/x/did/controller/signer/context.go b/x/did/controller/signer/context.go deleted file mode 100644 index f158c30fa..000000000 --- a/x/did/controller/signer/context.go +++ /dev/null @@ -1 +0,0 @@ -package signer diff --git a/x/did/controller/wallet/txns.go b/x/did/controller/wallet/txns.go deleted file mode 100644 index 23a750732..000000000 --- a/x/did/controller/wallet/txns.go +++ /dev/null @@ -1 +0,0 @@ -package wallet diff --git a/x/did/controller/wallet/wallet.go b/x/did/controller/wallet/wallet.go deleted file mode 100644 index 23a750732..000000000 --- a/x/did/controller/wallet/wallet.go +++ /dev/null @@ -1 +0,0 @@ -package wallet diff --git a/x/did/keeper/genesis.go b/x/did/keeper/genesis.go index 1292523b6..e9e79e727 100644 --- a/x/did/keeper/genesis.go +++ b/x/did/keeper/genesis.go @@ -5,14 +5,14 @@ import ( "cosmossdk.io/log" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/onsonr/crypto/mpc" + "github.com/onsonr/sonr/pkg/crypto/mpc" "github.com/onsonr/sonr/x/did/controller" "github.com/onsonr/sonr/x/did/types" ) func (k Keeper) NewController(ctx sdk.Context) (controller.ControllerI, error) { - shares, err := mpc.GenerateKeyshares() + shares, err := mpc.NewKeyshareSource() if err != nil { return nil, err } diff --git a/x/did/types/accstd/exports.go b/x/did/types/accounts.go similarity index 75% rename from x/did/types/accstd/exports.go rename to x/did/types/accounts.go index 320c72c27..b07506a53 100644 --- a/x/did/types/accstd/exports.go +++ b/x/did/types/accounts.go @@ -1,5 +1,4 @@ -// Package accountstd exports the types and functions that are used by developers to implement smart accounts. -package accstd +package types import ( "bytes" @@ -11,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/address" "github.com/onsonr/sonr/pkg/core/transaction" - "github.com/onsonr/sonr/x/did/types/accstd/internal/accounts" + "github.com/onsonr/sonr/x/did/types/internal/accounts" ) var ( @@ -19,22 +18,22 @@ var ( ErrInvalidType = errors.New("invalid type") ) -// Interface is the exported interface of an Account. -type Interface = accounts.Account +// AccountsInterface is the exported interface of an Account. +type AccountsInterface = accounts.Account -// ExecuteBuilder is the exported type of ExecuteBuilder. -type ExecuteBuilder = accounts.ExecuteBuilder +// AccountsExecuteBuilder is the exported type of AccountsExecuteBuilder. +type AccountsExecuteBuilder = accounts.ExecuteBuilder -// QueryBuilder is the exported type of QueryBuilder. -type QueryBuilder = accounts.QueryBuilder +// AccountsQueryBuilder is the exported type of AccountsQueryBuilder. +type AccountsQueryBuilder = accounts.QueryBuilder -// InitBuilder is the exported type of InitBuilder. -type InitBuilder = accounts.InitBuilder +// AccountsInitBuilder is the exported type of AccountsInitBuilder. +type AccountsInitBuilder = accounts.InitBuilder // AccountCreatorFunc is the exported type of AccountCreatorFunc. type AccountCreatorFunc = accounts.AccountCreatorFunc -func DIAccount[A Interface](name string, constructor func(deps Dependencies) (A, error)) DepinjectAccount { +func DIAccount[A AccountsInterface](name string, constructor func(deps Dependencies) (A, error)) DepinjectAccount { return DepinjectAccount{MakeAccount: AddAccount(name, constructor)} } @@ -47,31 +46,31 @@ func (DepinjectAccount) IsManyPerContainerType() {} // Dependencies is the exported type of Dependencies. type Dependencies = accounts.Dependencies -func RegisterExecuteHandler[ +func RegisterAccountsExecuteHandler[ Req any, ProtoReq accounts.ProtoMsgG[Req], Resp any, ProtoResp accounts.ProtoMsgG[Resp], -](router *ExecuteBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +](router *AccountsExecuteBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), ) { accounts.RegisterExecuteHandler(router, handler) } -// RegisterQueryHandler registers a query handler for a smart account that uses protobuf. -func RegisterQueryHandler[ +// RegisterAccountsQueryHandler registers a query handler for a smart account that uses protobuf. +func RegisterAccountsQueryHandler[ Req any, ProtoReq accounts.ProtoMsgG[Req], Resp any, ProtoResp accounts.ProtoMsgG[Resp], -](router *QueryBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +](router *AccountsQueryBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), ) { accounts.RegisterQueryHandler(router, handler) } -// RegisterInitHandler registers an initialisation handler for a smart account that uses protobuf. -func RegisterInitHandler[ +// RegisterAccountsInitHandler registers an initialisation handler for a smart account that uses protobuf. +func RegisterAccountsInitHandler[ Req any, ProtoReq accounts.ProtoMsgG[Req], Resp any, ProtoResp accounts.ProtoMsgG[Resp], -](router *InitBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), +](router *AccountsInitBuilder, handler func(ctx context.Context, req ProtoReq) (ProtoResp, error), ) { accounts.RegisterInitHandler(router, handler) } // AddAccount is a helper function to add a smart account to the list of smart accounts. -func AddAccount[A Interface](name string, constructor func(deps Dependencies) (A, error)) AccountCreatorFunc { +func AddAccount[A AccountsInterface](name string, constructor func(deps Dependencies) (A, error)) AccountCreatorFunc { return func(deps accounts.Dependencies) (string, accounts.Account, error) { acc, err := constructor(deps) return name, acc, err diff --git a/x/did/types/address.go b/x/did/types/address.go new file mode 100644 index 000000000..88aedc6d9 --- /dev/null +++ b/x/did/types/address.go @@ -0,0 +1,52 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/types/bech32" +) + +// ComputeSonrAddr computes the Sonr address from a public key +func ComputeSonrAddr(pk []byte) (string, error) { + sonrAddr, err := bech32.ConvertAndEncode("idx", pk) + if err != nil { + return "", err + } + return sonrAddr, nil +} + +// ComputeBitcoinAddr computes the Bitcoin address from a public key +func ComputeBitcoinAddr(pk []byte) (string, error) { + btcAddr, err := bech32.ConvertAndEncode("bc", pk) + if err != nil { + return "", err + } + return btcAddr, nil +} + +// +// // ComputeEthereumAddr computes the Ethereum address from a public key +// func ComputeEthereumAddr(pk *ecdsa.PublicKey) string { +// // Generate Ethereum address +// address := ethcrypto.PubkeyToAddress(*pk) +// +// // Apply ERC-55 checksum encoding +// addr := address.Hex() +// addr = strings.ToLower(addr) +// addr = strings.TrimPrefix(addr, "0x") +// hash := sha3.NewLegacyKeccak256() +// hash.Write([]byte(addr)) +// hashBytes := hash.Sum(nil) +// +// result := "0x" +// for i, c := range addr { +// if c >= '0' && c <= '9' { +// result += string(c) +// } else { +// if hashBytes[i/2]>>(4-i%2*4)&0xf >= 8 { +// result += strings.ToUpper(string(c)) +// } else { +// result += string(c) +// } +// } +// } +// return result +// } diff --git a/x/did/types/compute.go b/x/did/types/compute.go deleted file mode 100644 index 8c9b78e1b..000000000 --- a/x/did/types/compute.go +++ /dev/null @@ -1,56 +0,0 @@ -package types - -import ( - "crypto/ecdsa" - "strings" - - "github.com/cosmos/cosmos-sdk/types/bech32" - ethcrypto "github.com/ethereum/go-ethereum/crypto" - "golang.org/x/crypto/sha3" -) - -// ComputeSonrAddr computes the Sonr address from a public key -func ComputeSonrAddr(pk []byte) (string, error) { - sonrAddr, err := bech32.ConvertAndEncode("idx", pk) - if err != nil { - return "", err - } - return sonrAddr, nil -} - -// ComputeBitcoinAddr computes the Bitcoin address from a public key -func ComputeBitcoinAddr(pk []byte) (string, error) { - btcAddr, err := bech32.ConvertAndEncode("bc", pk) - if err != nil { - return "", err - } - return btcAddr, nil -} - -// ComputeEthereumAddr computes the Ethereum address from a public key -func ComputeEthereumAddr(pk *ecdsa.PublicKey) string { - // Generate Ethereum address - address := ethcrypto.PubkeyToAddress(*pk) - - // Apply ERC-55 checksum encoding - addr := address.Hex() - addr = strings.ToLower(addr) - addr = strings.TrimPrefix(addr, "0x") - hash := sha3.NewLegacyKeccak256() - hash.Write([]byte(addr)) - hashBytes := hash.Sum(nil) - - result := "0x" - for i, c := range addr { - if c >= '0' && c <= '9' { - result += string(c) - } else { - if hashBytes[i/2]>>(4-i%2*4)&0xf >= 8 { - result += strings.ToUpper(string(c)) - } else { - result += string(c) - } - } - } - return result -} diff --git a/x/did/types/did/crypto.go b/x/did/types/did/crypto.go new file mode 100644 index 000000000..d0065a7fc --- /dev/null +++ b/x/did/types/did/crypto.go @@ -0,0 +1,231 @@ +package did + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "errors" + "fmt" + + "github.com/decred/dcrd/dcrec/secp256k1/v4" + crypto "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/crypto/pb" + "github.com/multiformats/go-multicodec" + "github.com/multiformats/go-varint" +) + +// GenerateEd25519 generates an Ed25519 private key and the matching DID. +// This is the RECOMMENDED algorithm. +func GenerateEd25519() (crypto.PrivKey, DID, error) { + priv, pub, err := crypto.GenerateEd25519Key(rand.Reader) + if err != nil { + return nil, Undef, nil + } + did, err := FromPubKey(pub) + return priv, did, err +} + +// GenerateRSA generates a RSA private key and the matching DID. +func GenerateRSA() (crypto.PrivKey, DID, error) { + // NIST Special Publication 800-57 Part 1 Revision 5 + // Section 5.6.1.1 (Table 2) + // Paraphrased: 2048-bit RSA keys are secure until 2030 and 3072-bit keys are recommended for longer-term security. + const keyLength = 3072 + + priv, pub, err := crypto.GenerateRSAKeyPair(keyLength, rand.Reader) + if err != nil { + return nil, Undef, nil + } + did, err := FromPubKey(pub) + return priv, did, err +} + +// GenerateEd25519 generates a Secp256k1 private key and the matching DID. +func GenerateSecp256k1() (crypto.PrivKey, DID, error) { + priv, pub, err := crypto.GenerateSecp256k1Key(rand.Reader) + if err != nil { + return nil, Undef, nil + } + did, err := FromPubKey(pub) + return priv, did, err +} + +// GenerateECDSA generates an ECDSA private key and the matching DID +// for the default P256 curve. +func GenerateECDSA() (crypto.PrivKey, DID, error) { + return GenerateECDSAWithCurve(P256) +} + +// GenerateECDSAWithCurve generates an ECDSA private key and matching +// DID for the user-supplied curve +func GenerateECDSAWithCurve(code multicodec.Code) (crypto.PrivKey, DID, error) { + var curve elliptic.Curve + + switch code { + case P256: + curve = elliptic.P256() + case P384: + curve = elliptic.P384() + case P521: + curve = elliptic.P521() + default: + return nil, Undef, errors.New("unsupported ECDSA curve") + } + + priv, pub, err := crypto.GenerateECDSAKeyPairWithCurve(curve, rand.Reader) + if err != nil { + return nil, Undef, err + } + + did, err := FromPubKey(pub) + + return priv, did, err +} + +// FromPrivKey is a convenience function that returns the DID associated +// with the public key associated with the provided private key. +func FromPrivKey(privKey crypto.PrivKey) (DID, error) { + return FromPubKey(privKey.GetPublic()) +} + +// FromPubKey returns a did:key constructed from the provided public key. +func FromPubKey(pubKey crypto.PubKey) (DID, error) { + var code multicodec.Code + + switch pubKey.Type() { + case pb.KeyType_Ed25519: + code = multicodec.Ed25519Pub + case pb.KeyType_RSA: + code = RSA + case pb.KeyType_Secp256k1: + code = Secp256k1 + case pb.KeyType_ECDSA: + var err error + if code, err = codeForCurve(pubKey); err != nil { + return Undef, err + } + default: + return Undef, errors.New("unsupported key type") + } + + if pubKey.Type() == pb.KeyType_ECDSA && code == Secp256k1 { + var err error + + pubKey, err = coerceECDSAToSecp256k1(pubKey) + if err != nil { + return Undef, err + } + } + + var bytes []byte + + switch pubKey.Type() { + case pb.KeyType_ECDSA: + pkix, err := pubKey.Raw() + if err != nil { + return Undef, err + } + + publicKey, err := x509.ParsePKIXPublicKey(pkix) + if err != nil { + return Undef, err + } + + ecdsaPublicKey := publicKey.(*ecdsa.PublicKey) + + bytes = elliptic.MarshalCompressed(ecdsaPublicKey.Curve, ecdsaPublicKey.X, ecdsaPublicKey.Y) + case pb.KeyType_Ed25519, pb.KeyType_Secp256k1: + var err error + + if bytes, err = pubKey.Raw(); err != nil { + return Undef, err + } + case pb.KeyType_RSA: + var err error + + pkix, err := pubKey.Raw() + if err != nil { + return Undef, err + } + + publicKey, err := x509.ParsePKIXPublicKey(pkix) + if err != nil { + return Undef, err + } + + bytes = x509.MarshalPKCS1PublicKey(publicKey.(*rsa.PublicKey)) + } + + return DID{ + code: code, + bytes: string(append(varint.ToUvarint(uint64(code)), bytes...)), + }, nil +} + +// ToPubKey returns the crypto.PubKey encapsulated in the DID formed by +// parsing the provided string. +func ToPubKey(s string) (crypto.PubKey, error) { + id, err := Parse(s) + if err != nil { + return nil, err + } + + return id.PubKey() +} + +func codeForCurve(pubKey crypto.PubKey) (multicodec.Code, error) { + stdPub, err := crypto.PubKeyToStdKey(pubKey) + if err != nil { + return multicodec.Identity, err + } + + ecdsaPub, ok := stdPub.(*ecdsa.PublicKey) + if !ok { + return multicodec.Identity, errors.New("failed to assert type for code to curve") + } + + switch ecdsaPub.Curve { + case elliptic.P256(): + return P256, nil + case elliptic.P384(): + return P384, nil + case elliptic.P521(): + return P521, nil + case secp256k1.S256(): + return Secp256k1, nil + default: + return multicodec.Identity, fmt.Errorf("unsupported ECDSA curve: %s", ecdsaPub.Curve.Params().Name) + } +} + +// secp256k1.S256 is a valid ECDSA curve, but the go-libp2p/core/crypto +// package treats it as a different type and has a different format for +// the raw bytes of the public key. +// +// If a valid ECDSA public key was created using the secp256k1.S256 curve, +// this function will "convert" it from a crypto.ECDSAPubKey to a +// crypto.Secp256k1PublicKey. +func coerceECDSAToSecp256k1(pubKey crypto.PubKey) (crypto.PubKey, error) { + stdPub, err := crypto.PubKeyToStdKey(pubKey) + if err != nil { + return nil, err + } + + ecdsaPub, ok := stdPub.(*ecdsa.PublicKey) + if !ok { + return nil, errors.New("failed to assert type for secp256k1 coersion") + } + + ecdsaPubBytes := append([]byte{0x04}, append(ecdsaPub.X.Bytes(), ecdsaPub.Y.Bytes()...)...) + + secp256k1Pub, err := secp256k1.ParsePubKey(ecdsaPubBytes) + if err != nil { + return nil, err + } + + cryptoPub := crypto.Secp256k1PublicKey(*secp256k1Pub) + + return &cryptoPub, nil +} diff --git a/x/did/types/did/crypto_test.go b/x/did/types/did/crypto_test.go new file mode 100644 index 000000000..6e5aee987 --- /dev/null +++ b/x/did/types/did/crypto_test.go @@ -0,0 +1,108 @@ +package did_test + +import ( + "crypto/elliptic" + "crypto/rand" + "testing" + + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/crypto/pb" + "github.com/multiformats/go-multicodec" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/onsonr/sonr/x/did/types/did" +) + +const ( + exampleDIDStr = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK" + examplePubKeyStr = "Lm/M42cB3HkUiODQsXRcweM6TByfzEHGO9ND274JcOY=" +) + +func TestFromPubKey(t *testing.T) { + t.Parallel() + + _, ecdsaP256, err := crypto.GenerateECDSAKeyPairWithCurve(elliptic.P256(), rand.Reader) + require.NoError(t, err) + _, ecdsaP384, err := crypto.GenerateECDSAKeyPairWithCurve(elliptic.P384(), rand.Reader) + require.NoError(t, err) + _, ecdsaP521, err := crypto.GenerateECDSAKeyPairWithCurve(elliptic.P521(), rand.Reader) + require.NoError(t, err) + _, ecdsaSecp256k1, err := crypto.GenerateECDSAKeyPairWithCurve(secp256k1.S256(), rand.Reader) + require.NoError(t, err) + _, ed25519, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + _, rsa, err := crypto.GenerateRSAKeyPair(2048, rand.Reader) + require.NoError(t, err) + _, secp256k1PubKey1, err := crypto.GenerateSecp256k1Key(rand.Reader) + require.NoError(t, err) + + test := func(pub crypto.PubKey, code multicodec.Code) func(t *testing.T) { + t.Helper() + + return func(t *testing.T) { + t.Parallel() + + id, err := did.FromPubKey(pub) + require.NoError(t, err) + p, err := id.PubKey() + require.NoError(t, err) + assert.Equal(t, pub, p) + } + } + + t.Run("ECDSA with P256 curve", test(ecdsaP256, did.P256)) + t.Run("ECDSA with P384 curve", test(ecdsaP384, did.P384)) + t.Run("ECDSA with P521 curve", test(ecdsaP521, did.P521)) + t.Run("Ed25519", test(ed25519, did.Ed25519)) + t.Run("RSA", test(rsa, did.RSA)) + t.Run("secp256k1", test(secp256k1PubKey1, did.Secp256k1)) + + t.Run("ECDSA with secp256k1 curve (coerced)", func(t *testing.T) { + t.Parallel() + + id, err := did.FromPubKey(ecdsaSecp256k1) + require.NoError(t, err) + p, err := id.PubKey() + require.NoError(t, err) + require.Equal(t, pb.KeyType_Secp256k1, p.Type()) + }) + + t.Run("unmarshaled example key (secp256k1)", func(t *testing.T) { + t.Parallel() + + id, err := did.FromPubKey(examplePubKey(t)) + require.NoError(t, err) + require.Equal(t, exampleDID(t), id) + }) +} + +func TestToPubKey(t *testing.T) { + t.Parallel() + + pubKey, err := did.ToPubKey(exampleDIDStr) + require.NoError(t, err) + require.Equal(t, examplePubKey(t), pubKey) +} + +func exampleDID(t *testing.T) did.DID { + t.Helper() + + id, err := did.Parse(exampleDIDStr) + require.NoError(t, err) + + return id +} + +func examplePubKey(t *testing.T) crypto.PubKey { + t.Helper() + + pubKeyCfg, err := crypto.ConfigDecodeKey(examplePubKeyStr) + require.NoError(t, err) + + pubKey, err := crypto.UnmarshalEd25519PublicKey(pubKeyCfg) + require.NoError(t, err) + + return pubKey +} diff --git a/x/did/types/did/did.go b/x/did/types/did/did.go new file mode 100644 index 000000000..19042bf1e --- /dev/null +++ b/x/did/types/did/did.go @@ -0,0 +1,140 @@ +package did + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/x509" + "fmt" + "strings" + + crypto "github.com/libp2p/go-libp2p/core/crypto" + mbase "github.com/multiformats/go-multibase" + "github.com/multiformats/go-multicodec" + varint "github.com/multiformats/go-varint" +) + +// Signature algorithms from the [did:key specification] +// +// [did:key specification]: https://w3c-ccg.github.io/did-method-key/#signature-method-creation-algorithm +const ( + X25519 = multicodec.X25519Pub + Ed25519 = multicodec.Ed25519Pub // UCAN required/recommended + P256 = multicodec.P256Pub // UCAN required + P384 = multicodec.P384Pub + P521 = multicodec.P521Pub + Secp256k1 = multicodec.Secp256k1Pub // UCAN required + RSA = multicodec.RsaPub +) + +// Undef can be used to represent a nil or undefined DID, using DID{} +// directly is also acceptable. +var Undef = DID{} + +// DID is a Decentralized Identifier of the did:key type, directly holding a cryptographic public key. +// [did:key format]: https://w3c-ccg.github.io/did-method-key/ +type DID struct { + code multicodec.Code + bytes string // as string instead of []byte to allow the == operator +} + +// Parse returns the DID from the string representation or an error if +// the prefix and method are incorrect, if an unknown encryption algorithm +// is specified or if the method-specific-identifier's bytes don't +// represent a public key for the specified encryption algorithm. +func Parse(str string) (DID, error) { + const keyPrefix = "did:key:" + + if !strings.HasPrefix(str, keyPrefix) { + return Undef, fmt.Errorf("must start with 'did:key'") + } + + baseCodec, bytes, err := mbase.Decode(str[len(keyPrefix):]) + if err != nil { + return Undef, err + } + if baseCodec != mbase.Base58BTC { + return Undef, fmt.Errorf("not Base58BTC encoded") + } + code, _, err := varint.FromUvarint(bytes) + if err != nil { + return Undef, err + } + switch multicodec.Code(code) { + case Ed25519, P256, Secp256k1, RSA: + return DID{bytes: string(bytes), code: multicodec.Code(code)}, nil + default: + return Undef, fmt.Errorf("unsupported did:key multicodec: 0x%x", code) + } +} + +// MustParse is like Parse but panics instead of returning an error. +func MustParse(str string) DID { + did, err := Parse(str) + if err != nil { + panic(err) + } + return did +} + +// Defined tells if the DID is defined, not equal to Undef. +func (d DID) Defined() bool { + return d.code != 0 || len(d.bytes) > 0 +} + +// PubKey returns the public key encapsulated by the did:key. +func (d DID) PubKey() (crypto.PubKey, error) { + unmarshaler, ok := map[multicodec.Code]crypto.PubKeyUnmarshaller{ + X25519: crypto.UnmarshalEd25519PublicKey, + Ed25519: crypto.UnmarshalEd25519PublicKey, + P256: ecdsaPubKeyUnmarshaler(elliptic.P256()), + P384: ecdsaPubKeyUnmarshaler(elliptic.P384()), + P521: ecdsaPubKeyUnmarshaler(elliptic.P521()), + Secp256k1: crypto.UnmarshalSecp256k1PublicKey, + RSA: rsaPubKeyUnmarshaller, + }[d.code] + if !ok { + return nil, fmt.Errorf("unsupported multicodec: %d", d.code) + } + + codeSize := varint.UvarintSize(uint64(d.code)) + return unmarshaler([]byte(d.bytes)[codeSize:]) +} + +// String formats the decentralized identity document (DID) as a string. +func (d DID) String() string { + key, _ := mbase.Encode(mbase.Base58BTC, []byte(d.bytes)) + return "did:key:" + key +} + +func ecdsaPubKeyUnmarshaler(curve elliptic.Curve) crypto.PubKeyUnmarshaller { + return func(data []byte) (crypto.PubKey, error) { + x, y := elliptic.UnmarshalCompressed(curve, data) + + ecdsaPublicKey := &ecdsa.PublicKey{ + Curve: curve, + X: x, + Y: y, + } + + pkix, err := x509.MarshalPKIXPublicKey(ecdsaPublicKey) + if err != nil { + return nil, err + } + + return crypto.UnmarshalECDSAPublicKey(pkix) + } +} + +func rsaPubKeyUnmarshaller(data []byte) (crypto.PubKey, error) { + rsaPublicKey, err := x509.ParsePKCS1PublicKey(data) + if err != nil { + return nil, err + } + + pkix, err := x509.MarshalPKIXPublicKey(rsaPublicKey) + if err != nil { + return nil, err + } + + return crypto.UnmarshalRsaPublicKey(pkix) +} diff --git a/x/did/types/did/did_test.go b/x/did/types/did/did_test.go new file mode 100644 index 000000000..47585af9b --- /dev/null +++ b/x/did/types/did/did_test.go @@ -0,0 +1,41 @@ +package did + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseDIDKey(t *testing.T) { + str := "did:key:z6Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z" + d, err := Parse(str) + require.NoError(t, err) + require.Equal(t, str, d.String()) +} + +func TestMustParseDIDKey(t *testing.T) { + str := "did:key:z6Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z" + require.NotPanics(t, func() { + d := MustParse(str) + require.Equal(t, str, d.String()) + }) + str = "did:key:z7Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z" + require.Panics(t, func() { + MustParse(str) + }) +} + +func TestEquivalence(t *testing.T) { + undef0 := DID{} + undef1 := Undef + + did0, err := Parse("did:key:z6Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z") + require.NoError(t, err) + did1, err := Parse("did:key:z6Mkod5Jr3yd5SC7UDueqK4dAAw5xYJYjksy722tA9Boxc4z") + require.NoError(t, err) + + require.True(t, undef0 == undef1) + require.False(t, undef0 == did0) + require.True(t, did0 == did1) + require.False(t, undef1 == did1) +} diff --git a/x/did/types/accstd/internal/accounts/api_builder.go b/x/did/types/internal/accounts/api_builder.go similarity index 100% rename from x/did/types/accstd/internal/accounts/api_builder.go rename to x/did/types/internal/accounts/api_builder.go diff --git a/x/did/types/accstd/internal/accounts/context.go b/x/did/types/internal/accounts/context.go similarity index 98% rename from x/did/types/accstd/internal/accounts/context.go rename to x/did/types/internal/accounts/context.go index 9cc72f17a..659e60063 100644 --- a/x/did/types/accstd/internal/accounts/context.go +++ b/x/did/types/internal/accounts/context.go @@ -9,7 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/onsonr/sonr/pkg/core/transaction" - "github.com/onsonr/sonr/x/did/types/accstd/internal/prefixstore" + "github.com/onsonr/sonr/x/did/types/internal/prefixstore" ) var AccountStatePrefix = collections.NewPrefix(255) diff --git a/x/did/types/accstd/internal/accounts/encoding.go b/x/did/types/internal/accounts/encoding.go similarity index 100% rename from x/did/types/accstd/internal/accounts/encoding.go rename to x/did/types/internal/accounts/encoding.go diff --git a/x/did/types/accstd/internal/accounts/implementation.go b/x/did/types/internal/accounts/implementation.go similarity index 100% rename from x/did/types/accstd/internal/accounts/implementation.go rename to x/did/types/internal/accounts/implementation.go diff --git a/x/did/types/accstd/internal/accounts/interface.go b/x/did/types/internal/accounts/interface.go similarity index 100% rename from x/did/types/accstd/internal/accounts/interface.go rename to x/did/types/internal/accounts/interface.go diff --git a/x/did/types/accstd/internal/accounts/protoaccount.go b/x/did/types/internal/accounts/protoaccount.go similarity index 100% rename from x/did/types/accstd/internal/accounts/protoaccount.go rename to x/did/types/internal/accounts/protoaccount.go diff --git a/x/did/types/accstd/internal/prefixstore/prefixstore.go b/x/did/types/internal/prefixstore/prefixstore.go similarity index 100% rename from x/did/types/accstd/internal/prefixstore/prefixstore.go rename to x/did/types/internal/prefixstore/prefixstore.go diff --git a/x/did/types/params.go b/x/did/types/params.go index a88f388d9..c2cb73eb5 100644 --- a/x/did/types/params.go +++ b/x/did/types/params.go @@ -4,10 +4,10 @@ import ( "encoding/json" fmt "fmt" - "github.com/onsonr/sonr/pkg/motr/types/orm/keyalgorithm" - "github.com/onsonr/sonr/pkg/motr/types/orm/keycurve" - "github.com/onsonr/sonr/pkg/motr/types/orm/keyencoding" - "github.com/onsonr/sonr/pkg/motr/types/orm/keyrole" + "github.com/onsonr/sonr/pkg/common/models/keyalgorithm" + "github.com/onsonr/sonr/pkg/common/models/keycurve" + "github.com/onsonr/sonr/pkg/common/models/keyencoding" + "github.com/onsonr/sonr/pkg/common/models/keyrole" ) // DefaultParams returns default module parameters. diff --git a/x/did/controller/wallet/pubkey.go b/x/did/types/pubkey.go similarity index 96% rename from x/did/controller/wallet/pubkey.go rename to x/did/types/pubkey.go index 509738b9a..88c1721f4 100644 --- a/x/did/controller/wallet/pubkey.go +++ b/x/did/types/pubkey.go @@ -1,4 +1,4 @@ -package wallet +package types import ( "bytes" @@ -7,15 +7,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/crypto/types" "google.golang.org/protobuf/proto" - - commonv1 "github.com/onsonr/sonr/pkg/common/types" ) type PubKeyI interface { GetRole() string GetKeyType() string - GetRawKey() *commonv1.RawKey - GetJwk() *commonv1.JSONWebKey + // GetRawKey() *commonv1.RawKey + // GetJwk() *commonv1.JSONWebKey } // PubKey defines a generic pubkey. diff --git a/x/did/controller/signer/signer.go b/x/did/types/signer.go similarity index 97% rename from x/did/controller/signer/signer.go rename to x/did/types/signer.go index 5db3a24c7..1eeb82fd8 100644 --- a/x/did/controller/signer/signer.go +++ b/x/did/types/signer.go @@ -1,4 +1,4 @@ -package signer +package types import ( "context" diff --git a/x/vault/keeper/keeper.go b/x/vault/keeper/keeper.go index 9732c576e..846a0d892 100644 --- a/x/vault/keeper/keeper.go +++ b/x/vault/keeper/keeper.go @@ -15,7 +15,7 @@ import ( "github.com/ipfs/kubo/client/rpc" apiv1 "github.com/onsonr/sonr/api/vault/v1" - dwngen "github.com/onsonr/sonr/pkg/motr/config" + "github.com/onsonr/sonr/pkg/core/dwn" didkeeper "github.com/onsonr/sonr/x/did/keeper" "github.com/onsonr/sonr/x/vault/types" ) @@ -100,13 +100,13 @@ func NewKeeper( } // currentSchema returns the current schema -func (k Keeper) currentSchema(ctx sdk.Context) (*dwngen.Schema, error) { +func (k Keeper) currentSchema(ctx sdk.Context) (*dwn.Schema, error) { p, err := k.Params.Get(ctx) if err != nil { return nil, err } schema := p.Schema - return &dwngen.Schema{ + return &dwn.Schema{ Version: int(schema.Version), Account: schema.Account, Asset: schema.Asset, diff --git a/x/vault/keeper/querier.go b/x/vault/keeper/querier.go index 906f275ce..8e4f2b7d1 100644 --- a/x/vault/keeper/querier.go +++ b/x/vault/keeper/querier.go @@ -6,8 +6,8 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/onsonr/crypto/mpc" + "github.com/onsonr/sonr/pkg/crypto/mpc" "github.com/onsonr/sonr/x/did/controller" "github.com/onsonr/sonr/x/vault/types" ) @@ -65,7 +65,7 @@ func (k Querier) Allocate(goCtx context.Context, req *types.QueryAllocateRequest } // 2. Generate MPC Keyshares for new Account - shares, err := mpc.GenerateKeyshares() + shares, err := mpc.NewKeyshareSource() if err != nil { ctx.Logger().Error(fmt.Sprintf("Error generating keyshares: %s", err.Error())) return nil, types.ErrInvalidSchema.Wrap(err.Error()) @@ -79,14 +79,14 @@ func (k Querier) Allocate(goCtx context.Context, req *types.QueryAllocateRequest } // 4. Create a new vault PWA for service-worker - v, err := types.NewVault("", con.SonrAddress(), con.ChainID(), sch) + v, err := types.SpawnVault("", con.SonrAddress(), con.ChainID(), sch) if err != nil { ctx.Logger().Error(fmt.Sprintf("Error creating vault: %s", err.Error())) return nil, types.ErrInvalidSchema.Wrap(err.Error()) } // 5. Add to IPFS and Return CID for User Claims in Gateway - cid, err := k.ipfsClient.Unixfs().Add(context.Background(), v.FS) + cid, err := k.ipfsClient.Unixfs().Add(context.Background(), v) if err != nil { ctx.Logger().Error(fmt.Sprintf("Error adding to IPFS: %s", err.Error())) return nil, types.ErrVaultAssembly.Wrap(err.Error()) diff --git a/x/vault/types/params.go b/x/vault/types/params.go index e8e1abedd..100d4f111 100644 --- a/x/vault/types/params.go +++ b/x/vault/types/params.go @@ -3,7 +3,8 @@ package types import ( "encoding/json" - "github.com/onsonr/sonr/pkg/motr/types/orm" + "github.com/onsonr/sonr/pkg/common" + orm "github.com/onsonr/sonr/pkg/common/models" ) // DefaultParams returns default module parameters. @@ -35,13 +36,13 @@ func (p Params) Validate() error { // DefaultSchema returns the default schema func DefaultSchema() *Schema { return &Schema{ - Version: orm.SchemaVersion, - Account: orm.GetSchema(&orm.Account{}), - Asset: orm.GetSchema(&orm.Asset{}), - Chain: orm.GetSchema(&orm.Chain{}), - Credential: orm.GetSchema(&orm.Credential{}), - Grant: orm.GetSchema(&orm.Grant{}), - Keyshare: orm.GetSchema(&orm.Keyshare{}), - Profile: orm.GetSchema(&orm.Profile{}), + Version: common.SchemaVersion, + Account: common.GetSchema(&orm.Account{}), + Asset: common.GetSchema(&orm.Asset{}), + Chain: common.GetSchema(&orm.Chain{}), + Credential: common.GetSchema(&orm.Credential{}), + Grant: common.GetSchema(&orm.Grant{}), + Keyshare: common.GetSchema(&orm.Keyshare{}), + Profile: common.GetSchema(&orm.Profile{}), } } diff --git a/x/vault/types/spawn.go b/x/vault/types/spawn.go new file mode 100644 index 000000000..02822ea11 --- /dev/null +++ b/x/vault/types/spawn.go @@ -0,0 +1,42 @@ +package types + +import ( + "github.com/ipfs/boxo/files" + + "github.com/onsonr/sonr/pkg/core/dwn" + "github.com/onsonr/sonr/x/vault/types/static" +) + +const ( + kFileNameConfigJSON = "dwn.json" + kFileNameIndexHTML = "index.html" + kFileNameWorkerJS = "sw.js" +) + +type Vault = files.Directory + +func SpawnVault(keyshareJSON string, adddress string, chainID string, schema *dwn.Schema) (Vault, error) { + dwnCfg := &dwn.Config{ + MotrKeyshare: keyshareJSON, + MotrAddress: adddress, + IpfsGatewayUrl: "https://ipfs.sonr.land", + SonrApiUrl: "https://api.sonr.land", + SonrRpcUrl: "https://rpc.sonr.land", + SonrChainId: chainID, + VaultSchema: schema, + } + cnf, err := dwnCfg.MarshalJSON() + if err != nil { + return nil, err + } + return setupVaultDirectory(cnf), nil +} + +// spawnVaultDirectory creates a new directory with the default files +func setupVaultDirectory(cfgBz []byte) files.Directory { + return files.NewMapDirectory(map[string]files.Node{ + kFileNameConfigJSON: files.NewBytesFile(cfgBz), + kFileNameIndexHTML: files.NewBytesFile(static.IndexHTML), + kFileNameWorkerJS: files.NewBytesFile(static.WorkerJS), + }) +} diff --git a/x/vault/types/static/index.html b/x/vault/types/static/index.html new file mode 100644 index 000000000..db7b1a844 --- /dev/null +++ b/x/vault/types/static/index.html @@ -0,0 +1,36 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Sonr DWN + + + +
    +
    Loading...
    +
    + + diff --git a/x/vault/types/static/static.go b/x/vault/types/static/static.go new file mode 100644 index 000000000..7a56ecccd --- /dev/null +++ b/x/vault/types/static/static.go @@ -0,0 +1,11 @@ +package static + +import ( + _ "embed" +) + +//go:embed index.html +var IndexHTML []byte + +//go:embed sw.js +var WorkerJS []byte diff --git a/x/vault/types/static/sw.js b/x/vault/types/static/sw.js new file mode 100644 index 000000000..e1490650f --- /dev/null +++ b/x/vault/types/static/sw.js @@ -0,0 +1,258 @@ +// Cache names for different types of resources +const CACHE_NAMES = { + wasm: 'wasm-cache-v1', + static: 'static-cache-v1', + dynamic: 'dynamic-cache-v1' +}; + +// Import required scripts +importScripts( + "https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js", + "https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v1.1.0/sw.js", +); + +// Initialize WASM HTTP listener +const wasmInstance = registerWasmHTTPListener("https://cdn.sonr.id/wasm/app.wasm"); + +// MessageChannel port for WASM communication +let wasmPort; + +// Request queue for offline operations +let requestQueue = new Map(); + +// Setup message channel handler +self.addEventListener('message', async (event) => { + if (event.data.type === 'PORT_INITIALIZATION') { + wasmPort = event.data.port; + setupWasmCommunication(); + } +}); + +function setupWasmCommunication() { + wasmPort.onmessage = async (event) => { + const { type, data } = event.data; + + switch (type) { + case 'WASM_REQUEST': + handleWasmRequest(data); + break; + case 'SYNC_REQUEST': + processSyncQueue(); + break; + } + }; + + // Notify that WASM is ready + wasmPort.postMessage({ type: 'WASM_READY' }); +} + +// Enhanced install event +self.addEventListener("install", (event) => { + event.waitUntil( + Promise.all([ + skipWaiting(), + // Cache WASM binary and essential resources + caches.open(CACHE_NAMES.wasm).then(cache => + cache.addAll([ + 'https://cdn.sonr.id/wasm/app.wasm', + 'https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js' + ]) + ) + ]) + ); +}); + +// Enhanced activate event +self.addEventListener("activate", (event) => { + event.waitUntil( + Promise.all([ + clients.claim(), + // Clean up old caches + caches.keys().then(keys => + Promise.all( + keys.map(key => { + if (!Object.values(CACHE_NAMES).includes(key)) { + return caches.delete(key); + } + }) + ) + ) + ]) + ); +}); + +// Intercept fetch events +self.addEventListener('fetch', (event) => { + const request = event.request; + + // Handle API requests differently from static resources + if (request.url.includes('/api/')) { + event.respondWith(handleApiRequest(request)); + } else { + event.respondWith(handleStaticRequest(request)); + } +}); + +async function handleApiRequest(request) { + try { + // Try to make the request + const response = await fetch(request.clone()); + + // If successful, pass through WASM handler + if (response.ok) { + return await processWasmResponse(request, response); + } + + // If offline or failed, queue the request + await queueRequest(request); + + // Return cached response if available + const cachedResponse = await caches.match(request); + if (cachedResponse) { + return cachedResponse; + } + + // Return offline response + return new Response( + JSON.stringify({ error: 'Currently offline' }), + { + status: 503, + headers: { 'Content-Type': 'application/json' } + } + ); + } catch (error) { + await queueRequest(request); + return new Response( + JSON.stringify({ error: 'Request failed' }), + { + status: 500, + headers: { 'Content-Type': 'application/json' } + } + ); + } +} + +async function handleStaticRequest(request) { + // Check cache first + const cachedResponse = await caches.match(request); + if (cachedResponse) { + return cachedResponse; + } + + try { + const response = await fetch(request); + + // Cache successful responses + if (response.ok) { + const cache = await caches.open(CACHE_NAMES.static); + cache.put(request, response.clone()); + } + + return response; + } catch (error) { + // Return offline page for navigation requests + if (request.mode === 'navigate') { + return caches.match('/offline.html'); + } + throw error; + } +} + +async function processWasmResponse(request, response) { + // Clone the response before processing + const responseClone = response.clone(); + + try { + // Process through WASM + const processedResponse = await wasmInstance.processResponse(responseClone); + + // Notify client through message channel + if (wasmPort) { + wasmPort.postMessage({ + type: 'RESPONSE', + requestId: request.headers.get('X-Wasm-Request-ID'), + response: processedResponse + }); + } + + return processedResponse; + } catch (error) { + console.error('WASM processing error:', error); + return response; + } +} + +async function queueRequest(request) { + const serializedRequest = await serializeRequest(request); + requestQueue.set(request.url, serializedRequest); + + // Register for background sync + try { + await self.registration.sync.register('wasm-sync'); + } catch (error) { + console.error('Sync registration failed:', error); + } +} + +async function serializeRequest(request) { + const headers = {}; + for (const [key, value] of request.headers.entries()) { + headers[key] = value; + } + + return { + url: request.url, + method: request.method, + headers, + body: await request.text(), + timestamp: Date.now() + }; +} + +// Handle background sync +self.addEventListener('sync', (event) => { + if (event.tag === 'wasm-sync') { + event.waitUntil(processSyncQueue()); + } +}); + +async function processSyncQueue() { + const requests = Array.from(requestQueue.values()); + + for (const serializedRequest of requests) { + try { + const response = await fetch(new Request(serializedRequest.url, { + method: serializedRequest.method, + headers: serializedRequest.headers, + body: serializedRequest.body + })); + + if (response.ok) { + requestQueue.delete(serializedRequest.url); + + // Notify client of successful sync + if (wasmPort) { + wasmPort.postMessage({ + type: 'SYNC_COMPLETE', + url: serializedRequest.url + }); + } + } + } catch (error) { + console.error('Sync failed for request:', error); + } + } +} + +// Handle payment requests +self.addEventListener("canmakepayment", function (e) { + e.respondWith(Promise.resolve(true)); +}); + +// Handle periodic sync if available +self.addEventListener('periodicsync', (event) => { + if (event.tag === 'wasm-sync') { + event.waitUntil(processSyncQueue()); + } +}); + diff --git a/x/vault/types/vault.go b/x/vault/types/vault.go deleted file mode 100644 index 6507a6ce5..000000000 --- a/x/vault/types/vault.go +++ /dev/null @@ -1,31 +0,0 @@ -package types - -import ( - "github.com/ipfs/boxo/files" - - "github.com/onsonr/sonr/pkg/motr" - "github.com/onsonr/sonr/pkg/motr/config" -) - -type Vault struct { - FS files.Node -} - -func NewVault(keyshareJSON string, adddress string, chainID string, schema *config.Schema) (*Vault, error) { - dwnCfg := &config.Config{ - MotrKeyshare: keyshareJSON, - MotrAddress: adddress, - IpfsGatewayUrl: "https://ipfs.sonr.land", - SonrApiUrl: "https://api.sonr.land", - SonrRpcUrl: "https://rpc.sonr.land", - SonrChainId: chainID, - VaultSchema: schema, - } - fileMap, err := motr.NewVaultDirectory(dwnCfg) - if err != nil { - return nil, err - } - return &Vault{ - FS: fileMap, - }, nil -} From 1568844255b9396b4bc3a523e790106472782d01 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Sat, 23 Nov 2024 16:32:15 -0500 Subject: [PATCH 04/30] refactor: update templ version to v0.2.778 and remove unused air config --- .air.toml | 51 --------- .gitignore | 4 +- pkg/services/credentials/scripts_templ.go | 2 +- pkg/services/payments/scripts_templ.go | 2 +- pkg/services/storage/scripts_templ.go | 2 +- pkg/webapp/components/auth/authorize_templ.go | 2 +- .../auth/create_credential_templ.go | 2 +- .../components/auth/get_credential_templ.go | 2 +- pkg/webapp/components/auth/login_templ.go | 2 +- .../components/auth/register_start_templ.go | 2 +- pkg/webapp/components/auth/register_templ.go | 2 +- pkg/webapp/components/landing/arch_templ.go | 2 +- pkg/webapp/components/landing/cta_templ.go | 2 +- pkg/webapp/components/landing/footer_templ.go | 2 +- pkg/webapp/components/landing/header_templ.go | 2 +- pkg/webapp/components/landing/hero_templ.go | 2 +- .../components/landing/highlights_templ.go | 2 +- .../components/landing/lowlights_templ.go | 2 +- .../components/landing/mission_templ.go | 2 +- pkg/webapp/components/ui/badges_templ.go | 2 +- pkg/webapp/components/ui/buttons_templ.go | 2 +- pkg/webapp/components/ui/cards_templ.go | 2 +- pkg/webapp/components/ui/icon.templ | 18 +-- pkg/webapp/components/ui/icon_templ.go | 108 +----------------- pkg/webapp/components/ui/layout_templ.go | 2 +- pkg/webapp/components/ui/panels_templ.go | 2 +- pkg/webapp/components/ui/scripts_templ.go | 2 +- pkg/webapp/components/ui/sizes_templ.go | 2 +- pkg/webapp/components/ui/typography_templ.go | 2 +- pkg/webapp/models/{page.go => pages.go} | 0 pkg/webapp/pages/auth_templ.go | 2 +- pkg/webapp/pages/dashboard_templ.go | 2 +- pkg/webapp/pages/landing_templ.go | 2 +- process-compose.yaml | 9 -- 34 files changed, 36 insertions(+), 210 deletions(-) delete mode 100644 .air.toml rename pkg/webapp/models/{page.go => pages.go} (100%) diff --git a/.air.toml b/.air.toml deleted file mode 100644 index 4fa150e97..000000000 --- a/.air.toml +++ /dev/null @@ -1,51 +0,0 @@ -root = "." -testdata_dir = "testdata" -tmp_dir = "tmp" - -[build] -args_bin = [] -bin = "./tmp/main" -cmd = "go build -o ./tmp/main ./cmd/hway/main.go" -delay = 1000 -exclude_dir = ["assets", "tmp", "vendor", "testdata", "pkg/webapp/node_modules"] -exclude_file = [] -exclude_regex = ["_test.go", "_templ.go"] -exclude_unchanged = true -follow_symlink = false -full_bin = "" -include_dir = ["pkg/webapp"] -include_ext = ["go", "tpl", "templ", "html"] -include_file = [] -kill_delay = "0s" -log = "build-errors.log" -poll = false -poll_interval = 0 -post_cmd = [] -pre_cmd = ["templ generate"] -rerun = false -rerun_delay = 500 -send_interrupt = false -stop_on_error = false - -[color] -app = "" -build = "yellow" -main = "magenta" -runner = "green" -watcher = "cyan" - -[log] -main_only = false -time = false - -[misc] -clean_on_exit = false - -[proxy] -app_port = 3000 -enabled = false -proxy_port = 8787 - -[screen] -clear_on_rebuild = true -keep_scroll = true diff --git a/.gitignore b/.gitignore index bf539aa30..204014c97 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ dist # Output of the go coverage tool *.out -.air.toml tmp # Exclude embedded files !internal/files/dist @@ -85,3 +84,6 @@ sonr.wiki !devbox.lock !buf.lock + +.air.toml + diff --git a/pkg/services/credentials/scripts_templ.go b/pkg/services/credentials/scripts_templ.go index a6646451f..a12f1871e 100644 --- a/pkg/services/credentials/scripts_templ.go +++ b/pkg/services/credentials/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package credentials //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/services/payments/scripts_templ.go b/pkg/services/payments/scripts_templ.go index d75fc7134..63f0fa290 100644 --- a/pkg/services/payments/scripts_templ.go +++ b/pkg/services/payments/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package payments diff --git a/pkg/services/storage/scripts_templ.go b/pkg/services/storage/scripts_templ.go index b413849b6..aeed45ca9 100644 --- a/pkg/services/storage/scripts_templ.go +++ b/pkg/services/storage/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package storage //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/authorize_templ.go b/pkg/webapp/components/auth/authorize_templ.go index ad2c23bf7..961b0b757 100644 --- a/pkg/webapp/components/auth/authorize_templ.go +++ b/pkg/webapp/components/auth/authorize_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/create_credential_templ.go b/pkg/webapp/components/auth/create_credential_templ.go index 11f0103ea..eea1973f6 100644 --- a/pkg/webapp/components/auth/create_credential_templ.go +++ b/pkg/webapp/components/auth/create_credential_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/get_credential_templ.go b/pkg/webapp/components/auth/get_credential_templ.go index bfb597672..75368de9a 100644 --- a/pkg/webapp/components/auth/get_credential_templ.go +++ b/pkg/webapp/components/auth/get_credential_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/login_templ.go b/pkg/webapp/components/auth/login_templ.go index f7251cb92..6951af203 100644 --- a/pkg/webapp/components/auth/login_templ.go +++ b/pkg/webapp/components/auth/login_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/register_start_templ.go b/pkg/webapp/components/auth/register_start_templ.go index 35ee1d9f5..717370e4d 100644 --- a/pkg/webapp/components/auth/register_start_templ.go +++ b/pkg/webapp/components/auth/register_start_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/register_templ.go b/pkg/webapp/components/auth/register_templ.go index 231cc7bcf..17449b7c6 100644 --- a/pkg/webapp/components/auth/register_templ.go +++ b/pkg/webapp/components/auth/register_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/arch_templ.go b/pkg/webapp/components/landing/arch_templ.go index 81225c9f9..e5e8a1b2e 100644 --- a/pkg/webapp/components/landing/arch_templ.go +++ b/pkg/webapp/components/landing/arch_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/cta_templ.go b/pkg/webapp/components/landing/cta_templ.go index 8414bbef0..a3a12ab86 100644 --- a/pkg/webapp/components/landing/cta_templ.go +++ b/pkg/webapp/components/landing/cta_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/footer_templ.go b/pkg/webapp/components/landing/footer_templ.go index 2621849e4..c3000b9d2 100644 --- a/pkg/webapp/components/landing/footer_templ.go +++ b/pkg/webapp/components/landing/footer_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package landing diff --git a/pkg/webapp/components/landing/header_templ.go b/pkg/webapp/components/landing/header_templ.go index 2a948dbb9..bd4e740f3 100644 --- a/pkg/webapp/components/landing/header_templ.go +++ b/pkg/webapp/components/landing/header_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/hero_templ.go b/pkg/webapp/components/landing/hero_templ.go index d3cd16ae9..fb3bd7f42 100644 --- a/pkg/webapp/components/landing/hero_templ.go +++ b/pkg/webapp/components/landing/hero_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/highlights_templ.go b/pkg/webapp/components/landing/highlights_templ.go index 753f3be5f..2d3b62e7d 100644 --- a/pkg/webapp/components/landing/highlights_templ.go +++ b/pkg/webapp/components/landing/highlights_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/lowlights_templ.go b/pkg/webapp/components/landing/lowlights_templ.go index 1bd2e3dfb..ad8b1b5a7 100644 --- a/pkg/webapp/components/landing/lowlights_templ.go +++ b/pkg/webapp/components/landing/lowlights_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/mission_templ.go b/pkg/webapp/components/landing/mission_templ.go index 2fccf7548..33347e3c0 100644 --- a/pkg/webapp/components/landing/mission_templ.go +++ b/pkg/webapp/components/landing/mission_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/badges_templ.go b/pkg/webapp/components/ui/badges_templ.go index ffc481bfa..606c77c21 100644 --- a/pkg/webapp/components/ui/badges_templ.go +++ b/pkg/webapp/components/ui/badges_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/buttons_templ.go b/pkg/webapp/components/ui/buttons_templ.go index e53fd6e65..899f2633b 100644 --- a/pkg/webapp/components/ui/buttons_templ.go +++ b/pkg/webapp/components/ui/buttons_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/cards_templ.go b/pkg/webapp/components/ui/cards_templ.go index ca641cded..fdae71090 100644 --- a/pkg/webapp/components/ui/cards_templ.go +++ b/pkg/webapp/components/ui/cards_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/icon.templ b/pkg/webapp/components/ui/icon.templ index f1ba979a7..31d71e24c 100644 --- a/pkg/webapp/components/ui/icon.templ +++ b/pkg/webapp/components/ui/icon.templ @@ -22,10 +22,8 @@ const ( FaBrands FontAwesome = "fa-brands" ) -func Icon(s FontAwesome) IconFunc { - return func(name string) templ.Component { - return renderIcon(s, name) - } +func (s FontAwesome) Icon(name string) templ.Component { + return renderIcon(s, name) } func renderIcon(s FontAwesome, name string) templ.Component { @@ -39,15 +37,3 @@ func formatIconClass(s FontAwesome, name string) string { templ faIcon(class string) { } - -templ RegularIcon() { -} - -templ LightIcon() { -} - -templ ThinIcon() { -} - -templ BrandsIcon() { -} diff --git a/pkg/webapp/components/ui/icon_templ.go b/pkg/webapp/components/ui/icon_templ.go index 040e75f23..c19814e20 100644 --- a/pkg/webapp/components/ui/icon_templ.go +++ b/pkg/webapp/components/ui/icon_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -30,10 +30,8 @@ const ( FaBrands FontAwesome = "fa-brands" ) -func Icon(s FontAwesome) IconFunc { - return func(name string) templ.Component { - return renderIcon(s, name) - } +func (s FontAwesome) Icon(name string) templ.Component { + return renderIcon(s, name) } func renderIcon(s FontAwesome, name string) templ.Component { @@ -91,104 +89,4 @@ func faIcon(class string) templ.Component { }) } -func RegularIcon() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var4 := templ.GetChildren(ctx) - if templ_7745c5c3_Var4 == nil { - templ_7745c5c3_Var4 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - return templ_7745c5c3_Err - }) -} - -func LightIcon() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var5 := templ.GetChildren(ctx) - if templ_7745c5c3_Var5 == nil { - templ_7745c5c3_Var5 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - return templ_7745c5c3_Err - }) -} - -func ThinIcon() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var6 := templ.GetChildren(ctx) - if templ_7745c5c3_Var6 == nil { - templ_7745c5c3_Var6 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - return templ_7745c5c3_Err - }) -} - -func BrandsIcon() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var7 := templ.GetChildren(ctx) - if templ_7745c5c3_Var7 == nil { - templ_7745c5c3_Var7 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - return templ_7745c5c3_Err - }) -} - var _ = templruntime.GeneratedTemplate diff --git a/pkg/webapp/components/ui/layout_templ.go b/pkg/webapp/components/ui/layout_templ.go index 8aa496d19..093fe9b8b 100644 --- a/pkg/webapp/components/ui/layout_templ.go +++ b/pkg/webapp/components/ui/layout_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/panels_templ.go b/pkg/webapp/components/ui/panels_templ.go index a7df7e25c..439d6a52e 100644 --- a/pkg/webapp/components/ui/panels_templ.go +++ b/pkg/webapp/components/ui/panels_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/scripts_templ.go b/pkg/webapp/components/ui/scripts_templ.go index 86e24b9d6..71d6f3d5e 100644 --- a/pkg/webapp/components/ui/scripts_templ.go +++ b/pkg/webapp/components/ui/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/sizes_templ.go b/pkg/webapp/components/ui/sizes_templ.go index 52047ba52..09a5f47c3 100644 --- a/pkg/webapp/components/ui/sizes_templ.go +++ b/pkg/webapp/components/ui/sizes_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/typography_templ.go b/pkg/webapp/components/ui/typography_templ.go index c0ac9d207..fc49235a8 100644 --- a/pkg/webapp/components/ui/typography_templ.go +++ b/pkg/webapp/components/ui/typography_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/models/page.go b/pkg/webapp/models/pages.go similarity index 100% rename from pkg/webapp/models/page.go rename to pkg/webapp/models/pages.go diff --git a/pkg/webapp/pages/auth_templ.go b/pkg/webapp/pages/auth_templ.go index 79fcf26db..1e9cc4ff4 100644 --- a/pkg/webapp/pages/auth_templ.go +++ b/pkg/webapp/pages/auth_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package pages //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/pages/dashboard_templ.go b/pkg/webapp/pages/dashboard_templ.go index ed2ca5ca4..4708ea891 100644 --- a/pkg/webapp/pages/dashboard_templ.go +++ b/pkg/webapp/pages/dashboard_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package pages //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/pages/landing_templ.go b/pkg/webapp/pages/landing_templ.go index 4efb12569..912b46b8f 100644 --- a/pkg/webapp/pages/landing_templ.go +++ b/pkg/webapp/pages/landing_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.793 +// templ: version: v0.2.778 package pages diff --git a/process-compose.yaml b/process-compose.yaml index a75d2524b..40f822b48 100644 --- a/process-compose.yaml +++ b/process-compose.yaml @@ -17,12 +17,3 @@ processes: max_restarts: 1 depends: - ipfs - - hway: - namespace: testnet - command: "air" - background: true - restart: never - max_restarts: 1 - depends: - - sonr From e04d071ca797669bb1bf0e52ed612ac2c41a74bf Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 13:54:33 -0500 Subject: [PATCH 05/30] refactor: update devbox configuration and scripts --- Makefile | 5 +- deploy/local/devbox.json | 34 +++ deploy/local/devbox.lock | 251 ++++++++++++++++++ deploy/local/process-compose.yaml | 28 ++ deploy/testnet/devbox.json | 43 +++ .../testnet/process-compose.yaml | 4 +- devbox.json | 37 +-- devbox.lock | 60 +---- pkg/services/credentials/scripts_templ.go | 2 +- pkg/services/payments/scripts_templ.go | 2 +- pkg/services/storage/scripts_templ.go | 2 +- pkg/webapp/components/auth/authorize_templ.go | 2 +- .../auth/create_credential_templ.go | 2 +- .../components/auth/get_credential_templ.go | 2 +- pkg/webapp/components/auth/login_templ.go | 2 +- .../components/auth/register_start_templ.go | 2 +- pkg/webapp/components/auth/register_templ.go | 2 +- pkg/webapp/components/landing/arch_templ.go | 2 +- pkg/webapp/components/landing/cta_templ.go | 2 +- pkg/webapp/components/landing/footer_templ.go | 2 +- pkg/webapp/components/landing/header_templ.go | 2 +- pkg/webapp/components/landing/hero_templ.go | 2 +- .../components/landing/highlights_templ.go | 2 +- .../components/landing/lowlights_templ.go | 2 +- .../components/landing/mission_templ.go | 2 +- pkg/webapp/components/ui/badges_templ.go | 2 +- pkg/webapp/components/ui/buttons_templ.go | 2 +- pkg/webapp/components/ui/cards_templ.go | 2 +- pkg/webapp/components/ui/icon_templ.go | 2 +- pkg/webapp/components/ui/layout_templ.go | 2 +- pkg/webapp/components/ui/panels_templ.go | 2 +- pkg/webapp/components/ui/scripts_templ.go | 2 +- pkg/webapp/components/ui/sizes_templ.go | 2 +- pkg/webapp/components/ui/typography_templ.go | 2 +- pkg/webapp/pages/auth_templ.go | 2 +- pkg/webapp/pages/dashboard_templ.go | 2 +- pkg/webapp/pages/landing_templ.go | 2 +- pkl/README.md | 4 - scripts/init_env.sh | 28 +- scripts/setup_ipfs.sh | 27 -- slumber.yml | 45 ---- web/libs/noble-client | 1 - web/libs/osmosis-client | 1 - web/libs/sonr-client | 1 - web/workers/noble-client/.gitignore | 5 + web/workers/noble-client/README.md | 9 + web/workers/noble-client/package.json | 16 ++ web/workers/noble-client/src/index.js | 45 ++++ web/workers/noble-client/src/stub.js | 26 ++ web/workers/noble-client/wrangler.toml | 113 ++++++++ web/workers/osmosis-client/.gitignore | 5 + web/workers/osmosis-client/README.md | 10 + web/workers/osmosis-client/package.json | 16 ++ web/workers/osmosis-client/src/index.js | 45 ++++ web/workers/osmosis-client/src/stub.js | 26 ++ web/workers/osmosis-client/wrangler.toml | 113 ++++++++ web/workers/sonr-client/.gitignore | 5 + web/workers/sonr-client/README.md | 10 + web/workers/sonr-client/bun.lockb | Bin 0 -> 106594 bytes web/workers/sonr-client/package.json | 16 ++ web/workers/sonr-client/src/index.js | 45 ++++ web/workers/sonr-client/src/stub.js | 26 ++ web/workers/sonr-client/wrangler.toml | 113 ++++++++ 63 files changed, 1069 insertions(+), 202 deletions(-) create mode 100644 deploy/local/devbox.json create mode 100644 deploy/local/devbox.lock create mode 100644 deploy/local/process-compose.yaml create mode 100644 deploy/testnet/devbox.json rename process-compose.yaml => deploy/testnet/process-compose.yaml (77%) delete mode 100644 pkl/README.md mode change 100644 => 100755 scripts/init_env.sh delete mode 100755 scripts/setup_ipfs.sh delete mode 100644 slumber.yml delete mode 160000 web/libs/noble-client delete mode 160000 web/libs/osmosis-client delete mode 160000 web/libs/sonr-client create mode 100644 web/workers/noble-client/.gitignore create mode 100644 web/workers/noble-client/README.md create mode 100644 web/workers/noble-client/package.json create mode 100644 web/workers/noble-client/src/index.js create mode 100644 web/workers/noble-client/src/stub.js create mode 100644 web/workers/noble-client/wrangler.toml create mode 100644 web/workers/osmosis-client/.gitignore create mode 100644 web/workers/osmosis-client/README.md create mode 100644 web/workers/osmosis-client/package.json create mode 100644 web/workers/osmosis-client/src/index.js create mode 100644 web/workers/osmosis-client/src/stub.js create mode 100644 web/workers/osmosis-client/wrangler.toml create mode 100644 web/workers/sonr-client/.gitignore create mode 100644 web/workers/sonr-client/README.md create mode 100755 web/workers/sonr-client/bun.lockb create mode 100644 web/workers/sonr-client/package.json create mode 100644 web/workers/sonr-client/src/index.js create mode 100644 web/workers/sonr-client/src/stub.js create mode 100644 web/workers/sonr-client/wrangler.toml diff --git a/Makefile b/Makefile index 87cf4f835..fda10386a 100644 --- a/Makefile +++ b/Makefile @@ -286,7 +286,10 @@ testnet-basic: setup-testnet sh-testnet: mod-tidy CHAIN_ID="sonr-testnet-1" BLOCK_TIME="1000ms" CLEAN=true sh scripts/test_node.sh -.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet +buf-publish: + cd ./proto && bunx buf dep update && bunx buf build && bunx buf push + +.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet buf-publish ############################################################################### ### help ### diff --git a/deploy/local/devbox.json b/deploy/local/devbox.json new file mode 100644 index 000000000..7161a4296 --- /dev/null +++ b/deploy/local/devbox.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", + "packages": [ + "go@1.22", + "bun@latest", + "ipfs@latest", + "skate@latest", + "air@latest", + "templ@latest" + ], + "env": { + "GOPATH": "$HOME/go", + "CHAIN_ID": "sonr-testnet-1", + "DENOM": "usnr", + "KEYRING": "test", + "MONIKER": "florence", + "BINARY": "sonrd", + "ACC0_NAME": "acc0", + "ACC1_NAME": "acc1", + "ACC0_ADDRESS": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y", + "ACC1_ADDRESS": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd", + "ACC0_MNEMONIC": "$(skate get ACC0_MNEMONIC)", + "ACC1_MNEMONIC": "$(skate get ACC1_MNEMONIC)" + }, + "shell": { + "init_hook": ["export ROOT=$(git rev-parse --show-toplevel)"], + "scripts": { + "devnet": ["cd $ROOT", "make sh-testnet"], + "ipfs": ["ipfs daemon"], + "air": ["cd $ROOT", "air"], + "gex": ["gex"] + } + } +} diff --git a/deploy/local/devbox.lock b/deploy/local/devbox.lock new file mode 100644 index 000000000..e2633ad0f --- /dev/null +++ b/deploy/local/devbox.lock @@ -0,0 +1,251 @@ +{ + "lockfile_version": "1", + "packages": { + "air@latest": { + "last_modified": "2024-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#air", + "source": "devbox-search", + "version": "1.61.1", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1", + "default": true + } + ], + "store_path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1", + "default": true + } + ], + "store_path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1", + "default": true + } + ], + "store_path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1", + "default": true + } + ], + "store_path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1" + } + } + }, + "bun@latest": { + "last_modified": "2024-11-18T00:41:09Z", + "resolved": "github:NixOS/nixpkgs/5083ec887760adfe12af64830a66807423a859a7#bun", + "source": "devbox-search", + "version": "1.1.34", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/xnj00gq1mfffvgyisghk4m9f38gc5c5c-bun-1.1.34", + "default": true + } + ], + "store_path": "/nix/store/xnj00gq1mfffvgyisghk4m9f38gc5c5c-bun-1.1.34" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/kccpzv8fb7swmmxbhv805qzq242rhy33-bun-1.1.34", + "default": true + } + ], + "store_path": "/nix/store/kccpzv8fb7swmmxbhv805qzq242rhy33-bun-1.1.34" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8h5k3l4fpgs3al2wvna7x9ybyyc8k36d-bun-1.1.34", + "default": true + } + ], + "store_path": "/nix/store/8h5k3l4fpgs3al2wvna7x9ybyyc8k36d-bun-1.1.34" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/x089g4srqw71w5jnc87vxbh7m12498i0-bun-1.1.34", + "default": true + } + ], + "store_path": "/nix/store/x089g4srqw71w5jnc87vxbh7m12498i0-bun-1.1.34" + } + } + }, + "go@1.22": { + "last_modified": "2024-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#go_1_22", + "source": "devbox-search", + "version": "1.22.9", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/4nf51i4ah186y2jy3fad2fyvpa49qx6q-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/4nf51i4ah186y2jy3fad2fyvpa49qx6q-go-1.22.9" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8w8vzwgp55yl8j1ljgm4wzdgjkvkv5v3-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/8w8vzwgp55yl8j1ljgm4wzdgjkvkv5v3-go-1.22.9" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/vlih7j78ki05i8nvzdsxvws7a7ksq04m-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/vlih7j78ki05i8nvzdsxvws7a7ksq04m-go-1.22.9" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/frc5188kgv3ws0n999c7cy5vi2f8k4jp-go-1.22.9", + "default": true + } + ], + "store_path": "/nix/store/frc5188kgv3ws0n999c7cy5vi2f8k4jp-go-1.22.9" + } + } + }, + "ipfs@latest": { + "last_modified": "2023-02-24T09:01:09Z", + "resolved": "github:NixOS/nixpkgs/7d0ed7f2e5aea07ab22ccb338d27fbe347ed2f11#ipfs", + "source": "devbox-search", + "version": "0.17.0" + }, + "skate@latest": { + "last_modified": "2024-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#skate", + "source": "devbox-search", + "version": "1.0.0", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/q6yhpyfbqiabyic6ymx5rp2db62bnbvr-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/q6yhpyfbqiabyic6ymx5rp2db62bnbvr-skate-1.0.0" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/q55dbgvc4xwvr2g02dks6j2j699qni2k-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/q55dbgvc4xwvr2g02dks6j2j699qni2k-skate-1.0.0" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/s1hy525y8ciya3nrns9kryy3jlcw8igv-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/s1hy525y8ciya3nrns9kryy3jlcw8igv-skate-1.0.0" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8s03iazymz77nv6pjxpz7wair0m646wv-skate-1.0.0", + "default": true + } + ], + "store_path": "/nix/store/8s03iazymz77nv6pjxpz7wair0m646wv-skate-1.0.0" + } + } + }, + "templ@latest": { + "last_modified": "2024-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#templ", + "source": "devbox-search", + "version": "0.2.793", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/ivargvf76g71k5gk3iz4al52rsy28w38-templ-0.2.793", + "default": true + } + ], + "store_path": "/nix/store/ivargvf76g71k5gk3iz4al52rsy28w38-templ-0.2.793" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/03654iddn006yx5j1lqq496hax60v8p5-templ-0.2.793", + "default": true + } + ], + "store_path": "/nix/store/03654iddn006yx5j1lqq496hax60v8p5-templ-0.2.793" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/blvd5wbd1ix6m745s4zx3b84kwzprshq-templ-0.2.793", + "default": true + } + ], + "store_path": "/nix/store/blvd5wbd1ix6m745s4zx3b84kwzprshq-templ-0.2.793" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/sn5h79d36r86i6a8rm1k52c2ij1s32kx-templ-0.2.793", + "default": true + } + ], + "store_path": "/nix/store/sn5h79d36r86i6a8rm1k52c2ij1s32kx-templ-0.2.793" + } + } + } + } +} diff --git a/deploy/local/process-compose.yaml b/deploy/local/process-compose.yaml new file mode 100644 index 000000000..67e41333f --- /dev/null +++ b/deploy/local/process-compose.yaml @@ -0,0 +1,28 @@ +version: "0.6" + +processes: + ipfs: + namespace: testnet + command: "devbox run ipfs" + background: true + availability: + restart: never + max_restarts: 0 + + sonr: + namespace: testnet + background: true + command: "devbox run devnet" + restart: never + max_restarts: 1 + depends: + - ipfs + + hway-air: + namespace: testnet + background: true + command: "devbox run air" + restart: never + max_restarts: 1 + depends: + - sonr diff --git a/deploy/testnet/devbox.json b/deploy/testnet/devbox.json new file mode 100644 index 000000000..637c1b677 --- /dev/null +++ b/deploy/testnet/devbox.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", + "packages": [ + "go@1.22", + "bun@latest", + "ipfs@latest", + "air@latest", + "templ@latest" + ], + "env": { + "GOPATH": "$HOME/go", + "PATH": "./build:$HOME/go/bin:$PATH", + "CHAIN_ID": "sonr-testnet-1", + "DENOM": "usnr", + "KEYRING": "test", + "MONIKER": "florence", + "BINARY": "sonrd", + "ACC0_NAME": "acc0", + "ACC1_NAME": "acc1", + "ACC0_ADDRESS": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y", + "ACC1_ADDRESS": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd", + "ACC0_MNEMONIC": "$(skate get ACC0_MNEMONIC)", + "ACC1_MNEMONIC": "$(skate get ACC1_MNEMONIC)", + "TUNNEL_TOKEN": "$(skate get CLOUDFLARE_TUNNEL_TOKEN)", + "TEMPL_EXPERIMENT": "rawgo", + "R2_CDN_BUCKET": "cdn", + "R2_PKL_BUCKET": "pkljar" + }, + "shell": { + "init_hook": ["export ROOT=$(git rev-parse --show-toplevel)"], + "scripts": { + "start:testnet": ["make sh-testnet"], + "start:ipfs": ["sh scripts/setup_ipfs.sh"], + "start:air": ["air"], + "start:gex": ["go install github.com/cosmos/gex@latest", "gex"], + "gen:pkl": ["make gen-pkl"], + "gen:templ": ["make gen-templ"], + "buf-push": [ + "cd ./proto && bunx buf dep update && bunx buf build && bunx buf push" + ] + } + } +} diff --git a/process-compose.yaml b/deploy/testnet/process-compose.yaml similarity index 77% rename from process-compose.yaml rename to deploy/testnet/process-compose.yaml index 40f822b48..bb0f06d2e 100644 --- a/process-compose.yaml +++ b/deploy/testnet/process-compose.yaml @@ -3,7 +3,7 @@ version: "0.6" processes: ipfs: namespace: testnet - command: "sh scripts/setup_ipfs.sh" + command: "devbox run start:ipfs" background: true availability: restart: never @@ -12,7 +12,7 @@ processes: sonr: namespace: testnet background: true - command: "make sh-testnet" + command: "devbox run start:testnet" restart: never max_restarts: 1 depends: diff --git a/devbox.json b/devbox.json index e767e1d03..bc31be2f9 100644 --- a/devbox.json +++ b/devbox.json @@ -1,42 +1,17 @@ { "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", - "packages": [ - "go@1.22", - "bun@latest", - "ipfs@latest", - "air@latest", - "templ@latest" - ], + "packages": ["go@1.22", "bun@latest", "ipfs@latest", "templ@latest"], "env": { "GOPATH": "$HOME/go", "PATH": "./build:$HOME/go/bin:$PATH", - "CHAIN_ID": "sonr-testnet-1", - "DENOM": "usnr", - "KEYRING": "test", - "MONIKER": "florence", - "BINARY": "sonrd", - "ACC0_NAME": "acc0", - "ACC1_NAME": "acc1", - "ACC0_ADDRESS": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y", - "ACC1_ADDRESS": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd", - "ACC0_MNEMONIC": "$(skate get ACC0_MNEMONIC)", - "ACC1_MNEMONIC": "$(skate get ACC1_MNEMONIC)", - "TUNNEL_TOKEN": "$(skate get CLOUDFLARE_TUNNEL_TOKEN)", - "TEMPL_EXPERIMENT": "rawgo", - "R2_CDN_BUCKET": "cdn", - "R2_PKL_BUCKET": "pkljar" + "TEMPL_EXPERIMENT": "rawgo" }, "shell": { + "init_hook": ["./scripts/init_env.sh"], "scripts": { - "gen:pkl": [ - "make gen-pkl" - ], - "gen:templ": [ - "make gen-templ" - ], - "buf-push": [ - "cd ./proto && bunx buf dep update && bunx buf build && bunx buf push" - ] + "start-local": ["cd deploy/local && devbox services up"], + "start-testnet": ["cd deploy/testnet && devbox services up"], + "start-gex": ["go install github.com/cosmos/gex@latest", "gex"] } } } diff --git a/devbox.lock b/devbox.lock index c2759642a..d498be17a 100644 --- a/devbox.lock +++ b/devbox.lock @@ -1,54 +1,6 @@ { "lockfile_version": "1", "packages": { - "air@latest": { - "last_modified": "2024-11-16T04:25:12Z", - "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#air", - "source": "devbox-search", - "version": "1.61.1", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1", - "default": true - } - ], - "store_path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1", - "default": true - } - ], - "store_path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1", - "default": true - } - ], - "store_path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1", - "default": true - } - ], - "store_path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1" - } - } - }, "bun@latest": { "last_modified": "2024-10-23T04:36:58Z", "resolved": "github:NixOS/nixpkgs/dfffb2e7a52d29a0ef8e21ec8a0f30487b227f1a#bun", @@ -149,17 +101,7 @@ "last_modified": "2023-02-24T09:01:09Z", "resolved": "github:NixOS/nixpkgs/7d0ed7f2e5aea07ab22ccb338d27fbe347ed2f11#ipfs", "source": "devbox-search", - "version": "0.17.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "path": "/nix/store/1azparhiwjzxgpkswpqnapzw0bfb7vl7-kubo-0.17.0", - "default": true - } - ] - } - } + "version": "0.17.0" }, "templ@latest": { "last_modified": "2024-10-13T23:44:06Z", diff --git a/pkg/services/credentials/scripts_templ.go b/pkg/services/credentials/scripts_templ.go index a12f1871e..a6646451f 100644 --- a/pkg/services/credentials/scripts_templ.go +++ b/pkg/services/credentials/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package credentials //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/services/payments/scripts_templ.go b/pkg/services/payments/scripts_templ.go index 63f0fa290..d75fc7134 100644 --- a/pkg/services/payments/scripts_templ.go +++ b/pkg/services/payments/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package payments diff --git a/pkg/services/storage/scripts_templ.go b/pkg/services/storage/scripts_templ.go index aeed45ca9..b413849b6 100644 --- a/pkg/services/storage/scripts_templ.go +++ b/pkg/services/storage/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package storage //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/authorize_templ.go b/pkg/webapp/components/auth/authorize_templ.go index 961b0b757..ad2c23bf7 100644 --- a/pkg/webapp/components/auth/authorize_templ.go +++ b/pkg/webapp/components/auth/authorize_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/create_credential_templ.go b/pkg/webapp/components/auth/create_credential_templ.go index eea1973f6..11f0103ea 100644 --- a/pkg/webapp/components/auth/create_credential_templ.go +++ b/pkg/webapp/components/auth/create_credential_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/get_credential_templ.go b/pkg/webapp/components/auth/get_credential_templ.go index 75368de9a..bfb597672 100644 --- a/pkg/webapp/components/auth/get_credential_templ.go +++ b/pkg/webapp/components/auth/get_credential_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/login_templ.go b/pkg/webapp/components/auth/login_templ.go index 6951af203..f7251cb92 100644 --- a/pkg/webapp/components/auth/login_templ.go +++ b/pkg/webapp/components/auth/login_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/register_start_templ.go b/pkg/webapp/components/auth/register_start_templ.go index 717370e4d..35ee1d9f5 100644 --- a/pkg/webapp/components/auth/register_start_templ.go +++ b/pkg/webapp/components/auth/register_start_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/auth/register_templ.go b/pkg/webapp/components/auth/register_templ.go index 17449b7c6..231cc7bcf 100644 --- a/pkg/webapp/components/auth/register_templ.go +++ b/pkg/webapp/components/auth/register_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package auth //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/arch_templ.go b/pkg/webapp/components/landing/arch_templ.go index e5e8a1b2e..81225c9f9 100644 --- a/pkg/webapp/components/landing/arch_templ.go +++ b/pkg/webapp/components/landing/arch_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/cta_templ.go b/pkg/webapp/components/landing/cta_templ.go index a3a12ab86..8414bbef0 100644 --- a/pkg/webapp/components/landing/cta_templ.go +++ b/pkg/webapp/components/landing/cta_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/footer_templ.go b/pkg/webapp/components/landing/footer_templ.go index c3000b9d2..2621849e4 100644 --- a/pkg/webapp/components/landing/footer_templ.go +++ b/pkg/webapp/components/landing/footer_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing diff --git a/pkg/webapp/components/landing/header_templ.go b/pkg/webapp/components/landing/header_templ.go index bd4e740f3..2a948dbb9 100644 --- a/pkg/webapp/components/landing/header_templ.go +++ b/pkg/webapp/components/landing/header_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/hero_templ.go b/pkg/webapp/components/landing/hero_templ.go index fb3bd7f42..d3cd16ae9 100644 --- a/pkg/webapp/components/landing/hero_templ.go +++ b/pkg/webapp/components/landing/hero_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/highlights_templ.go b/pkg/webapp/components/landing/highlights_templ.go index 2d3b62e7d..753f3be5f 100644 --- a/pkg/webapp/components/landing/highlights_templ.go +++ b/pkg/webapp/components/landing/highlights_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/lowlights_templ.go b/pkg/webapp/components/landing/lowlights_templ.go index ad8b1b5a7..1bd2e3dfb 100644 --- a/pkg/webapp/components/landing/lowlights_templ.go +++ b/pkg/webapp/components/landing/lowlights_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/landing/mission_templ.go b/pkg/webapp/components/landing/mission_templ.go index 33347e3c0..2fccf7548 100644 --- a/pkg/webapp/components/landing/mission_templ.go +++ b/pkg/webapp/components/landing/mission_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package landing //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/badges_templ.go b/pkg/webapp/components/ui/badges_templ.go index 606c77c21..ffc481bfa 100644 --- a/pkg/webapp/components/ui/badges_templ.go +++ b/pkg/webapp/components/ui/badges_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/buttons_templ.go b/pkg/webapp/components/ui/buttons_templ.go index 899f2633b..e53fd6e65 100644 --- a/pkg/webapp/components/ui/buttons_templ.go +++ b/pkg/webapp/components/ui/buttons_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/cards_templ.go b/pkg/webapp/components/ui/cards_templ.go index fdae71090..ca641cded 100644 --- a/pkg/webapp/components/ui/cards_templ.go +++ b/pkg/webapp/components/ui/cards_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/icon_templ.go b/pkg/webapp/components/ui/icon_templ.go index c19814e20..616b2de8c 100644 --- a/pkg/webapp/components/ui/icon_templ.go +++ b/pkg/webapp/components/ui/icon_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/layout_templ.go b/pkg/webapp/components/ui/layout_templ.go index 093fe9b8b..8aa496d19 100644 --- a/pkg/webapp/components/ui/layout_templ.go +++ b/pkg/webapp/components/ui/layout_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/panels_templ.go b/pkg/webapp/components/ui/panels_templ.go index 439d6a52e..a7df7e25c 100644 --- a/pkg/webapp/components/ui/panels_templ.go +++ b/pkg/webapp/components/ui/panels_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/scripts_templ.go b/pkg/webapp/components/ui/scripts_templ.go index 71d6f3d5e..86e24b9d6 100644 --- a/pkg/webapp/components/ui/scripts_templ.go +++ b/pkg/webapp/components/ui/scripts_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/sizes_templ.go b/pkg/webapp/components/ui/sizes_templ.go index 09a5f47c3..52047ba52 100644 --- a/pkg/webapp/components/ui/sizes_templ.go +++ b/pkg/webapp/components/ui/sizes_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/components/ui/typography_templ.go b/pkg/webapp/components/ui/typography_templ.go index fc49235a8..c0ac9d207 100644 --- a/pkg/webapp/components/ui/typography_templ.go +++ b/pkg/webapp/components/ui/typography_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package ui //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/pages/auth_templ.go b/pkg/webapp/pages/auth_templ.go index 1e9cc4ff4..79fcf26db 100644 --- a/pkg/webapp/pages/auth_templ.go +++ b/pkg/webapp/pages/auth_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package pages //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/pages/dashboard_templ.go b/pkg/webapp/pages/dashboard_templ.go index 4708ea891..ed2ca5ca4 100644 --- a/pkg/webapp/pages/dashboard_templ.go +++ b/pkg/webapp/pages/dashboard_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package pages //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/pkg/webapp/pages/landing_templ.go b/pkg/webapp/pages/landing_templ.go index 912b46b8f..4efb12569 100644 --- a/pkg/webapp/pages/landing_templ.go +++ b/pkg/webapp/pages/landing_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.2.778 +// templ: version: v0.2.793 package pages diff --git a/pkl/README.md b/pkl/README.md deleted file mode 100644 index e32b62034..000000000 --- a/pkl/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# pkl - -This is a project to generate a language-agnostic, type-safe, and idiomatic -Go code from a [Pkl](https://pkl-lang.org) file. diff --git a/scripts/init_env.sh b/scripts/init_env.sh old mode 100644 new mode 100755 index f1f641af1..236e666d2 --- a/scripts/init_env.sh +++ b/scripts/init_env.sh @@ -1 +1,27 @@ -#!/usr/bin/env bash +#!/bin/bash + +go install github.com/cosmos/gex@latest + +rm -rf ~/.ipfs + +# Initialize IPFS +ipfs init + +# Set up the Cloudflare IPFS gateway peers +ipfs config --json Peering.Peers '[ +{"ID": "QmcFf2FH3CEgTNHeMRGhN7HNHU1EXAxoEk6EFuSyXCsvRE", "Addrs": ["/dnsaddr/node-1.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcFmLd5ySfk2WZuJ1mfSWLDjdmHZq7rSAua4GoeSQfs1z", "Addrs": ["/dnsaddr/node-2.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcfFmzSDVbwexQ9Au2pt5YEXHK5xajwgaU6PpkbLWerMa", "Addrs": ["/dnsaddr/node-3.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcfJeB3Js1FG7T8YaZATEiaHqNKVdQfybYYkbT1knUswx", "Addrs": ["/dnsaddr/node-4.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcfVvzK4tMdFmpJjEKDUoqRgP4W9FnmJoziYX5GXJJ8eZ", "Addrs": ["/dnsaddr/node-5.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcfZD3VKrUxyP9BbyUnZDpbqDnT7cQ4WjPP8TRLXaoE7G", "Addrs": ["/dnsaddr/node-6.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcfZP2LuW4jxviTeG8fi28qjnZScACb8PEgHAc17ZEri3", "Addrs": ["/dnsaddr/node-7.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcfgsJsMtx6qJb74akCw1M24X1zFwgGo11h1cuhwQjtJP", "Addrs": ["/dnsaddr/node-8.ingress.cloudflare-ipfs.com"]}, +{"ID": "Qmcfr2FC7pFzJbTSDfYaSy1J8Uuy8ccGLeLyqJCKJvTHMi", "Addrs": ["/dnsaddr/node-9.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcfR3V5YAtHBzxVACWCzXTt26SyEkxdwhGJ6875A8BuWx", "Addrs": ["/dnsaddr/node-10.ingress.cloudflare-ipfs.com"]}, +{"ID": "Qmcfuo1TM9uUiJp6dTbm915Rf1aTqm3a3dnmCdDQLHgvL5", "Addrs": ["/dnsaddr/node-11.ingress.cloudflare-ipfs.com"]}, +{"ID": "QmcfV2sg9zaq7UUHVCGuSvT2M2rnLBAPsiE79vVyK3Cuev", "Addrs": ["/dnsaddr/node-12.ingress.cloudflare-ipfs.com"]} +]' + +# Make sure ipfs is publicly accessible +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' diff --git a/scripts/setup_ipfs.sh b/scripts/setup_ipfs.sh deleted file mode 100755 index b98c18d5a..000000000 --- a/scripts/setup_ipfs.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -rm -rf ~/.ipfs - -# Initialize IPFS -ipfs init - -# Set up the Cloudflare IPFS gateway peers -ipfs config --json Peering.Peers '[ -{"ID": "QmcFf2FH3CEgTNHeMRGhN7HNHU1EXAxoEk6EFuSyXCsvRE", "Addrs": ["/dnsaddr/node-1.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcFmLd5ySfk2WZuJ1mfSWLDjdmHZq7rSAua4GoeSQfs1z", "Addrs": ["/dnsaddr/node-2.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfFmzSDVbwexQ9Au2pt5YEXHK5xajwgaU6PpkbLWerMa", "Addrs": ["/dnsaddr/node-3.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfJeB3Js1FG7T8YaZATEiaHqNKVdQfybYYkbT1knUswx", "Addrs": ["/dnsaddr/node-4.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfVvzK4tMdFmpJjEKDUoqRgP4W9FnmJoziYX5GXJJ8eZ", "Addrs": ["/dnsaddr/node-5.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfZD3VKrUxyP9BbyUnZDpbqDnT7cQ4WjPP8TRLXaoE7G", "Addrs": ["/dnsaddr/node-6.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfZP2LuW4jxviTeG8fi28qjnZScACb8PEgHAc17ZEri3", "Addrs": ["/dnsaddr/node-7.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfgsJsMtx6qJb74akCw1M24X1zFwgGo11h1cuhwQjtJP", "Addrs": ["/dnsaddr/node-8.ingress.cloudflare-ipfs.com"]}, -{"ID": "Qmcfr2FC7pFzJbTSDfYaSy1J8Uuy8ccGLeLyqJCKJvTHMi", "Addrs": ["/dnsaddr/node-9.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfR3V5YAtHBzxVACWCzXTt26SyEkxdwhGJ6875A8BuWx", "Addrs": ["/dnsaddr/node-10.ingress.cloudflare-ipfs.com"]}, -{"ID": "Qmcfuo1TM9uUiJp6dTbm915Rf1aTqm3a3dnmCdDQLHgvL5", "Addrs": ["/dnsaddr/node-11.ingress.cloudflare-ipfs.com"]}, -{"ID": "QmcfV2sg9zaq7UUHVCGuSvT2M2rnLBAPsiE79vVyK3Cuev", "Addrs": ["/dnsaddr/node-12.ingress.cloudflare-ipfs.com"]} -]' - -# Make sure ipfs is publicly accessible -ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' - -ipfs daemon diff --git a/slumber.yml b/slumber.yml deleted file mode 100644 index 158c1a8b5..000000000 --- a/slumber.yml +++ /dev/null @@ -1,45 +0,0 @@ -# For basic usage info, see: -# https://slumber.lucaspickering.me/book/getting_started.html -# For all collection options, see: -# https://slumber.lucaspickering.me/book/api/request_collection/index.html - -# Profiles are groups of data you can easily switch between. A common usage is -# to define profiles for various environments of a REST service -# slumber.yml -profiles: - local: - data: - host: http://localhost:1317 - production: - data: - host: https://api.sonr.id - -requests: - did: !folder - name: Params - requests: - did_params: !request - method: GET - url: "{{host}}/did/v1/params" - macaroon_params: !request - method: GET - url: "{{host}}/macaroon/v1/params" - service_params: !request - method: GET - url: "{{host}}/service/v1/params" - vault_params: !request - method: GET - url: "{{host}}/vault/v1/params" - - vault: !folder - name: Vault - requests: - vault_allocate: !request - method: GET - url: "{{host}}/vault/v1/allocate" - vault_schema: !request - method: GET - url: "{{host}}/vault/v1/schema" - vault_sync: !request - method: GET - url: "{{host}}/vault/v1/sync" diff --git a/web/libs/noble-client b/web/libs/noble-client deleted file mode 160000 index 712a041f4..000000000 --- a/web/libs/noble-client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 712a041f4fa040be8c53ca0c701f961c59a22233 diff --git a/web/libs/osmosis-client b/web/libs/osmosis-client deleted file mode 160000 index e9529062b..000000000 --- a/web/libs/osmosis-client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e9529062bc943894e14b67a48a665b0f7e4aabb4 diff --git a/web/libs/sonr-client b/web/libs/sonr-client deleted file mode 160000 index d002aa61f..000000000 --- a/web/libs/sonr-client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d002aa61f0fed83c3227c146d329b58927975b5d diff --git a/web/workers/noble-client/.gitignore b/web/workers/noble-client/.gitignore new file mode 100644 index 000000000..90cfa7c2d --- /dev/null +++ b/web/workers/noble-client/.gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +.env +dist +out diff --git a/web/workers/noble-client/README.md b/web/workers/noble-client/README.md new file mode 100644 index 000000000..e83bd8757 --- /dev/null +++ b/web/workers/noble-client/README.md @@ -0,0 +1,9 @@ +# `noble-client` + +This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. + +It uses `noble-es` to provide a simple interface to interact with the Sonr network. + +## Usage + +### Deploying to Cloudflare diff --git a/web/workers/noble-client/package.json b/web/workers/noble-client/package.json new file mode 100644 index 000000000..b8b7b285d --- /dev/null +++ b/web/workers/noble-client/package.json @@ -0,0 +1,16 @@ +{ + "name": "noble-client", + "version": "0.0.0", + "private": true, + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev", + "start": "wrangler dev" + }, + "devDependencies": { + "wrangler": "^3.60.3" + }, + "dependencies": { + "sonr-es": "^0.5.3" + } +} diff --git a/web/workers/noble-client/src/index.js b/web/workers/noble-client/src/index.js new file mode 100644 index 000000000..2ae2b739e --- /dev/null +++ b/web/workers/noble-client/src/index.js @@ -0,0 +1,45 @@ +export * from "./stub.js"; + +/** + * Welcome to Cloudflare Workers! This is your first Durable Objects application. + * + * - Run `npm run dev` in your terminal to start a development server + * - Open a browser tab at http://localhost:8787/ to see your Durable Object in action + * - Run `npm run deploy` to publish your application + * + * Learn more at https://developers.cloudflare.com/durable-objects + */ + +/** + * Env provides a mechanism to reference bindings declared in wrangler.toml within JavaScript + * + * @typedef {Object} Env + * @property {DurableObjectNamespace} NOBLE_DURABLE_CLIENT - The Durable Object namespace binding + */ + + +export default { + /** + * This is the standard fetch handler for a Cloudflare Worker + * + * @param {Request} request - The request submitted to the Worker from the client + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + * @param {ExecutionContext} ctx - The execution context of the Worker + * @returns {Promise} The response to be sent back to the client + */ + async fetch(request, env, ctx) { + // We will create a `DurableObjectId` using the pathname from the Worker request + // This id refers to a unique instance of our 'MyDurableObject' class above + let id = env.NOBLE_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); + + // This stub creates a communication channel with the Durable Object instance + // The Durable Object constructor will be invoked upon the first call for a given id + let stub = env.NOBLE_DURABLE_CLIENT.get(id); + + // We call the `sayHello()` RPC method on the stub to invoke the method on the remote + // Durable Object instance + let greeting = await stub.sayHello("world"); + + return new Response(greeting); + }, +}; diff --git a/web/workers/noble-client/src/stub.js b/web/workers/noble-client/src/stub.js new file mode 100644 index 000000000..10d27bb12 --- /dev/null +++ b/web/workers/noble-client/src/stub.js @@ -0,0 +1,26 @@ +import { DurableObject } from "cloudflare:workers"; + +/** A Durable Object's behavior is defined in an exported Javascript class */ +export class NobleDurableClient extends DurableObject { + /** + * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to + * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) + * + * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + */ + constructor(ctx, env) { + super(ctx, env); + } + + /** + * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable + * Object instance receives a request from a Worker via the same method invocation on the stub + * + * @param {string} name - The name provided to a Durable Object instance from a Worker + * @returns {Promise} The greeting to be sent back to the Worker + */ + async sayHello(name) { + return `Hello, ${name}!`; + } +} diff --git a/web/workers/noble-client/wrangler.toml b/web/workers/noble-client/wrangler.toml new file mode 100644 index 000000000..8f4a4020a --- /dev/null +++ b/web/workers/noble-client/wrangler.toml @@ -0,0 +1,113 @@ +#:schema node_modules/wrangler/config-schema.json +name = "noble-client" +main = "src/index.js" +compatibility_date = "2024-11-12" + +# Workers Logs +# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ +# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs +[observability] +enabled = true + +# Automatically place your workloads in an optimal location to minimize latency. +# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure +# rather than the end user may result in better performance. +# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement +# [placement] +# mode = "smart" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Docs: +# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables +# Note: Use secrets to store sensitive data. +# - https://developers.cloudflare.com/workers/configuration/secrets/ +# [vars] +# MY_VARIABLE = "production_value" + +# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai +# [ai] +# binding = "AI" + +# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets +# [[analytics_engine_datasets]] +# binding = "MY_DATASET" + +# Bind a headless browser instance running on Cloudflare's global network. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering +# [browser] +# binding = "MY_BROWSER" + +# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases +# [[d1_databases]] +# binding = "MY_DB" +# database_name = "my-database" +# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms +# [[dispatch_namespaces]] +# binding = "MY_DISPATCHER" +# namespace = "my-namespace" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects +[[durable_objects.bindings]] +name = "NOBLE_DURABLE_CLIENT" +class_name = "NobleDurableClient" + +# Durable Object migrations. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations +[[migrations]] +tag = "v1" +new_classes = ["NobleDurableClient"] + +# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive +# [[hyperdrive]] +# binding = "MY_HYPERDRIVE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates +# [[mtls_certificates]] +# binding = "MY_CERTIFICATE" +# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.consumers]] +# queue = "my-queue" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets +# [[r2_buckets]] +# binding = "MY_BUCKET" +# bucket_name = "my-bucket" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes +# [[vectorize]] +# binding = "MY_INDEX" +# index_name = "my-index" diff --git a/web/workers/osmosis-client/.gitignore b/web/workers/osmosis-client/.gitignore new file mode 100644 index 000000000..90cfa7c2d --- /dev/null +++ b/web/workers/osmosis-client/.gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +.env +dist +out diff --git a/web/workers/osmosis-client/README.md b/web/workers/osmosis-client/README.md new file mode 100644 index 000000000..c54afa25e --- /dev/null +++ b/web/workers/osmosis-client/README.md @@ -0,0 +1,10 @@ +# `osmosis-client` + +This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. + +It uses `osmosis-es` to provide a simple interface to interact with the Sonr network. + +## Usage + +### Deploying to Cloudflare + diff --git a/web/workers/osmosis-client/package.json b/web/workers/osmosis-client/package.json new file mode 100644 index 000000000..4dabb65ab --- /dev/null +++ b/web/workers/osmosis-client/package.json @@ -0,0 +1,16 @@ +{ + "name": "sonr-client", + "version": "0.0.0", + "private": true, + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev", + "start": "wrangler dev" + }, + "devDependencies": { + "wrangler": "^3.60.3" + }, + "dependencies": { + "sonr-es": "^0.5.3" + } +} diff --git a/web/workers/osmosis-client/src/index.js b/web/workers/osmosis-client/src/index.js new file mode 100644 index 000000000..940c612d0 --- /dev/null +++ b/web/workers/osmosis-client/src/index.js @@ -0,0 +1,45 @@ +export * from "./stub.js"; + +/** + * Welcome to Cloudflare Workers! This is your first Durable Objects application. + * + * - Run `npm run dev` in your terminal to start a development server + * - Open a browser tab at http://localhost:8787/ to see your Durable Object in action + * - Run `npm run deploy` to publish your application + * + * Learn more at https://developers.cloudflare.com/durable-objects + */ + +/** + * Env provides a mechanism to reference bindings declared in wrangler.toml within JavaScript + * + * @typedef {Object} Env + * @property {DurableObjectNamespace} OSMOSIS_DURABLE_CLIENT - The Durable Object namespace binding + */ + + +export default { + /** + * This is the standard fetch handler for a Cloudflare Worker + * + * @param {Request} request - The request submitted to the Worker from the client + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + * @param {ExecutionContext} ctx - The execution context of the Worker + * @returns {Promise} The response to be sent back to the client + */ + async fetch(request, env, ctx) { + // We will create a `DurableObjectId` using the pathname from the Worker request + // This id refers to a unique instance of our 'MyDurableObject' class above + let id = env.OSMOSIS_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); + + // This stub creates a communication channel with the Durable Object instance + // The Durable Object constructor will be invoked upon the first call for a given id + let stub = env.OSMOSIS_DURABLE_CLIENT.get(id); + + // We call the `sayHello()` RPC method on the stub to invoke the method on the remote + // Durable Object instance + let greeting = await stub.sayHello("world"); + + return new Response(greeting); + }, +}; diff --git a/web/workers/osmosis-client/src/stub.js b/web/workers/osmosis-client/src/stub.js new file mode 100644 index 000000000..f2afbbace --- /dev/null +++ b/web/workers/osmosis-client/src/stub.js @@ -0,0 +1,26 @@ +import { DurableObject } from "cloudflare:workers"; + +/** A Durable Object's behavior is defined in an exported Javascript class */ +export class OsmosisDurableClient extends DurableObject { + /** + * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to + * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) + * + * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + */ + constructor(ctx, env) { + super(ctx, env); + } + + /** + * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable + * Object instance receives a request from a Worker via the same method invocation on the stub + * + * @param {string} name - The name provided to a Durable Object instance from a Worker + * @returns {Promise} The greeting to be sent back to the Worker + */ + async sayHello(name) { + return `Hello, ${name}!`; + } +} diff --git a/web/workers/osmosis-client/wrangler.toml b/web/workers/osmosis-client/wrangler.toml new file mode 100644 index 000000000..e9a92ea58 --- /dev/null +++ b/web/workers/osmosis-client/wrangler.toml @@ -0,0 +1,113 @@ +#:schema node_modules/wrangler/config-schema.json +name = "osmosis-client" +main = "src/index.js" +compatibility_date = "2024-11-12" + +# Workers Logs +# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ +# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs +[observability] +enabled = true + +# Automatically place your workloads in an optimal location to minimize latency. +# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure +# rather than the end user may result in better performance. +# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement +# [placement] +# mode = "smart" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Docs: +# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables +# Note: Use secrets to store sensitive data. +# - https://developers.cloudflare.com/workers/configuration/secrets/ +# [vars] +# MY_VARIABLE = "production_value" + +# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai +# [ai] +# binding = "AI" + +# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets +# [[analytics_engine_datasets]] +# binding = "MY_DATASET" + +# Bind a headless browser instance running on Cloudflare's global network. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering +# [browser] +# binding = "MY_BROWSER" + +# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases +# [[d1_databases]] +# binding = "MY_DB" +# database_name = "my-database" +# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms +# [[dispatch_namespaces]] +# binding = "MY_DISPATCHER" +# namespace = "my-namespace" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects +[[durable_objects.bindings]] +name = "OSMOSIS_DURABLE_CLIENT" +class_name = "OsmosisDurableClient" + +# Durable Object migrations. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations +[[migrations]] +tag = "v1" +new_classes = ["OsmosisDurableClient"] + +# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive +# [[hyperdrive]] +# binding = "MY_HYPERDRIVE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates +# [[mtls_certificates]] +# binding = "MY_CERTIFICATE" +# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.consumers]] +# queue = "my-queue" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets +# [[r2_buckets]] +# binding = "MY_BUCKET" +# bucket_name = "my-bucket" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes +# [[vectorize]] +# binding = "MY_INDEX" +# index_name = "my-index" diff --git a/web/workers/sonr-client/.gitignore b/web/workers/sonr-client/.gitignore new file mode 100644 index 000000000..90cfa7c2d --- /dev/null +++ b/web/workers/sonr-client/.gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +.env +dist +out diff --git a/web/workers/sonr-client/README.md b/web/workers/sonr-client/README.md new file mode 100644 index 000000000..40b5fb2c4 --- /dev/null +++ b/web/workers/sonr-client/README.md @@ -0,0 +1,10 @@ +# `sonr-client` + +This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. + +It uses `sonr-es` to provide a simple interface to interact with the Sonr network. + +## Usage + +### Deploying to Cloudflare + diff --git a/web/workers/sonr-client/bun.lockb b/web/workers/sonr-client/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..eab8f6254d966e5eefcf09ad26d818e7ffc1ad4b GIT binary patch literal 106594 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�KrrB{ZA{#ho{e%P7|okertTZO3=CY+4wg%mMJ5d9kb~5j1Cb6 zh`sSDBJkRM`2-4?eTpa#_@$N(GCI;X6DPrp#`K#$caHHM>wQ;U59xAcRgX^7s`lr}b zPWFGhb4K}+MtSP&+#>n0sKZr{WIxpK$b7q`=!(}k{mcoaOOMu7?|8TWV@_IyDQ$L_ zLC=(J!+S9#j)FU)xej@l4DCpGk^ z)J5qspmnPPtK_u}pD=_4=~Dj+nSM*+Rp-(l)|p-snzpOZ8&tWTcI4Xzt5` zul27-tUH{w*FSu}CF@39@nZJ_lrH>D0b*DO@5x-DyzkQ2%FkXV|41>Gd6T1hNTNqX zBhPJZK$ODp4RP0)?9;pFi9$LeZ2~PRovf*u*o)3T`q3ZPG&n=Sh|-1MS0RRVyvyUQ zD9U@hwx!>FJ)lA8q+?xs9p%Atzj3_X5B&(SMkhy_?*wJ(KGk*m(xAjJJQ#1_|D*Z$ zJ@5A<*Epj!f1z}l5mA6x_q>YX*`uvF4X>blAZltz*{DnszQaV;9r(Q(Vp#WCLEnb#G1jD_3-)<# z=gduQkKZP#r^lDklB05dW6Z`tMZPAZO1~U~KTBDDSLefAEB06T9V&uf2~MN>Vbm)q zT~~lVLwGm!|2K*mKa?C_7y1Sjaq^y3jf%Uu7t}5ZL?bjWz zQbi@X_p0d-49BFsb$yd}q+#9_rOSraEnWB}EJ$;|{-@Oelj9sabA%6kDygF{GEdq^ z5fj&UFHIP`>%l#D=Lmc=!7<}=Mug5!-n6LTS&zE!Gr3Z_6mlJ<%Z}EK?aL<3V4F>G z)iXJ@7R>N8JZ{}}oN;G#?NG@BXX_ftfX6rMDR!wGki@u1M7|(goeh;%6%pmH+G8zd zmG3NBh0^6f>v|Az%W2eyy;kuG;q7;L@YY4%ac}?o!Wc1UN)iM4=x^0U8X3f9Hap+W zsZ?=S*_=5g^`_jg|Hph@dHmwM$J%q0?tZlH^(n3vO;V#PYK^nTOfQo|T%Ph>J6VL0 z;=grj()M?v(zA)0$R}h*ez-cNF(b(fSVi`a^UEqJM^YX{2Cm@EfZ$t=8S^p_?U_+&rLRZBnjj{TiV zVQ4Q2HmgzCsuH0LmE4beY4VMaW;>$tz=hUr@b+geZf_kwgBf8pQJqSy>`tQ( zZ$1*Yzc1=2@vtP_(KdA~rCF(Qvm}FwO4KA5euqVE=*y91NB-v9F|^0gL)}KI~k0fqgm|&me{1Xlz=hr5eSoMxg1sC_d+~w+0@W!Gcigh|x?uzq} zC#TM_F#X?bY#OL|dCO?a9(Ok} zRyhXe3vPbR@pTsuypUDt(ppp(n~Z;p(mjNT0>l;t7{?bKrt>H(?5j*!-%-m|?e^eg z{{kUpSIz^^y>IZwclzG@tTrj|>4RN3SL|VjNdrcm;!Bhv6TQP%b(&4l`4vR#R#vo@ zs0{z~3i_Ur=N6w?rE|;tt|QO)c+PhjGTt=z368xr)*Geg%ud6r2+bL!-l=|l*D+ID ziR+BIyt=g|^5}iZVYIHr*ESosD!q65s!ey@m~+oPGBo=x{pB6ae#%AX^YiJ|0s|98 zk?)Hp-L>Sdn?y8@B%BFL-!ZE9QQ*$aOs~&p9;5Oggx1x%f40aWPnn!|y7NWBaoyD8 zvxBtQgvBb!ui6p07MyrK^5yj*qK>p(pII6G-V{-E7!5|!&xt5*-xD6(`B`b#pqWQP#e4K!<~!c02M(9nFIkjWmXT{W z-nz~DUMMwLDel*PAFLco7x{e&l*f`+m&>^EF{qu@xFQ{)7%MvHN9{Nmn)PIiW99qG zr*zBqb4-+bCmkjB9D4QXse{wq!MMm@=NW@j$cXzD_L=gapN~b+@t$kjKh$ugJKy!a zN`XbyQQ}D_*^KY+6ZXjIKa_4@H@K|YsQ78fd1>sTs46|WdtSN7Ht$-q+7DGnSt~2E6;EcEJkdoSh=C_g&`Mg^CyX z{m`F02;Q#mjGLO=RUD|Ved6d;d25AS`m2FUpUE3SR?(P#Q2Ol0_`qsG+D4XPVJ1HpP zETb%K@7Y^a3d!Xf4rW7G|p-;G71RlywUr%`VyNzqP*#-XQ0T~aHh$uj8^WGut zcA~-K1brPAUze{$kR8uFI4>C~ng6o$ z_R&>9E3%K~^!$&s>Vf~oZps0jr02@l+m+P5zF5NJxO4ag zmr%mO&icwE#z4ZfntM;`2)%xzbY;=Ht_%F)V~1$_Rh&Ws`pth5tWxjrvHIK`mC)W) z9i~@kRCqQmT{ccD_LXYvpn>~Xx%pD!=C~^9Z`-A z2=N+g>6HJpH<(nK&2A5emQHAe&2jejHM$B4vBzri$^E~j+rRi7pqyM(5D@bHmQ}o8 zjs5dal&(Blw|oz;O?&Pcug6g~@iC(r5Q+cXSULmbW}t2Q1S5Y0I!ChZNaC;(!;vjd{S@8O(ZUc{Ic%+g3>*K)^*meTXKw0 zjkP^A{FF9=O3vQ!6Z!o*Zqw)Qw1qd>ftTTF_dJ?V6lE7mnCuQkUXy&CYo_XeXlQ3_GRM5wg<<%c19rY{GUrRL;@#afa zu%e1oDN`Zx3oMK?b??Pq_Dc^b%uXqy-y?9!mE#TK7@R#d|VmsUBLqQ>6ds^?@bp_PJ{_{wspF`|dbBFXhhqfKQnENjKN|!*JMt>kQ*w9US z?E*2mH~q1?a)OVikCB}W^k350c_*LpQuLYf?{{zlgTKt;|u|AJHtB z^6l|$yQMp_YuBDmMzP7Wk36oBOi-nM)Unh?;GGy7Kt{NL(p5!70b(7l9pzYmyI9uh z#@gwua2-pwKc(}Md)utLy7a-`)sc5QGn~u#%lFG@Dr%n;B<2^ikyTP}y0vV$bI#qT zh4KRY4I8qqtD$vi&VG3kOCOvROzWmTLZXy~4R$m8p-V1Kx0FN6O!!p?i^sNjuv70~ z`2po8Ki$6Sx^`ev=eoOgA4(1vE^o6NMd_YF>-vpFeb&5QTG)!A5AZzFUp{(IrD^OkD1AECq(d3dWK<BVM|3*ddlfFmuF*aY3GnQ2mXE{NBx#B_k~Qzw+QV_R{`)cZ zgZNAmzXZv``B3qKf2ZMJhF!7mPd;!;gymkdp5i`dt>n5K33{dC@B}mcyK-PWr^FIf z5Z5sH_G=v($&3=X{HW;Gg`Woc`b1trzOE-}YH3iq=l-P%t{Vfb*!R)t{-ue}l}Dow z9BuUc*urT<8#hfqhOw#P#jaDdM3uK+bS6;_8E?9D<5G*N%L5D-+rB-_-kLQeTwmQ# zy64flpG>}$DzZ6e=HSe@K*@x2AKMGspmgEyn-Rm-o!viiPE!4X z5GS$O!#;@{y8MGCKYZ$a`K0~X1g?x$U9`EVz9b*LtWx*=ca>uBai?K%fiQ2IAjbVs z7Tp%o-6&m6L=+%az0KglQsf7&qqnPmxG5AcM+(arDp0>~UK6$KEAsnF+dy=<*DO{) zw*T?!+e*?@Ki3r#YLly?x3tnT@zEJX$?iwGO zAP-ZnSJWhG7Etj~>gBd!B)RA*hpEAyJ8a;!PfF0?dAoJMgBO(KdNT?rUF7%NP#){8 z{Vq`E<6a->>78v^O2{z$EF(hu_-e z7azrv=5WSMEZy6S9uGR`c(u4KysF-XUvMW@NLfw0yv9!y%~N^3>Zk;s>R4n59=Y}l zA^(2;s;a=HwH>qNX(3DgN~cX~J_-ykThM zg@CA7twxG-<5}$O>lR`6LbD%S7;_qb6?R5WUjB)TxjJ*s>JE023lmW+ySY603{bik z(YiZ4_Bj-NeOfMaR;`NJ#WVT(l*f;~9QbEr`ZN_4OQh`Y_41a#vu71|4<~u6N4Cp6 zYf9X#bU+V6kN zQ^TFYB<{}A>}Q^5H{No14mS*qe=D#L`}s5d`+Uj+@rhKFt{z%9BuAk$xxQWg*xu^* z9IPVG-kZGN5qYCEHDQNX%%bHK!%Z@Err12{Wrw~|?@I9hwtj%^TU3goDip2p`Zb}n zjDEh*N9$VE|1OvikX$*UPB}s*o^<|PXY%y%IO)oi%X7TH!jDqaJ$uEX)9{<-5VeO2MT7kOQB8-u@S&wm`tuClem zA9Ch;IA<5Tx==jAp{_7Wb9Vf?@y#GVmCsxq_&H^MAg)FKWCcZiJcPbu%6uI=AB^u&Ay<6>_U@}x&D#m1$A zN717JrE7%NjrFy8D`sUpU|u|AO)BxlV9D(+lPN>f!YUyTpL&g#SE+tCr=zNos-dQl z%E!BTf&)L3^78~pV%Ch`zCEI7PK?quM(fVarP455dhE9{{9d=HsYUUMeJkzV-GcRI z_?bx}1Sw8Tla)n!uYHRe6075-I~jj^D>A%9>6)N*v&7SmD5b9P zb5tDW&x|=k}PeyKmc5g% z(c4s`Fp1JNMeAbk9Z}Oef6-+wvGKqNZ?#DY`${p-Bky858k*}$QTN>kf-3OWxYtUk zE3bdRe=MYH;N#xNUk&aRHbDdVf*&$J@DS{u-HKbQ69Wx)zQh)H#mE`TNdz+>YzL^jlfl zrdXn(XxB^bCX}uPT35i8;=_GER!qwYo_pkSC-hiXRZemW{P}k?#uhJmOto z)3floEZQAz8AeBlM^k@c(WC}% zwxjgxNjf{R@N8Ns<8|(tN3kh>v|Z2c$bWbn z;gFP0aEZ+LS-`4||6L0Dr)mC4E_T(FpXC%Sn^rr^`xd zi!sdP|8QgP*Dk1LwE6iy?8JxTAsPHa6%=~Utq-@<_C5^$Eq$0!o`J6HR0u(#7#5{# zi`G4$I^*fu6JsQ%!4~rL({T#lW|B+T0;c4JHG+q`u2*`>XvZ;M7_#ig{Cs{uVkJ>Q z&-JPupTHqJlUP>GJ5*HY_v?0O-6y*S0_UEdPLO|nm0dvh^IG}HB#AG1a_1>!ri|`R z&&5RNq4y2a-25%Eu2JoE$tyI{!6b96$5xzN&bs(^I-%Dcd$g|cqdPusVFye184K`h z9~I-`AGTv$y6Y`Sw(p}y=(r4%h|{z07GyHIj+Iy6%@E(Z8@YD2F-wvsYmv8FDww(w z{hrnVt@|Z@?W$Db1RGy}H)GJZ!*=%sXHFjpoUU~Zv$Ke7X&jvjtv)S1I{MSsyPCaH zKVjyDZN#QP5657jmw`^$QK-k4& z{uTZd5tBRcb3UD-k(o&=Ijy*_G|_W96Q%2d)(uq|Wy?(|QTO*&s6T6vFx~^#5tFj3L z>=w7Jei+}iZpq<0R~>Nh+C|E?VC?vegp%APr=gCaK8z(VrnF^;r1-P2skcl=9kE)~ z*7C`s*@uR*RKbt$fHVR8&6OKkw}NjZBxO#=cbdR$Kxy`_1YL;aO{ zN&I)`8s}D$#_`S$xmb|44NTwJDfTY5LwCSJguroF^30!j!7t?ix}$XqFD!fUH`pnX z6TTU>^yYEBC%TgR2kzZO`!CX+xu=mX<6Id<1Vl z52q@G?-TkwKk8LmTJ-BD)$U$z-p|J$mlQ7LpmaUax-T^7Ufx|H*+DtfudN%Od|WG~ zVEmU`eNe#Bg-qhCfD0)T5BP`WugB(>o~_n%VsS~AJnwv3j>sY0~NCGgwc*-PYd#&d>q9oxzl7w*RAnd^%_%Swp5b+!by+RFUOw7KfU;BoWJ}< zqlt*N$aHjH{JEW#t!1kHC|z%~?#{0!2D_A68EbSoTO1Z!_SD=wmGyO1Nd1rp@lSEH z6sHwgm4XO)g?y*HLp}S7XiJg<@qJmZ4U7~Q<7eG zj{mNGN_{@cQ@i90!%fk;?$2lH=xVFq<`#1DzIww-7whHYGH;}Q!tbM@OX0<5&U*5! zpLcclTcUJ*(YhYbNw0qqx`Z{QlB!cK{36c?wl5E^oVeI!XTNo zkp8=enuxB`ZGh^5&#or6S2cRU8Ot=+{^$~50)eIwmmxfGg_kz^b1x#rtgWwg~(WgixpZPpGcDYJXA zkC^pk=O-doYIbh`RJiFv(hJ#Mdc$>EATE?zL>{^SCY#)ffvsNjPq z(ym-`v5Ix7S10EOuOBV2)m6Cph{dq^G{sK;Pu&#+`eCiZ;rzDyQop_tWf|^Sla`Ua zS@z?e==t-wc%klPL=+%)smAQl@XzwB^nu5HUrPh>qEcl_=?X81O$xJ%kv6f<4)03W zbmq40UBfaFKN9H1)yWPw~4gctFd~X_r*8ODnwt{zz+DNo*ed5`D zTGwF#cQ?CBB@d03xjx-_6a3)z9>t}OBF}iQS(Oa_Gm$@79SB94@|~NB-EIeV-+C;I z(!GM#&9R&heNvnsK{QD9wXd5|LOuGcH~-DdVX`H!GmjEYSsog7p8fTjdsXx0!tGsc zdb`*eIvi2Xx+(Aw&V3jbf0IHx!w8BAA0@}Q=!tytAQ7kCEKkFf+weE9n{=j zD^ygu37%yR`W$py?xdKM`|n#)G{)i0in|3j*0T-WFto1eBMPH05;@0HJ3nN(KdzT} zv`}^Ln2y$sy;1KKmyg{YI(&}jme|EXg)^P6JNBuG-kY;OK5K z9IZ?E*?%_5>&|Q!=jh|iXclj#N#>9EjJqk+r>_obvWBFv zy>c&+=&BBW`tUy27-3@cb3g=I7c7-NnT7rezOxVsa7h99%kE8Ri zR)2Ie&6!r;^BS@xdTn9XlJetQkuZn2!Z*HH+hwamI@zf45Q)|e934U(YoBN`qWC_c3<@;8@qg6#DgcYG_%uPFQ?*Inua5D-er8IcX{t9CvTqN>(?s# z{q(Vd?O^|8{=RcxOv7Di8zsIgqI9Fsx=F-RgDd2=cwgnKTn|SR+!-7YnTW4k=j%Q1 z_pA(KgGmg^Po60oy=sRszPF=TD}aTG`1OSFB){8B&X71oh8HN^XtXY`>swwkHYtiX z4<*3w5Khb3o7V9?Ud`yrojV#qpZJdb3vc@I{zqtBa%$AN@W0HMA~ob&W{`Q}fi-c`A3x*B5><+e%b%e14U0 zmSlRUHt~#&w_#4L(O|-rpJP4$Z!A9nbC}To%y<{t=8)G^O%M{Q!X|d7df$gg7;l6 z+q~!#j1B*a%5NN6mo8}c&}<~joEuGM!kBT&wMGrE9|1Co^<)BKWmLn3$y!>&hJjp% z`NfZXFXvm;G~l%M4`QI`yXU_=ZmJ+Ry%VK-9j)sn{KRFApH$IKytC(UTApKbl~3_y z`y5%z{@Ra@qS0pre^)Z4u(|Fr;XEp7KBJMdlliEmbvKi0?$kp%iXGiSDBXCp?kS4h zhN|9XUW&E3wI?3sO!&RNLAM-K!F=V$=Zq1Ni!N4w=?hUlAmLVBg-?=nuE3I$D#+U@b&^-~C>-c%g`UPrRs4XLFG=8Vb z?BSIli@I{*Ao0`jCwk_V8tyHwSBx_l_jDyuqkm_ffYzPxo~ABOZR$QiTUWYgNGPX5 zTr0iXUhiNxbNlfTp>NMq>`%WI|9C;~&A{H$#^+HO|GKZ$nM12H!EbzYV*_uXuiH(u zZYa}DWBMBZLsAZNOT1)qdw19P3ePbKczno?Y51fsACM4W6-3h>vNQbK)z68Jd+Ip) zUGfvh1kaisefy?Eu&NN1heWh4O)j1M9QQ!_t`5^Lg6GUD-hiKz#PiPc1{G1J$#pC? zm-MMNWYt{`qg0`h)lXMx?<7sj!CV=!Hqlh`O~b>&eM`}O@-Cu78}kdMUJz6 z8?e4Qat5w-&M#?x}$?E5Y^s#itrBp>)&Hx+|~RUcHz%Pk3iLs;4n2eDJuAv}V@LZ{@;yj$W?AS9s2( z9}*cVH^ToiwKM8yg`esv!lTNj!pnGxe6MPn6-}H_x*2F)zQ)$vqt?u>ac>JqJ6;g2 z>8;Rz*2rSm6s?Y)~Veiohse@IY6{Drmib4 zxqipbdfiH5z23!zgFZ|s-7K_j-YBt7?k_nFTYE+WlBdS2CT9*`t5h?^-c!yu(H$hG z9PQ8FL8yTV_1XVheSAWuU8>*K{5g#rDG8(11uloDPi z>PNOC$nRR?`ctjEJS%FY$h(u#Brk6%X|-7f`Wf&Wi}H9Sf8NdDTuP*u6->F#|KS-b z-W;@Uj>M6hbA%zwQ#YT6#&+;nGwfWFxo5*|*m-L4V9N=W+@f498M#+NyCX_4Z3W%r zo{?ljRfe2p-OA+G1nZ@*7@>4?(Yg<>uicH1ycuHQ|DC1R$bT;H<#Ej$6W@(yZM(kw z_Il3x`~PY0J>Z&XqQ2394Y49BiVZ8a&_Pg|1?>OCOU>|OYy zn+5N$9)Gc0R*S&~LyI4^>ifw=o=~RrV9N~$UfwL>zVyoSZ5@PumME0F>EWOPn=giM zv2UWk#rZ+m3vX`iwVPeOk4f)owXSZMllpVX1}D9q?~UsuFWNuAzuxttx0ft!XxQb| z@z_aGI~~10rU>*+63R79EmL^cGxI%9D;6=fj4u0SY{C~4ixAG26qF_y4N4D)wxXlQ$pOf3zI(A-#6s&MWVB zr(P4tT`QEUG;?}pHmR~fbkUplYmM18a9rz?_qR(@i%nGYy)(0phu50rdkRe&F+aWC ztCfM%ouAyTTB?i1t42rngnD~L+t(_ByG9mx=6};yAa}h` z?)Si3PNl#1E7s)6%pT?af+nBkGP&-(;cOz2hUtJA#9O9bi@z|x zZ}-Cen{55QwZZkQ`*D3|m0fc!_S9w5CH6ml*52eTtk*XQ<#s;bSLAAAv~0tq&s%%n z-+REq{9x-#)qc6v2!2;Otkk`IDTAY%|1|tL`n++`_Jd1oi}x-ux9;Vs@0u7zd%tda z%kGCj-_1g~Ll(3cB-2}DytL&Qx5VIjTRcv@9$heFr}x|GvsWaTZh9_n-D&rL!Y8Ae zWds0X~X`{0i2_N=VcC`C? z;nV1Z$1hWtd|lEpZiU;O{+ZuCMLt{fqL63tCZQhBV#a@nx;1w3hZfxy)G!v-lUs#y z-;P{1_u$xZ=iOGdpKZOi+91Ct8@HZpVerO%Q`0^5{LIgP{oe0gw@oRvUcYI($7e#E zrAtGjn=>X|963B?Qpfb2CiMmSZWGGA?7Gsu`}d}%uU=+OzBTQ&$Kj8+Q^dFd@9LF1Hap7Pv-xzf)rIvhhxxU6`TBuLoIvh&q1-pEkNUKU zZ+h*)t^wUvHavB_hE;L1wk3LgUS9h{=~aa`ynfl(=2z9#*Dtyz{yNfk{z{vBzoOUZ z4QevLxy`;UAyrEV$8S4?a=p5b^$5Kkzi_&JwJyV^r8l4AZ`Cq7vXIpR^MWi*?ab=TUi~?b+6oSw0rISY4Py~#yxgCQCpzzPNCesn@hW2=^fH#Tfdp( zmQ?RJA#m>IY3T=7n_1po93a|#uf&H5ehWqS`rkaiA!e@Y;GxOVtd18$mxd%&yw=oX zS9o7zf!tj}xmM*u+z*eaR-y3XgdRnk)p+Z><-zL@1MG zM<`buKBU>v@kc97@_Dy#qSL*v?R{oVsCT=>%&3*hF2-XX4!c^tk+XTjnS*ZW%}cGn z_Gg8~v6goR%$OzLxYcof;+1x(0=X$dx&2Di6utFp@O`KFXeY(TmQ9bGNOFz8I;{WR znWBdmOSO8q@OIj)VE;S8COZC1+z-DX*?z8dlF z=1;pO2}o5ev7r0YA?tzS7c&HPf5-wsJ)q2yD+7Uy4o@%E1# zIsH+3e@EBxN4}po;P%55WZzxeFO<8oawX-aSFwF&MFse__Ub(G{^vHM3O%rMGx=Dj zeVrdwl&R;Yi|Pz~H|@vP6`iZuZ>l?Rz2n<>+5WWZ2XD1sI=Lp-FTpG#ls+JoTi3XJ zs%PM`s#!A~>*qy)jJ;PizTy-MOlhsq3YlCarn|drmpI!0gVZQ%921O~S8- zmhoB@|3!Ab=-5Xak1#tFWZ!=~D3trYUBRX1N3)FD*shAd*mp#gjLyS6AI^y@e|%Z% zY29Y_HcJ|Fr=8N>s6uncm#qq|FG^u`fnQJ9=*GJZNYANA+g^Y}si})Qy0h z_8mO#ZeI9()V6w8Ou7D!$iNIT4-4fgVs?jY>A9g!gn{>>J99@a_%g0hbR&<`kE*#< zm8_E5uPe9qaL+F@l19&VvRbpiaq5H_y_!YZPN;X`#p?~T4c_cH&+H)5r*)AdLb=s9 z2bD{0*E3~;(dMjIM;U^^}OBOrsCHfe7=#s$Aoefx4Mi9 zA9L_l#QO0?@feW*o)F62-Qt3BlBb>B zcZpep#2+_y_}^>NHoo-6;YRj5KFaKOlrLMW^5^QkUdOeHKj68ydgi-*F>N;Z?77!A z^xCen^P1c~%FS)C6%o=s`|bq*FuJjco1ZJ+pLEy^6ig% zeNWeaRX)(L&(e=A#$BJ@slwjI!$+2M9{jZIg_XU{r@vuxxpk*gLb)*p1?sIixz%1= z^jf#AEt-C-^7X*AK991Dd$z8h`Kj;xKG7*}GfOPE(C_8Ko?XihaXA-v?#=NZQCqxX zzmMwN#@uiwlgoXwI87+GnBKtq1FsaVW;|friP+hPg3EnKUhKOfu~hZu=Vd{*!JQog zA7A;rVy^Gu#&xf4a5>SWnM2i*zOlt!$|owW7tFlF`I!Opv(rMkhesNXZn(W$N{J(3 z9ar5OS-JJ{ki;%ss&4O={zLS+p-0N>xD6$pTc14__xXeAy9L8z=Dmn|J9$-L*}`iJ zhfTfNnA;~NGC<8EN*BsCo9S3aamDyeA=g4*{l}*FNLXpN*P%~y-VSk)c}6IAmVrXyli2n7^Z_?I zZC}^1W#^2hKa&R3Gcs*4ddcxoq7@I{_1WF(x#7>3LH%C!KKt2enxe>%6`yK;S+(SX z{D#SAZeP5}z#TF(gmP1Bb$MO$bNcXw^(5YIKW?>Mxi);jP{#?qJvTlI4zq42d0ewn zJCx4ZCYKtX zReJ}WD5 z$ieP|A8bE6XGSe?WCfF`sNwelqn{1mC8==!_Ijo-w~ljOC^yr6UEL2SpB>tjrJwfG zt7CfCAIdU)m%ZQS5dJT_1{$69k)xmSd9xdZ+dAPeM{_Db2U-xI$ z4VDVzUJ%M%ebvRKxb4=M1_|RHj8F`@xAVoLPqr7&&YxYYcp-PY1Brzb=j~ou!o5l4 znT~C}-#)!p(S6_ewOxu?mp>eMq-?j6zXWnG3gwn=Gt8ml#hHbj2bzDASE!r%_Vm(I zB{oVzW-ZF}ij?h~{?p^8{{77}OfwBW4wbdOd8tBr;oe(2RPkOur1J&4nb*YvxtD}; z+pL){I)Axs>%@WA7qJ-tBeSO*CQe&%%LpRphT=7d0<6Xl2QCEa=Kipio+&;Q< z-KaT+PHm?2+gU2%?7X7=hZ!22cOGS+yqe&CWl@2%Cu4S4pE{V8(7w)|p+&kCy6kQD z+$Czs$E14B!hYXXptrKygZ59F47ls&(P;dWv|&Mm`gWRnyMB>`FQs1noK|CW$#%t0%-vf1#mPIu@^(`w zw{PWPdQm-QT)nt9a?J?G_=jKn)*VxR;F(Y3na+9Urqg+Stx``p!3dDwQ48(&5gwzXd!@HNuy-r29d zPoJJ#>-iT7z%2hq(V-s1SP-1bbkGIyISod<*M~6uZ$L@`@I+V1-HzCHo%;%^!i<~`+3H|rJ zP;R;65jWcHxSBcHYxRhecRiEB=Vgqo{duBHX)-$EP2e4aV^5U_cQ4j+DA3EpyY)kB z|M_V}?@oGQ(Rz$$txAh0>KO^_@IWXx@tDo8G^7h->RVzvQUdriU(@ zo?l<_kl(jjo|}$y`+_*RkA!l=($5v{+~VE#LdRlOIoBC&xS`;ymGzB^oeCcPz0aFc z6>98TzthG-qIcS&aMNm!$49oe{Z{T-kpUk>PUj5*5(X3#&eJ{?%B_B){qV&0ndhEZ zbvFOCHU7=^`ByGCUYC_pIN;m9!PCq9GHSi4oBVu+xl!c=!C<21*=KE~uZ9LEO>ySYG&!ZmC)GPnVrm=zE z#h4MPkFH*Jo4s~V;`M!_#I^=w?*58+I%C3af!wD;xg&pG^H^S{OXPiLgA!YIjqqGH z$9>=0U46sujVjgW$KkiiVw>B4T2Ojq@TW6RR(n`9xw^8>& z`xf1vTr}%qpYV0ew7t!~PUv;Lp76ZWbD`Wh9v>^ueskh@y^W>5N<8~sKXW*FT8+w8 zw*TxOe|hu84P63fv_1HA&!lvha>Km$zhB*6mJ&YGyMp7GnXf`$I}JNAQK0V&q1@f~ zs;(ZgVs+w@>r;AHAOE_F*T}Oa9jvYdnKfFQHcb(++oIU4aQ}yemIS95-D_<+qDXB6 z^V?6oJ-^QEw|u~`h?m0iWG{ts>xEtoxDs^6b>W$>N36?R9xF1liq{u+qqdJnpW62G z@rktY?>mn6Ija{Cap3gc_^@uK#`<0bpA>9V-S<}2CmpQbr3v(XC6pU=F=LkK+lz`* z?{q$Fb~&=k=JO^eqhC6E`T9O8xHxFcw2iBWHZ{5RsAqNO0iglj8TH3|wpLymHQ1+W zv4|a&wfLT(Ph&{oVH0O6s3hDr!!Xqwm{oS(H3` zy3;e`sMEXdRJwJk+=2kdTaNFJ+3%{?q)w4YXJI?^Mksgb^pMXZ&dM`qM?9G2zVFSF z`D+({ow(_)+aiM)`LZGxMDa^ExXt@Kw@YH914}QxSJrBLFQdhf&V859`g~q*klp?p z0)5{K<(Ao-sC@g~bE}D;QL{4j_Oz=vX=eNR@7^7{RzCCMGQE+8f#*K#ncHIfl87~j zd}`dOz5k2v_<@VtB$u>08|8dHZtVzx+;>8`PkJeLZ%gwFK6!0pdRMdBQLTK>BnKYT zdly*S<>ctsp(&Qjx{s~1@x|kEC!T-2;o+j zw3*wwz~NKRC+zv)oLjJ`XOZcclNWgG(ng$?Dml zQ2NxT0bO4dInrd`;#V@0QeA2^n>X0+=AmH~JA0=4U2sY+Gte{EI)v$4kc|sJ3gynf zSjg4O^~xBVL$Qyql(DV(DrvT_vn2K7xvIx+S6esJC1yZi+eOk=(+0SM>UEqq*gF_dXtD9DUU4gxFPv$}7+Bc4ap zp4!Ly+u^xqKiw9{{U(%~TE4^GYs#Tdy*Ctm9Gq;rW&+K)2?#BrIht92L^dIn0utug6Ufayo~O+!ZCK+CV|}VLb;tDHuW}74K4AtgvGu^ z6>D$ZXdPI(M=|ql1~(rkSF-iDyW!F6WW8dOx7IjS$Sy6j*T)sT?_GVjVSjA!LGR3D z*Un`Ga(@Wr)}OcH)2_I$%?G@6dO9ZQ`0F=Y6&KxB=zH34_8Z!Aa12-$5Yvr%-PHgk9gvvZ}@}Deaz>VtDq#Ca-3D zYn8Tc*M04p!kMlftDCMgZE5)M?TWpXCa?WA-19@qo3nKe4cU^mZspH%&)sdm3*=@A z<=VLoEMar=>D5hBAKrd=+=s|0dsB0}|7Fl=pX zv2k;ICR=tJ<1aA}t84VtGk(+zSS2_t6&z~p~&r5oidgrRNGLq zLeB>8?!7sdv7lAr+68^a^{};D*jn#(*_!n%*1CKSllup*5$LNglzXbxZf`~M@O@!( z7h6ZCY@u#hv>xj_XR=OzYQSyos~b!H6nEfpmFV;dAnLrB~KyWHW!} zntRP+kA^I4)3ssWf$L`YNM3zdZq;>_L*%x3bxh-$+BMpI*uJW7t+Im;+^Xx7wOzPQ zMtky9e+4_Y*|wta+5YACcNtuG$MJ53TZA9pGNt)EgTjd|uUE93G4z_t#DhooUmvv0 z*)qj{QXjvA(?V`}91O8BbDer5V^VJifxd->aubdxcIp^k>fLOQqP^uk2i-g>8{Eb6 z*k#{&o_im!+jno=iaCA-O9k)jdt~0!L2Y-fd!E@yzk_Xin^^@qJ^Oz3aGlcvxkZF> zPuSXiDm7a+zkZ?k{VN*lnHL^0+Tq%Y@DdWe^p+)>-)h>i$f+VlCeFw@TeA4;`4-l5 z=6jx6G~TP{>ji=1;*M=EUs)j6KqzV#tS#?h3t(hEMyv zeq&?PD=YQl0r3TazJ@}%4Q-SzoeGxz5SupD_H(G6(Jh;P`|F7+kLf-2!NW0Cd<=Wu z_!+Oo;0?3!@?U5mA<-Dyij&~{kL5!O0D#{H*sE_M`@==w(V@*Y-|Vb zOIMEw=Z$Ertokc>zD(DTW>fe1+M1d4D!-ybKmR=uNke*_`+#-hw7Xl{o;r40@#T$4 z?F}1S&P(dnt?4@#-h0?0)6S5IjX;cF9)X|iG9}prspFct7EM~ z<~O$famdL2@Y0g0-8ZF0tTg;|OY-!|sdKY#A1zc}X1E}0S(j}l`y9u&GI}pNY5jIb zD}mgSLb=hkWUCvMs=lt1*@5j{R+-2BGAVcZhjpPbO>cx-TXlSKIc~wn!?EuNhkTrU zr^=Qm<}Es%7}@5)@e+mmj2<)MtzKQ>dTc47+;hP{n--Y%v6J)kZe3Rf6|D5Em*T+O znTzV%g{&+7wz28{gmESJimTK&GH!gi-0r$HR~GAkV14yLL#wYiFm%iQPbba^WT|YB zf8{KIuB#|i79yu7A6baSKqVKR|8Kqp@-6T`Zvk41qd(P^d;0xfDwp9QVc{XTek&^y zmB@K??01I$3qnX|iLYEiI=?E45LEvUzSD=_ZAOU;*%Z-IOZ{BO1Z_3>2DmQJc)q)MM~S&*OTaTBhd(e{2mE#Ct9 z7Wgv@P}%C+nClnUYQuh0IquIm|M$E_Hi(of21ylu_(AXd`bCwqWS8J@WthY_Q2M3w z|F^zDx+tVdc~FE@G`#EoxjdqHLnI+`8C=7syGT^>e`uZ|f67(mW%<{93*=iM-vap- z$hSbg1@bMBZ-IOZ}KHD~6J3zm&;t$ZbLjwUBFc267(DzS+ z0s6kG90&yl0}4P1gaP3|1VF!K8U;iH^nKGIKr*lqpzm=m29^K`z*1ltumP9=OavwY zlYuF~G+;U~1DFZS0%imBdpl!+(SR@D2ebjqfa(C11@e9J_1ZukfP9>MntZqz(q0@O z-zC2xKOw)Myrz8LjCWQ5D}hzOa$o_l5SRmu1BL>P07t+HXbd<5E&%zkJ75Rc1LUjp zolyFwX93)kpBez$B%C|#7!RX_niAD9Fz28sdJ zKyAPfC=L__3Ias{1E3IpUzopAIPuZ@bgv38iTe_KSS?)1PstY50W*N?P!%9MR0b*m zRG!Hur2(=>d7unn#NU%0je&AN1%PZv@<=ZE-5g*xFcX*tOb5unROzz9J?T^zFbC=Y zq%+;qmHfK_AO;!&^#LkJ6sEco%>p1hklloKqA(l44zL9%E^6^7;!3{n29WQy0vZEO zKqG+s&>rBs2Y+=Tc_f4Q!+?PR#nT0F1v&z4fzANM+Y;~ungLA#7r-4LerKQwK>Wl@ zG`f25_swyo_gVnNPxMZJDh|@61K4`FCYPY04X2?l)zwM5D*Lm0U>}K2n7_tC_wejNZgMA z;(*~mEHDfh3Jd{afM_5Jhy)^laDZf!49epPz<6LRFa{V6j01>H@e?S#0Wb}i0!-zf z#kkJMbw7)LR)v!fE&%2O^MJX)B483g{=X6^23P~Nf#N_>zzQePcH`cm9$fi?U!w+)EC8Q2Jr90OnjK;g-NDy$st%LAK$ZNOGwhv1&Vs0&yUNWnd| z_3v>lj4QSM1%XF+&IIlOcY!;=ZQvGg1Go-c1NH!;0kY*)T+ag}^Biy%$NA-0q z4LAjy1Wo|Qfn&f?;0SOSI0PI74gmXseZXEI6}SLg0xkm=`THxlQk+!gZt~arxHbhI z01pA`*AUGE_zrvpD9x{dSHMf)1@Ihr3_Jmz0Z#$qc?-M&-T_~L&%h_(Bk%$E2IwOW zJ>UoKe*r&%EZ`nMja0V3;hx$)>RVACi^ecCX0gX>Z2>R91*lL7f%r?NjuZY2o%`50 z^b2>y0L&q~uWp@l02Zl`gaiah6`3sthAnWd{MJCv+t$Lt%EDHpl!qw9Ql+T>@Srv| zV@6lg*JncUj{{H!Rf5@F^DagSRqB=2v$n9YutI1n03IFZaA<$!8%4g2EUo8lZDDI+ z!_{G>L3w+y=W&JNZFf+>LQGQd6a(c-Y@eTG~+X z5GD4>wN{;uN0et28w(WhaiCNNrE{^#vg>tbUQ@@j5)@NV0**BAweeVq&878hEF3K; zE#xn#58~Dqtz4?UMb!-O*jZRNvaqq1Mo2@#l)4XkG_ElQPeRF6 zuhY{VPU&Y$^W`ZaecL{>eDHJ_c&w39*nq|pWx=y?_^tyBYiu=A^Gx6=t#>bImw2Xy zxtc;_3zW~ewcU2jtyIE#JueL@rO^&iDu3A0t6=<5A5h4mpqv1u0w~i0Zl?y_XX~qB?Q)ZpFGR7170_ZK-^p%+O6=+% zba!uIwFUv8kTmPS%9S2f^;yPKkaL=)T?9`>@O+$5qxsg6`^)h>u&8Dp%@obH)@(P; z(*8v^)wh%9m$NbH(z4|oeZ58&)-Wn+9aPtp3t34k>&C1v`ixI0{6Mn?0fku4DGond zP@>Q5#{0ozgQA687z_%Pl8mW|A13cOfZ z&h+~Z#>0yJK~TuAZC`cuFWh3#d{FE--7bMbKKkuNR>-Gy2Ty{6)Q|?xKq(JOe8Rmt zrS`}41oq@s#DZm%S2JeQm@`Lp=HhTy9stVd-t|UH!4XUaUP=#mYl`rLd9c#HMER=S4{j z84s+0-j_lW8X67jEV_2ad}zdXlwf)hf13S3v+qcdO!Bw8Ps_i!l9Wa{M>aq_L7evile{scOYtrDcpJc?t9gp@Q>}R`tfmNfcJh?XN7K*MjfvR6^FRg7^?~NP_XMO- zIUTsDeS9OE%s5_}leQ9k7d(}~W2A^}@cBW3DeClm2c-%q&mIj_6r6wk3@;5ytpGQy z3X0uq$McQx*l*Y-jPL^j0;c11OXW zx6dDqa!H(dRZSVdQ#__sZ7EZ3>Zqm+2E`aW>8=lc>@Jd8R!xZqg)I7G!k2TSJ2zLT zDVjC-7aq-8KZF6GM4WB9a?-W|?NZemXlS$GZ<^bB&27oQw86h?KxKi-&%4r`hx{zE z`Ack{`hwa;ip-(DGu++6EMAOJ;SydVKlK$aSDV7FA6P@{`3*^fEO0Fcg<8!9gO@kCmRxo-D98h9f6jwK9zWN6qP%9u)3eIz?Lr9k+wS5@ zZE#%wzEg{=I9r>fSy)pb?A-pw zG+;dxnOq_DlPN{cb00iB+sdpwD6l74N3$Pj&Nx)wmr*>Lg1 zfP(+y1`m)A>O8ms^;CI^W*?mb21==XQ~Q7=L$d0EhwoGP%0uuuK8fh2+pxu7M<3*R z0XD2GDCA0Iq*4?%Y16pxE=$Mg>&=4{vc8|xKb+huzPq{S;m4(^FXjLbu|sQyH%RNf z+nY{#|I5c!$)-5fgR@k>x_xw4=+e^kF(;P={KZ-YH8mV$@s1Eey1u!2+* zZG7L}-E??Is$GZztu^G2Jt!J;L4(#vk7gd#uM=GRJk@W{(g$y$fg=rbthCr590iW* zUca*Ii|uIFf~zT*$7{9$H1PM4M~O@i_0ODD*P3c&N~xp9{DBQLqz9C1s3u5*BU{Tw z6!7?o9|RX1A9x|Yc_V7+LW(!tJ07AE=@(rVnyWzSB7LTw{jnaQZMjgbpp z#UIZ7Tt8k43i%Ews^5I@nC_Pnt!z{f6zV#FqWa~Bs3$9CRm*yB%i>`ad5AQOelDX& z<8}Qf8|lpjg<1^od_f16yy~)-XX5jz_w3X>dKlDGO;Pvl?bk|^H#;&@xilF3(f;b(S60&$=)T6lxn0PjyhxDUM4scv`28*C|0t#XKdVhfS5q zL%lGEf)<1EIDtYn->NxFUKBDL(3DY_)}Ek{bwayk^nBbyF&q>=PbufbgQU^tmHV?U zb#^YwG+;cDfimg@h)xGj`MjdTJ5Nx^)_l#Ei-#ZOR6$pr>TCCMcjh(TZ$M*bK7SOT zkZy)gdsJ~-I_aBQ1DO(@fOwJ`_PE}q%(E+M9(bb6SL`3Mv0sat#pW)exd6VESz*TI zLi3_2%L@mUoem0GXR;f7Cm=}fBZ`doe`L`ioJtAtz}D-*L;3SO_{hSZk2|ID6x5bJ z3W+bK>_i93UM;-m@Z)NrkafWGj*q9?fET~MO_O{A1#KDGKvtcT=JNi)=2NBZ13{qy z9Vi9lY-@6`Pb;-p^W>rKXGpr6MS1N8S{;YVFZUO<4*Gjr8Uu&rXkcelA{3 zN#WxeS@M0-t<3X#)Rar0R0GeQ#$FCx-!_-4DIY+gG2n?>x080QJ{7B`l&Qtm?BXoD z-f}v3qghim#TFD~URjQ=>iJHGi3SVHc>sU33wEsP&}0?rH)!wH*A-h zXBsFpKE2<3%J`#a+Rs)~Hh@AY^=K%nv-H}v0cy(cUKLATg*yKCoQowNMQ;B-k^m2D z>lIRopPx(-TBF+BidAZKo`|^(%s7+p)T+0xCK>B+PFu(mNz3I-;5>BdSUw01{gsCM~%B(8ZrWNbrjys*sgm}E@d z&(u?;@&nzTf>IjN7CgMzxo|HT%~JCe&GBd+J8u(nx~2E>a*8^((Bl6sX-*bgJcGtv zJ>TreuLge-&%fxVd1j%AC0AE1DiAxfa-SVGOatasMxc5Oe!ba7s?$ta4_}3a>T%uW8o}S3cf`+;Z*0}+#%RuYGooi+-SeHcO zMlv=+HT$RrtszZwEv7*O#6$fGBWSQHY2-2g!(FJy#j+bK-2bEX+wZgCG~&0lu+L*Q z9K9#Bo9Ms7w`oS^+`t}J+Vx!=#Onr)>w-daLSL+Fc$_OKr;!A2H_g^@0}r*^!Sm)! zI9;vRA@J}uQg5D8{{9xx<%T0_s3{se5$|iBan?M4{Vz87pH1oiY!q z@0&&i*RFd7-Y-*c6j!?-vqb@*lm*3gSc&rY6+1EWLmeRmihk!|@qp?7NXvwHG^a-* zRf_4iV6Q%ZerDmV<}@zh`)@QAKtH>9XrW)^PjA1{%ttXps?B>fuOUxI?MJ=!_cv=E z^Z528hDl?i0?oR80S}ErFD`X^*7V+wzRa&tPX0}U-`CnyqfpIjdXY%2F*L}SKgcC; z!Z&VBkM+e`Az#T4R68KhA4O)9ZZt9^tyTLR7=_IVy+Qp;JRA1*e>uz}0lf|IupaSW zOM_m&^Y9AfF}qT{G27i2r}_nu{vE2-s&VKt`sB!M{0FW1-=!*D)1`T2k@uJjKr%5t zbjtpccv4b^KybN`aCjznpSza0!}+rCJ#+(|S-$LFu$> z+BZ|%&qv6jY=TyF3=|rlemP@Uf4(o5{X#yVVaZT92yY!8l_eYo2vp@)W;7(kru9~uJOShlHGP*$; zP_fa(hT=Jq*d%Uwvn;7a-g1oMcxx_))=Z-*M(CkLQHF zTjusDMNRSIDF+`;Pck-X`B_aFz*8LBo!+r*#XLp!Rt+Wgbr%S8#n`f1}1xYRWpEVqoOjV3*#k(`w2-P{=wbigcXo`6T#|nsT0} zRQUGIy7MUqshaYLryLT!YFX#0zPp<8ji=lgCi zQiG@Xl>bq*RJF37)D#DvGPB8xngb^<7^kMR;VCCR#Z?=+vfE5G#Tyjrhb*aNwdcZ9 z-`;A95|r|wbap-4pmG(XL^WkRPbp#2;^~s)h~sKX0#8}zDeI?jGhd{pZ09LK1D5}~ zJbgFjDO7bx8YtA?Ik&8Il_PbZc2HBswcu>f@w|N@?be#>!``g< zvcp-Y1lkRRbrdR%d9CGeWo{ODs1}=U*?V%G?JiFG*`@IcC}f?Ya_3{uIxR>+D}#E^ ziRx>#^YkYe<-j(W@)c>;I?t69Vi85l!`W^6LSueT&r? z-|af2k@uoKoeWAPP`(;T2W8o%(_SgIAIU2Fm$P%OO;NYTPwEpM0I5?(iR|u~o}#%< zEYea+fA1qP8z4Qwe4eh{cI49bD^pv6hi1&6K`Sq=CKolA%{R3lQMX`r>+A;#rSwc@ zlm4R=NAIgCBS4|~#Lceyou0HVuvAS+0EI@?yUv-m^Btk+ucqt+#S9deleMojPnhnj zro8INm8?Ct2F6z1Hh4DEjkPkqa_lldM``ATl@F}DyetF?-#Ds%r_Fz(tFLjnddbWN zEa!qcaUP$1toow#hyheeD5WT;5~Vmy;u9qGiMY4(O`TbjJyr!pl z6;AWoq2{%=FZ>SXs8)LLd!#ML=~AUMI6|th@Q4bNDncYdUBVQykN{URYxO2)$Lvkc zw4VgqNkkpZj|N{TnY^_Q8dj>+SFehRyK?OHtK9oda?^9~k4{1HCVu^Iu{%uDN*_Cg z=c0HX{;6nz(UDhzbJLUf6r7?1f-EJpAKO~fc5G2#SXijCv8AO#8UW1|(H0@0!2^{R zaz%h8zaiUFthy7^zDQe(uz(nMpKyQn`>~dx3VE0uPwpXdc)leK)}%`QK`HeOwXt^? zWbLl>4Od7leI!b$>Q)wNYa_UKa*xD0UTmI`hlEId!z_cO0TSP6F@9|x8=`a3lsM1J zQ-b7vh!DHRwIn0^9V8_CUW}@iHe6F;wD4+oZ(@zpxj~HBw(%=gX94LQbn%7K&eC#<|CElw%tI=)KFhBlm6!k&%uVI=Xe%V zCFht&;<2_aQ^-Stf6qb{e;6hF@6}*z0yWq(Q-gUY7G)zOLE+d9CRa!Tq+(eJ3a&p^ zDz(I7!sN6}uMCn(L(vKcA$V}OOd$;m zq&8WM>R2iXMg@x{cI@krC_>Qe$V0@^C|Q^|NGcg5_Q%%_SVXjMN{QX&_|`#;RH0-V z_;%n>0Q#_#VZ^_BZc6;$bp{V1<}G5e$?hMX@Vf}8<= z%cvb;+pWaLeNOx@PX zv)Geblv}y01K6MX|Jt?8t8#(Byn>mAy5#*tONJ{0bC|S}OZpkRW^{0Xj`AYy`kBeEg#%2-*{{3!YF5>CRwvy98$S1MAP~ zGG4AGlXWQ}g@E+ATW23TBN|B5;VVp$4FTyhIg#jK^f^I3y~`0hnhy{xdwOI(wI|x zE=H)ED+Ef@e^dv;so79e=I2A(e=$0BM?-=7FGLb1i;#*X%IFXb1h|(hb3AELNG*+W zDqFOe9mvwrY-Oti*6e%Im{#4Pa*!fi?2GzR8iJmym>p~4m35cI&}0q{e~MAm{AB^* z3M4`v!iW3HmBDf)|3GymHz%qJk@;aZKo%Cwzrc(U9u$Vri!TN~s<%`lcOPs>cE>nH zf&&|J1)6v%dZ|+M<&;?WMC)cYbf_7(6PVp$n%u(59Xrs2FvhSXW~F;*kOTo3>|l0^ z)M1lQ;h`vW%0M_6P7t|ca?e*9WH~58i>)yeNtW`L!$x$>NPDM%I|l{^?gl)%2mQYp z8tlJ?K@tv{>4=@3xBxf1vVOL%Ax(B}gDd-9%pG^5$WWnJ@-vqfm>$$(C;lyx!=0>y z#yI;$Lfk_o%+8T?;ty?p&PNPzmBEQ6k8kUMNe#9gq z#g747co-V&5Y9%Ju+-LG;3yDO!oRFf#`<)WCU$m6M~c`x#2gY99>UmlS(D8(gM(d> zetuR$i`A&j!r3qI@OS9E(dJ?8UdB!_5f7b+WSX%amzH?=^Ht#C?+_0iwa^}q+QMK| zKOkj%WuYZTIv)luy5RjrT$(}$1&CR#tc5ZA9dKvgLxk?ZCe=zf3=ppbI=n_xrSJgZJrz zR*Gsx?VhJP1I4uB67WYQkUJ#?F7AdBqjMm~){Vfzu8c#Mb~!Bz)|>&5@dwVzou~sd zf3^!zI{P6u+U1GU+IAPrV9~C)vSP)$7it3E!Bv9xODL3&++0WfE z2NWwqC6P#O02VsgOmnalEi3;9)&|82G=kKy1%?MpLd4vQN}6m875ihv7bFgmMh3x1 z+A{9q%fO*9V{Lg5w7xv;DNGlJiYcCufK{K`H`P zoTX8JAdC>?O8t_pC`vWF-nuRno<1{B&Z)yBB=+1YCBAhMM9Jtosx3C2x&P3SiPuf z2tvYxeRQ=x+&hp17vt_(HSq_nDjh23_~?%112YH&Nu$CjOiM5YhabjJ;AT?%xtIR=dUp+@MSd#_E4dlO%u+!hPC*H4Q71BQ4V$*C=x~R z?=-O3+T_K=5w!5gB-mJ!O9!;a;ZY)$>~KT4SvKggXR0hb_W1)=Jy=P#t@P*fl{NBBQU=5h}PU zvYBV(DV$OMn{;>{Wo};LdD4HDuTg)M*Z+qYsO03Szl!i5W#_GXc6t3L>0CuYwSmCu z>cIaXlNH6^gmUFSyMFwOl9OH6{U(zv@GlbiIybkX!r=cR7itMqRafwTBr|7g0XaDX z)J;9tEfusgI0UD~s)83GRPe+Gnz~v%)j=t+s&3JBp)Mdg9jx6(lR`81N-;XiSl44? zz!2I@L|cxy5uxU-q^h$)5U;w0vFON`_W7Tj5iny3WBj9@ZBCUTBWD2g;KxdQ!qCN# zVgQU8SuNK7?On+IEsP~mR}V>GT*weSp^K(_B8GMz(Z?;os=8I@n-=|5pUVKB>K1(b z9xE+;xi|f>uM_LYM8WDKw^olxxf``>3f{p$S`vVUowki?(L@6WWD5nb7+617@V-xU znD$+#>J?e`DrB;&TG*fI#qC`HH+RF>b&VGVYH~Xrz|P&MV;8(b`>p>>8F~}4=%SYN zhpgC=L9Do_S%pdjW1&!U;m`FZNdkjfk``9J8sm3~fHP;nAI;7Pcb!0j@R3!vtPa9h z3%fqVa-V^050@Byd4HKg8Ag**Sf&kE$nae{+Qi3gGRuYUL=UctT~FbkeoJ;aJ^ zFcyYo+=f+cb+Pa@h!Q@Eom7jDTAVD`<{H|v4>5FsA@Rj_$`bD2fCXl828UzuKIcvV zew#vgSYR%KYMVQ@rbS=^Irk=g6**E#Q_FPj0jiRuR?i=|Ug?@0aF zCNXWcRoD6a%aF?7F_BC=fk;%!_SQCkCXss=0=XM5xjIUEPLBg`&H&7#=-%Cz%VIeW z)sRHtAscn2k&BC4cFPsWDno21&K1l{WNW*5li2P+ZC1-!w0ME4y@kR@wZeZbPPH>g zsP4arQ(1vrg<1y~gyk)(#nH{AcrZM`-beMF7!z?icU$N6IwHv{m{phdI-DtoE)bOC znW?O+n<{KJAwc*@E4jM2x8!mM&Z{7aU)80?hAUz@9f0dP>Flv-WI_xA5$cjG2-M;} zg12%B${san;ikS825sQv?+`uhfk1l_EDMp*&`BAF10WJ5w!muZ>*nz`gys>-(#P6P zEoyO}T7dxWhB=U~euwa=9yon)e9sAy>E7C)V#KZ;;=_d*!AXb1<~U9WMlv8<;r@e4 zk3VckCk%O2Z4f8V$P31K#0c$U0PZ{^_a4M>H;}`RiM7}__vuG)XP<;bEu*_z_50~c zh(KG(4q8G5es?^^n{-Nn{hSWmOm(ZRO;WuBd8%7vzazgv3k#o(xy>ITvVg#_plEm2 zkrdll+1Od*Pi*CAWoK_Ic673nNNjPmi6dB{{IeZMv}YIlme|`ANDk^Bgn0v{G{~Qp zC#8N$c{uifiGwAfK0%T}Qd_pJ6BWfqCA0yIt<$NNDzM!TyP_hb7Sbr%{H1jF4U&iZ zF^QJk34SbM2SUD|kTNKO6{s+AAf{gNOGEDb=M%7ZEIa_K@Z5w84YVaeO6)2Nil&8@ zyx$6z`-KO=?^JK$WOR1&tb~!O)S(($TVM6hqCxhsS)ts~tA_~O=`C8|qc(>v3Bf^v zg2F@jWQv&pmEKD772Xb7JePk1(W`8R-2(LS9V)FV)v>XURueF}mMa9)V%Z_e@DRC@ ztzW2QX3z3vzoVWw%MRj1vn31_A2x6DQ~cR)sb?{>g9Nkezl90)63p^vzn7gJf&N@r zXsGXRVM<#ktEg;Vd8jlbZ}r&ZWA=N(smJUCiD=<5|?JD~NL^R&*dp@bqtj zSh>s=#Gd|5kjh4!M*n0Zl?QQ)0)nT%)kx(%oFKu|zY0QfU?Y_vJpHX8bv+9?>W9A- zqprarM*Z-&Vz@lw7qrw5e=A1a>OdRy!{3VG%)#YV_Wj=q$!;Z~O7{KV3gJw_X_9^a zZ$dba;e`CTzi8`sAYt0bP?I{u=w0M|OBON^vte4An!H~BEiO(9I=B=I;-H@gl1kC# z48ms1U`YU-y=NV$9MW{nQ2hRK?ueNL^z`XdPl#4aGID4HF*%-L9NHtTU4k$f5FmUc z9a%XH2z3I-RshY%2)I|wrIsYD%S$ZLea4Ok#iHDurdAdfbAY0qqY9u186 z7d~x6CpWaeo@@97)?6WM&P$h%<{XkiNX`Jv{^;HzD;VKHfZz$!+l7~z9&!3 zo)92m?CT|gIJ1B=exafC^$zZ!4b{qQ^*ej?@9v9Fk>HC^eo|q!DZ@i`e4s=tA9NG= z051%_Kt~6mo%=wA%r8J1DGds;q)(!-sS14V0Mj8Fzmuhr2XW<)!RicdEG>wJFO#$w zD3p||+Wo`$b8%&-HoNMFoBhEQTHfkGnm}3PtnU2@Idc>Oat6R6x@V5n{sDgV12#nK zu7R_ij4YvYxIe0Nvi%gC+4m^;e1AntexQwGpO6Hj>K5swP4(KV>zp5oqV9vP_JDn; z5z(+K8dCbLH0^N&(`+P3%e-^&Cqe+LuhEY`m_b$(*5BZ-L# zLDQ<@=X>6H6Vai@$xfv>Z)$e`G;gwSTXbiBc`L04<9))WHO4~$n=E1omW;LjOA6$Nb`)!r4r znwvZ_1kBuxy5Rcb)HUryqMg3lIt4l2gPa`CNC)3Lq>{${-h+j&)*Z~;OAy4}uzHhO mBFCB}*X{UiF;a{7} The response to be sent back to the client + */ + async fetch(request, env, ctx) { + // We will create a `DurableObjectId` using the pathname from the Worker request + // This id refers to a unique instance of our 'MyDurableObject' class above + let id = env.SONR_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); + + // This stub creates a communication channel with the Durable Object instance + // The Durable Object constructor will be invoked upon the first call for a given id + let stub = env.SONR_DURABLE_CLIENT.get(id); + + // We call the `sayHello()` RPC method on the stub to invoke the method on the remote + // Durable Object instance + let greeting = await stub.sayHello("world"); + + return new Response(greeting); + }, +}; diff --git a/web/workers/sonr-client/src/stub.js b/web/workers/sonr-client/src/stub.js new file mode 100644 index 000000000..c0ec6bb77 --- /dev/null +++ b/web/workers/sonr-client/src/stub.js @@ -0,0 +1,26 @@ +import { DurableObject } from "cloudflare:workers"; + +/** A Durable Object's behavior is defined in an exported Javascript class */ +export class SonrDurableClient extends DurableObject { + /** + * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to + * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) + * + * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state + * @param {Env} env - The interface to reference bindings declared in wrangler.toml + */ + constructor(ctx, env) { + super(ctx, env); + } + + /** + * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable + * Object instance receives a request from a Worker via the same method invocation on the stub + * + * @param {string} name - The name provided to a Durable Object instance from a Worker + * @returns {Promise} The greeting to be sent back to the Worker + */ + async sayHello(name) { + return `Hello, ${name}!`; + } +} diff --git a/web/workers/sonr-client/wrangler.toml b/web/workers/sonr-client/wrangler.toml new file mode 100644 index 000000000..1ccb2aa5f --- /dev/null +++ b/web/workers/sonr-client/wrangler.toml @@ -0,0 +1,113 @@ +#:schema node_modules/wrangler/config-schema.json +name = "sonr-client" +main = "src/index.js" +compatibility_date = "2024-11-12" + +# Workers Logs +# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ +# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs +[observability] +enabled = true + +# Automatically place your workloads in an optimal location to minimize latency. +# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure +# rather than the end user may result in better performance. +# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement +# [placement] +# mode = "smart" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Docs: +# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables +# Note: Use secrets to store sensitive data. +# - https://developers.cloudflare.com/workers/configuration/secrets/ +# [vars] +# MY_VARIABLE = "production_value" + +# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai +# [ai] +# binding = "AI" + +# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets +# [[analytics_engine_datasets]] +# binding = "MY_DATASET" + +# Bind a headless browser instance running on Cloudflare's global network. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering +# [browser] +# binding = "MY_BROWSER" + +# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases +# [[d1_databases]] +# binding = "MY_DB" +# database_name = "my-database" +# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms +# [[dispatch_namespaces]] +# binding = "MY_DISPATCHER" +# namespace = "my-namespace" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects +[[durable_objects.bindings]] +name = "SONR_DURABLE_CLIENT" +class_name = "SonrDurableClient" + +# Durable Object migrations. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations +[[migrations]] +tag = "v2" +renamed_classes = [{ from = "MyDurableObject", to = "SonrDurableClient" }] + +# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive +# [[hyperdrive]] +# binding = "MY_HYPERDRIVE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates +# [[mtls_certificates]] +# binding = "MY_CERTIFICATE" +# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.consumers]] +# queue = "my-queue" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets +# [[r2_buckets]] +# binding = "MY_BUCKET" +# bucket_name = "my-bucket" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes +# [[vectorize]] +# binding = "MY_INDEX" +# index_name = "my-index" From 4cbada21a7009c7763e59ae554a2c704cc1f5078 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 15:13:16 -0500 Subject: [PATCH 06/30] refactor: remove web documentation --- pkg/resolver/formatter.go | 7 ++++ web/README.md | 40 ------------------ web/Taskfile.yml | 86 --------------------------------------- 3 files changed, 7 insertions(+), 126 deletions(-) create mode 100644 pkg/resolver/formatter.go delete mode 100644 web/README.md delete mode 100644 web/Taskfile.yml diff --git a/pkg/resolver/formatter.go b/pkg/resolver/formatter.go new file mode 100644 index 000000000..2f9b78686 --- /dev/null +++ b/pkg/resolver/formatter.go @@ -0,0 +1,7 @@ +package resolver + +type DID string + +func (d DID) String() string { + return string(d) +} diff --git a/web/README.md b/web/README.md deleted file mode 100644 index aca1f39a4..000000000 --- a/web/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# `sonr` - Sonr Chain - -[![Go Reference](https://pkg.go.dev/badge/github.com/onsonr/sonr.svg)](https://pkg.go.dev/github.com/onsonr/sonr) -![GitHub commit activity](https://img.shields.io/github/commit-activity/w/onsonr/sonr) -![GitHub Release Date - Published_At](https://img.shields.io/github/release-date/onsonr/sonr) -[![Static Badge](https://img.shields.io/badge/homepage-sonr.io-blue?style=flat-square)](https://sonr.io) -[![Go Report Card](https://goreportcard.com/badge/github.com/onsonr/sonr)](https://goreportcard.com/report/github.com/onsonr/sonr) -[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=sonrhq_sonr&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=sonr-io_sonr) - -> Sonr is a combination of decentralized primitives. Fundamentally, it is a peer-to-peer identity and asset management system that leverages DID documents, Webauthn, and IPFS—providing users with a secure, portable decentralized identity. - -# Documentation - -1. [Quick Start](https://github.com/onsonr/sonr/wiki/1-%E2%80%90-Quick-Start) -2. [Chain Modules](https://github.com/onsonr/sonr/wiki/2-%E2%80%90-Chain-Modules) -3. [System Architecture](https://github.com/onsonr/sonr/wiki/3-%E2%80%90-System-Architecture) -4. [Token Economy](https://github.com/onsonr/sonr/wiki/4-%E2%80%90-Token-Economy) -5. [Service Mangement](https://github.com/onsonr/sonr/wiki/5-%E2%80%90-Service-Management) -6. [Design System](https://github.com/onsonr/sonr/wiki/6-%E2%80%90-Design-System) -7. [Self Custody](https://github.com/onsonr/sonr/wiki/7-%E2%80%90-Self-Custody) - -# Stats - -![Alt](https://repobeats.axiom.co/api/embed/8d0b17e889942889c5b6e632da09bd597efd84c4.svg "Repobeats analytics image") - -# Acknowledgements - -Sonr would not have been possible without the direct and indirect support of the following individuals: - -- **Juan Benet**: For the IPFS Ecosystem. -- **Satoshi Nakamoto**: For Bitcoin. -- **Steve Jobs**: For User first UX. -- **Tim Berners-Lee**: For the Internet. - -# Community & Support - -- [Forum](https://github.com/onsonr/sonr/discussions) -- [Issues](https://github.com/onsonr/sonr/issues) -- [Twitter](https://sonr.io/twitter) -- [Dev Chat](https://sonr.io/discord) diff --git a/web/Taskfile.yml b/web/Taskfile.yml deleted file mode 100644 index 652684c07..000000000 --- a/web/Taskfile.yml +++ /dev/null @@ -1,86 +0,0 @@ -version: "3" -vars: - ROOT_DIR: - sh: git rev-parse --show-toplevel - -tasks: - clean: - internal: true - cmds: - - rm -rf .task - - rm -rf pkg/design/node_modules - - rm -rf .out - - # ╭──────────────────────────────────────────────────╮ - # │ Generate Commands │ - # ╰──────────────────────────────────────────────────╯ - - gen:tailwind: - cmds: - - cd ./pkg/webapp && bun run build - - cp ./pkg/webapp/components/styles/styles.css ./cmd/hway/styles.css - - gen:pkl: - sources: - - pkl/base.types/Ctx.pkl - - pkl/base.types/DWN.pkl - - pkl/base.types/ORM.pkl - cmds: - - for: sources - cmd: go run github.com/apple/pkl-go/cmd/pkl-gen-go {{ .ITEM }} - - task: clean - - gen:templ: - cmds: - - templ generate - - # ╭──────────────────────────────────────────────────╮ - # │ Build Commands │ - # ╰──────────────────────────────────────────────────╯ - build:motr: - env: - GOOS: js - GOARCH: wasm - cmds: - - go build -o build/app.wasm ./cmd/motr/main.go - - build:hway: - cmds: - - task: gen:tailwind - - task: gen:templ - - go build -o build/hway ./cmd/hway/main.go - - # ╭──────────────────────────────────────────────────╮ - # │ Serve Commands │ - # ╰──────────────────────────────────────────────────╯ - - serve:hway: - cmds: - - task: build:hway - - ./build/hway - - # ╭──────────────────────────────────────────────────╮ - # │ Deploy Commands │ - # ╰──────────────────────────────────────────────────╯ - deploy:buf: - dir: proto - cmds: - - bunx buf dep update - - bunx buf build - - bunx buf push - - deploy:hway: - dir: cmd/hway - cmds: - - task: gen:design - - bunx wrangler deploy - - deploy:pkl: - cmds: - - bunx pkl project package pkl/*/ - - | - for dir in .out/*/; do - folder=$(basename "$dir") - rclone copy "$dir" "r2:pkljar/$folder" - done - - task: clean From 711acd6bb83927d52ae63a006205733bfe59589f Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 15:17:19 -0500 Subject: [PATCH 07/30] refactor: move resolver formatter to services package --- pkg/{ => services}/resolver/formatter.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkg/{ => services}/resolver/formatter.go (100%) diff --git a/pkg/resolver/formatter.go b/pkg/services/resolver/formatter.go similarity index 100% rename from pkg/resolver/formatter.go rename to pkg/services/resolver/formatter.go From 629ef72954268270a267ae19c13670a5de1cd23b Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 15:44:55 -0500 Subject: [PATCH 08/30] refactor: Rename x/vault -> x/dwn and x/service -> x/svc --- api/dwn/module/v1/module.pulsar.go | 498 ++ api/dwn/v1/genesis.pulsar.go | 2322 +++++++++ api/dwn/v1/query.pulsar.go | 4218 +++++++++++++++++ api/dwn/v1/query_grpc.pb.go | 253 + api/dwn/v1/state.cosmos_orm.go | 166 + api/dwn/v1/state.pulsar.go | 626 +++ api/dwn/v1/tx.pulsar.go | 2061 ++++++++ api/dwn/v1/tx_grpc.pb.go | 171 + api/svc/module/v1/module.pulsar.go | 498 ++ api/svc/v1/genesis.pulsar.go | 3264 +++++++++++++ api/svc/v1/query.pulsar.go | 993 ++++ api/svc/v1/query_grpc.pb.go | 127 + api/svc/v1/state.cosmos_orm.go | 368 ++ api/svc/v1/state.pulsar.go | 1749 +++++++ api/svc/v1/tx.pulsar.go | 2195 +++++++++ api/svc/v1/tx_grpc.pb.go | 173 + api/vault/v1/tx.pulsar.go | 1032 +++- api/vault/v1/tx_grpc.pb.go | 40 + app/app.go | 90 +- proto/README.md | 10 +- proto/{service => dwn}/module/v1/module.proto | 8 +- proto/{vault => dwn}/v1/genesis.proto | 10 +- proto/{vault => dwn}/v1/query.proto | 6 +- proto/dwn/v1/state.proto | 19 + proto/{vault => dwn}/v1/tx.proto | 9 +- proto/{vault => svc}/module/v1/module.proto | 8 +- proto/{service => svc}/v1/genesis.proto | 6 +- proto/{service => svc}/v1/query.proto | 8 +- proto/{service => svc}/v1/state.proto | 5 +- proto/{service => svc}/v1/tx.proto | 8 +- proto/vault/v1/state.proto | 21 - scripts/protocgen.sh | 14 - web/workers/noble-client/.gitignore | 5 - web/workers/noble-client/README.md | 9 - web/workers/noble-client/package.json | 16 - web/workers/noble-client/src/index.js | 45 - web/workers/noble-client/src/stub.js | 26 - web/workers/noble-client/wrangler.toml | 113 - web/workers/osmosis-client/.gitignore | 5 - web/workers/osmosis-client/README.md | 10 - web/workers/osmosis-client/package.json | 16 - web/workers/osmosis-client/src/index.js | 45 - web/workers/osmosis-client/src/stub.js | 26 - web/workers/osmosis-client/wrangler.toml | 113 - web/workers/sonr-client/.gitignore | 5 - web/workers/sonr-client/README.md | 10 - web/workers/sonr-client/bun.lockb | Bin 106594 -> 0 bytes web/workers/sonr-client/package.json | 16 - web/workers/sonr-client/src/index.js | 45 - web/workers/sonr-client/src/stub.js | 26 - web/workers/sonr-client/wrangler.toml | 113 - x/{vault => dwn}/README.md | 28 +- x/{vault => dwn}/autocli.go | 2 +- x/{vault => dwn}/client/cli/query.go | 2 +- x/{vault => dwn}/client/cli/tx.go | 4 +- x/{vault => dwn}/depinject.go | 24 +- x/{vault => dwn}/keeper/genesis_test.go | 5 +- x/{service => dwn}/keeper/keeper.go | 57 +- x/{vault => dwn}/keeper/keeper_test.go | 52 +- .../rpc.go => dwn/keeper/msg_server.go} | 9 +- .../keeper/msg_server_test.go} | 2 +- x/dwn/keeper/orm_test.go | 31 + x/dwn/keeper/query_server.go | 51 + x/{service => dwn}/module.go | 21 +- x/{vault => dwn}/types/codec.go | 2 - x/{vault => dwn}/types/genesis.go | 2 - x/{vault => dwn}/types/genesis.pb.go | 75 +- x/{vault => dwn}/types/genesis_test.go | 10 +- x/{vault => dwn}/types/keys.go | 4 +- x/{vault => dwn}/types/msgs.go | 0 x/{vault => dwn}/types/params.go | 0 x/{vault => dwn}/types/query.pb.go | 124 +- x/{vault => dwn}/types/query.pb.gw.go | 2 +- x/{vault => dwn}/types/spawn.go | 2 +- x/dwn/types/state.pb.go | 355 ++ x/{vault => dwn}/types/static/index.html | 0 x/{vault => dwn}/types/static/static.go | 0 x/{vault => dwn}/types/static/sw.js | 0 x/{vault => dwn}/types/tx.pb.go | 464 +- x/service/keeper/genesis.go | 37 - x/service/keeper/orm_test.go | 31 - x/service/types/errors.go | 10 - x/{service => svc}/README.md | 26 +- x/{service => svc}/autocli.go | 2 +- x/{service => svc}/client/cli/query.go | 2 +- x/{service => svc}/client/cli/tx.go | 18 +- x/{service => svc}/depinject.go | 28 +- x/{service => svc}/keeper/genesis_test.go | 5 +- x/svc/keeper/keeper.go | 102 + x/{service => svc}/keeper/keeper_test.go | 58 +- .../rpc.go => svc/keeper/msg_server.go} | 2 +- .../keeper/msg_server_test.go} | 2 +- .../querier.go => svc/keeper/query_server.go} | 2 +- x/{vault => svc}/module.go | 32 +- x/{service => svc}/types/codec.go | 2 - x/{service => svc}/types/genesis.go | 6 +- x/{service => svc}/types/genesis.pb.go | 84 +- x/{service => svc}/types/genesis_test.go | 10 +- x/{service => svc}/types/keys.go | 4 +- x/{service => svc}/types/msgs.go | 0 x/{service => svc}/types/params.go | 0 x/{service => svc}/types/query.pb.go | 56 +- x/{service => svc}/types/query.pb.gw.go | 4 +- x/{service => svc}/types/state.pb.go | 60 +- x/{service => svc}/types/tx.pb.go | 88 +- x/vault/keeper/genesis.go | 61 - x/vault/keeper/keeper.go | 126 - x/vault/keeper/orm_test.go | 14 - x/vault/keeper/querier.go | 128 - x/vault/types/errors.go | 13 - x/vault/types/formatter.go | 1 - x/vault/types/state.pb.go | 457 -- 112 files changed, 22252 insertions(+), 2167 deletions(-) create mode 100644 api/dwn/module/v1/module.pulsar.go create mode 100644 api/dwn/v1/genesis.pulsar.go create mode 100644 api/dwn/v1/query.pulsar.go create mode 100644 api/dwn/v1/query_grpc.pb.go create mode 100644 api/dwn/v1/state.cosmos_orm.go create mode 100644 api/dwn/v1/state.pulsar.go create mode 100644 api/dwn/v1/tx.pulsar.go create mode 100644 api/dwn/v1/tx_grpc.pb.go create mode 100644 api/svc/module/v1/module.pulsar.go create mode 100644 api/svc/v1/genesis.pulsar.go create mode 100644 api/svc/v1/query.pulsar.go create mode 100644 api/svc/v1/query_grpc.pb.go create mode 100644 api/svc/v1/state.cosmos_orm.go create mode 100644 api/svc/v1/state.pulsar.go create mode 100644 api/svc/v1/tx.pulsar.go create mode 100644 api/svc/v1/tx_grpc.pb.go rename proto/{service => dwn}/module/v1/module.proto (64%) rename proto/{vault => dwn}/v1/genesis.proto (84%) rename proto/{vault => dwn}/v1/query.proto (96%) create mode 100644 proto/dwn/v1/state.proto rename proto/{vault => dwn}/v1/tx.proto (92%) rename proto/{vault => svc}/module/v1/module.proto (64%) rename proto/{service => svc}/v1/genesis.proto (92%) rename proto/{service => svc}/v1/query.proto (75%) rename proto/{service => svc}/v1/state.proto (91%) rename proto/{service => svc}/v1/tx.proto (93%) delete mode 100644 proto/vault/v1/state.proto delete mode 100644 web/workers/noble-client/.gitignore delete mode 100644 web/workers/noble-client/README.md delete mode 100644 web/workers/noble-client/package.json delete mode 100644 web/workers/noble-client/src/index.js delete mode 100644 web/workers/noble-client/src/stub.js delete mode 100644 web/workers/noble-client/wrangler.toml delete mode 100644 web/workers/osmosis-client/.gitignore delete mode 100644 web/workers/osmosis-client/README.md delete mode 100644 web/workers/osmosis-client/package.json delete mode 100644 web/workers/osmosis-client/src/index.js delete mode 100644 web/workers/osmosis-client/src/stub.js delete mode 100644 web/workers/osmosis-client/wrangler.toml delete mode 100644 web/workers/sonr-client/.gitignore delete mode 100644 web/workers/sonr-client/README.md delete mode 100755 web/workers/sonr-client/bun.lockb delete mode 100644 web/workers/sonr-client/package.json delete mode 100644 web/workers/sonr-client/src/index.js delete mode 100644 web/workers/sonr-client/src/stub.js delete mode 100644 web/workers/sonr-client/wrangler.toml rename x/{vault => dwn}/README.md (85%) rename x/{vault => dwn}/autocli.go (94%) rename x/{vault => dwn}/client/cli/query.go (96%) rename x/{vault => dwn}/client/cli/tx.go (95%) rename x/{vault => dwn}/depinject.go (78%) rename x/{vault => dwn}/keeper/genesis_test.go (63%) rename x/{service => dwn}/keeper/keeper.go (67%) rename x/{vault => dwn}/keeper/keeper_test.go (68%) rename x/{vault/keeper/rpc.go => dwn/keeper/msg_server.go} (68%) rename x/{vault/keeper/rpc_test.go => dwn/keeper/msg_server_test.go} (96%) create mode 100644 x/dwn/keeper/orm_test.go create mode 100644 x/dwn/keeper/query_server.go rename x/{service => dwn}/module.go (91%) rename x/{vault => dwn}/types/codec.go (89%) rename x/{vault => dwn}/types/genesis.go (93%) rename x/{vault => dwn}/types/genesis.pb.go (89%) rename x/{vault => dwn}/types/genesis_test.go (69%) rename x/{vault => dwn}/types/keys.go (85%) rename x/{vault => dwn}/types/msgs.go (100%) rename x/{vault => dwn}/types/params.go (100%) rename x/{vault => dwn}/types/query.pb.go (90%) rename x/{vault => dwn}/types/query.pb.gw.go (99%) rename x/{vault => dwn}/types/spawn.go (95%) create mode 100644 x/dwn/types/state.pb.go rename x/{vault => dwn}/types/static/index.html (100%) rename x/{vault => dwn}/types/static/static.go (100%) rename x/{vault => dwn}/types/static/sw.js (100%) rename x/{vault => dwn}/types/tx.pb.go (52%) delete mode 100644 x/service/keeper/genesis.go delete mode 100644 x/service/keeper/orm_test.go delete mode 100644 x/service/types/errors.go rename x/{service => svc}/README.md (57%) rename x/{service => svc}/autocli.go (94%) rename x/{service => svc}/client/cli/query.go (96%) rename x/{service => svc}/client/cli/tx.go (87%) rename x/{service => svc}/depinject.go (70%) rename x/{service => svc}/keeper/genesis_test.go (63%) create mode 100644 x/svc/keeper/keeper.go rename x/{service => svc}/keeper/keeper_test.go (64%) rename x/{service/keeper/rpc.go => svc/keeper/msg_server.go} (96%) rename x/{service/keeper/rpc_test.go => svc/keeper/msg_server_test.go} (95%) rename x/{service/keeper/querier.go => svc/keeper/query_server.go} (92%) rename x/{vault => svc}/module.go (89%) rename x/{service => svc}/types/codec.go (89%) rename x/{service => svc}/types/genesis.go (65%) rename x/{service => svc}/types/genesis.pb.go (90%) rename x/{service => svc}/types/genesis_test.go (69%) rename x/{service => svc}/types/keys.go (84%) rename x/{service => svc}/types/msgs.go (100%) rename x/{service => svc}/types/params.go (100%) rename x/{service => svc}/types/query.pb.go (85%) rename x/{service => svc}/types/query.pb.gw.go (97%) rename x/{service => svc}/types/state.pb.go (88%) rename x/{service => svc}/types/tx.pb.go (87%) delete mode 100644 x/vault/keeper/genesis.go delete mode 100644 x/vault/keeper/keeper.go delete mode 100644 x/vault/keeper/orm_test.go delete mode 100644 x/vault/keeper/querier.go delete mode 100644 x/vault/types/errors.go delete mode 100644 x/vault/types/formatter.go delete mode 100644 x/vault/types/state.pb.go diff --git a/api/dwn/module/v1/module.pulsar.go b/api/dwn/module/v1/module.pulsar.go new file mode 100644 index 000000000..501dc07c7 --- /dev/null +++ b/api/dwn/module/v1/module.pulsar.go @@ -0,0 +1,498 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package modulev1 + +import ( + _ "cosmossdk.io/api/cosmos/app/v1alpha1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_Module protoreflect.MessageDescriptor +) + +func init() { + file_dwn_module_v1_module_proto_init() + md_Module = File_dwn_module_v1_module_proto.Messages().ByName("Module") +} + +var _ protoreflect.Message = (*fastReflection_Module)(nil) + +type fastReflection_Module Module + +func (x *Module) ProtoReflect() protoreflect.Message { + return (*fastReflection_Module)(x) +} + +func (x *Module) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_module_v1_module_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Module_messageType fastReflection_Module_messageType +var _ protoreflect.MessageType = fastReflection_Module_messageType{} + +type fastReflection_Module_messageType struct{} + +func (x fastReflection_Module_messageType) Zero() protoreflect.Message { + return (*fastReflection_Module)(nil) +} +func (x fastReflection_Module_messageType) New() protoreflect.Message { + return new(fastReflection_Module) +} +func (x fastReflection_Module_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Module +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Module) Descriptor() protoreflect.MessageDescriptor { + return md_Module +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Module) Type() protoreflect.MessageType { + return _fastReflection_Module_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Module) New() protoreflect.Message { + return new(fastReflection_Module) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage { + return (*Module)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.module.v1.Module")) + } + panic(fmt.Errorf("message dwn.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.module.v1.Module")) + } + panic(fmt.Errorf("message dwn.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.module.v1.Module")) + } + panic(fmt.Errorf("message dwn.module.v1.Module does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.module.v1.Module")) + } + panic(fmt.Errorf("message dwn.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.module.v1.Module")) + } + panic(fmt.Errorf("message dwn.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.module.v1.Module")) + } + panic(fmt.Errorf("message dwn.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.module.v1.Module", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Module) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Module) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: dwn/module/v1/module.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Module is the app config object of the module. +// Learn more: https://docs.cosmos.network/main/building-modules/depinject +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_module_v1_module_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_dwn_module_v1_module_proto_rawDescGZIP(), []int{0} +} + +var File_dwn_module_v1_module_proto protoreflect.FileDescriptor + +var file_dwn_module_v1_module_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x64, 0x77, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x77, + 0x6e, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, + 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a, + 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, + 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, 0xa9, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, + 0x64, 0x77, 0x6e, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, + 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x77, 0x6e, 0x2f, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x44, 0x4d, 0x58, 0xaa, 0x02, 0x0d, 0x44, 0x77, 0x6e, 0x2e, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x44, 0x77, 0x6e, 0x5c, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x44, 0x77, 0x6e, 0x5c, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x0f, 0x44, 0x77, 0x6e, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_dwn_module_v1_module_proto_rawDescOnce sync.Once + file_dwn_module_v1_module_proto_rawDescData = file_dwn_module_v1_module_proto_rawDesc +) + +func file_dwn_module_v1_module_proto_rawDescGZIP() []byte { + file_dwn_module_v1_module_proto_rawDescOnce.Do(func() { + file_dwn_module_v1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_dwn_module_v1_module_proto_rawDescData) + }) + return file_dwn_module_v1_module_proto_rawDescData +} + +var file_dwn_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_dwn_module_v1_module_proto_goTypes = []interface{}{ + (*Module)(nil), // 0: dwn.module.v1.Module +} +var file_dwn_module_v1_module_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_dwn_module_v1_module_proto_init() } +func file_dwn_module_v1_module_proto_init() { + if File_dwn_module_v1_module_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_dwn_module_v1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Module); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dwn_module_v1_module_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_dwn_module_v1_module_proto_goTypes, + DependencyIndexes: file_dwn_module_v1_module_proto_depIdxs, + MessageInfos: file_dwn_module_v1_module_proto_msgTypes, + }.Build() + File_dwn_module_v1_module_proto = out.File + file_dwn_module_v1_module_proto_rawDesc = nil + file_dwn_module_v1_module_proto_goTypes = nil + file_dwn_module_v1_module_proto_depIdxs = nil +} diff --git a/api/dwn/v1/genesis.pulsar.go b/api/dwn/v1/genesis.pulsar.go new file mode 100644 index 000000000..c4ad51b96 --- /dev/null +++ b/api/dwn/v1/genesis.pulsar.go @@ -0,0 +1,2322 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package dwnv1 + +import ( + _ "cosmossdk.io/api/amino" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_GenesisState protoreflect.MessageDescriptor + fd_GenesisState_params protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_genesis_proto_init() + md_GenesisState = File_dwn_v1_genesis_proto.Messages().ByName("GenesisState") + fd_GenesisState_params = md_GenesisState.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_GenesisState)(nil) + +type fastReflection_GenesisState GenesisState + +func (x *GenesisState) ProtoReflect() protoreflect.Message { + return (*fastReflection_GenesisState)(x) +} + +func (x *GenesisState) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_genesis_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_GenesisState_messageType fastReflection_GenesisState_messageType +var _ protoreflect.MessageType = fastReflection_GenesisState_messageType{} + +type fastReflection_GenesisState_messageType struct{} + +func (x fastReflection_GenesisState_messageType) Zero() protoreflect.Message { + return (*fastReflection_GenesisState)(nil) +} +func (x fastReflection_GenesisState_messageType) New() protoreflect.Message { + return new(fastReflection_GenesisState) +} +func (x fastReflection_GenesisState_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_GenesisState +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_GenesisState) Descriptor() protoreflect.MessageDescriptor { + return md_GenesisState +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_GenesisState) Type() protoreflect.MessageType { + return _fastReflection_GenesisState_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_GenesisState) New() protoreflect.Message { + return new(fastReflection_GenesisState) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_GenesisState) Interface() protoreflect.ProtoMessage { + return (*GenesisState)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_GenesisState_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.GenesisState.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.GenesisState")) + } + panic(fmt.Errorf("message dwn.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.GenesisState.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.GenesisState")) + } + panic(fmt.Errorf("message dwn.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.GenesisState.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.GenesisState")) + } + panic(fmt.Errorf("message dwn.v1.GenesisState does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.GenesisState.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.GenesisState")) + } + panic(fmt.Errorf("message dwn.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.GenesisState.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.GenesisState")) + } + panic(fmt.Errorf("message dwn.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.GenesisState.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.GenesisState")) + } + panic(fmt.Errorf("message dwn.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_GenesisState) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.GenesisState", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_GenesisState) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_GenesisState) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_Params protoreflect.MessageDescriptor + fd_Params_ipfs_active protoreflect.FieldDescriptor + fd_Params_local_registration_enabled protoreflect.FieldDescriptor + fd_Params_schema protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_genesis_proto_init() + md_Params = File_dwn_v1_genesis_proto.Messages().ByName("Params") + fd_Params_ipfs_active = md_Params.Fields().ByName("ipfs_active") + fd_Params_local_registration_enabled = md_Params.Fields().ByName("local_registration_enabled") + fd_Params_schema = md_Params.Fields().ByName("schema") +} + +var _ protoreflect.Message = (*fastReflection_Params)(nil) + +type fastReflection_Params Params + +func (x *Params) ProtoReflect() protoreflect.Message { + return (*fastReflection_Params)(x) +} + +func (x *Params) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_genesis_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Params_messageType fastReflection_Params_messageType +var _ protoreflect.MessageType = fastReflection_Params_messageType{} + +type fastReflection_Params_messageType struct{} + +func (x fastReflection_Params_messageType) Zero() protoreflect.Message { + return (*fastReflection_Params)(nil) +} +func (x fastReflection_Params_messageType) New() protoreflect.Message { + return new(fastReflection_Params) +} +func (x fastReflection_Params_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Params) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Params) Type() protoreflect.MessageType { + return _fastReflection_Params_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Params) New() protoreflect.Message { + return new(fastReflection_Params) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { + return (*Params)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.IpfsActive != false { + value := protoreflect.ValueOfBool(x.IpfsActive) + if !f(fd_Params_ipfs_active, value) { + return + } + } + if x.LocalRegistrationEnabled != false { + value := protoreflect.ValueOfBool(x.LocalRegistrationEnabled) + if !f(fd_Params_local_registration_enabled, value) { + return + } + } + if x.Schema != nil { + value := protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) + if !f(fd_Params_schema, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.Params.ipfs_active": + return x.IpfsActive != false + case "dwn.v1.Params.local_registration_enabled": + return x.LocalRegistrationEnabled != false + case "dwn.v1.Params.schema": + return x.Schema != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Params")) + } + panic(fmt.Errorf("message dwn.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.Params.ipfs_active": + x.IpfsActive = false + case "dwn.v1.Params.local_registration_enabled": + x.LocalRegistrationEnabled = false + case "dwn.v1.Params.schema": + x.Schema = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Params")) + } + panic(fmt.Errorf("message dwn.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.Params.ipfs_active": + value := x.IpfsActive + return protoreflect.ValueOfBool(value) + case "dwn.v1.Params.local_registration_enabled": + value := x.LocalRegistrationEnabled + return protoreflect.ValueOfBool(value) + case "dwn.v1.Params.schema": + value := x.Schema + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Params")) + } + panic(fmt.Errorf("message dwn.v1.Params does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.Params.ipfs_active": + x.IpfsActive = value.Bool() + case "dwn.v1.Params.local_registration_enabled": + x.LocalRegistrationEnabled = value.Bool() + case "dwn.v1.Params.schema": + x.Schema = value.Message().Interface().(*Schema) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Params")) + } + panic(fmt.Errorf("message dwn.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Params.schema": + if x.Schema == nil { + x.Schema = new(Schema) + } + return protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) + case "dwn.v1.Params.ipfs_active": + panic(fmt.Errorf("field ipfs_active of message dwn.v1.Params is not mutable")) + case "dwn.v1.Params.local_registration_enabled": + panic(fmt.Errorf("field local_registration_enabled of message dwn.v1.Params is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Params")) + } + panic(fmt.Errorf("message dwn.v1.Params does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Params.ipfs_active": + return protoreflect.ValueOfBool(false) + case "dwn.v1.Params.local_registration_enabled": + return protoreflect.ValueOfBool(false) + case "dwn.v1.Params.schema": + m := new(Schema) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Params")) + } + panic(fmt.Errorf("message dwn.v1.Params does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.Params", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Params) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Params) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.IpfsActive { + n += 2 + } + if x.LocalRegistrationEnabled { + n += 2 + } + if x.Schema != nil { + l = options.Size(x.Schema) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Schema != nil { + encoded, err := options.Marshal(x.Schema) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x22 + } + if x.LocalRegistrationEnabled { + i-- + if x.LocalRegistrationEnabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if x.IpfsActive { + i-- + if x.IpfsActive { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field IpfsActive", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.IpfsActive = bool(v != 0) + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field LocalRegistrationEnabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.LocalRegistrationEnabled = bool(v != 0) + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Schema == nil { + x.Schema = &Schema{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Schema); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_Schema protoreflect.MessageDescriptor + fd_Schema_version protoreflect.FieldDescriptor + fd_Schema_account protoreflect.FieldDescriptor + fd_Schema_asset protoreflect.FieldDescriptor + fd_Schema_chain protoreflect.FieldDescriptor + fd_Schema_credential protoreflect.FieldDescriptor + fd_Schema_did protoreflect.FieldDescriptor + fd_Schema_jwk protoreflect.FieldDescriptor + fd_Schema_grant protoreflect.FieldDescriptor + fd_Schema_keyshare protoreflect.FieldDescriptor + fd_Schema_profile protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_genesis_proto_init() + md_Schema = File_dwn_v1_genesis_proto.Messages().ByName("Schema") + fd_Schema_version = md_Schema.Fields().ByName("version") + fd_Schema_account = md_Schema.Fields().ByName("account") + fd_Schema_asset = md_Schema.Fields().ByName("asset") + fd_Schema_chain = md_Schema.Fields().ByName("chain") + fd_Schema_credential = md_Schema.Fields().ByName("credential") + fd_Schema_did = md_Schema.Fields().ByName("did") + fd_Schema_jwk = md_Schema.Fields().ByName("jwk") + fd_Schema_grant = md_Schema.Fields().ByName("grant") + fd_Schema_keyshare = md_Schema.Fields().ByName("keyshare") + fd_Schema_profile = md_Schema.Fields().ByName("profile") +} + +var _ protoreflect.Message = (*fastReflection_Schema)(nil) + +type fastReflection_Schema Schema + +func (x *Schema) ProtoReflect() protoreflect.Message { + return (*fastReflection_Schema)(x) +} + +func (x *Schema) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_genesis_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Schema_messageType fastReflection_Schema_messageType +var _ protoreflect.MessageType = fastReflection_Schema_messageType{} + +type fastReflection_Schema_messageType struct{} + +func (x fastReflection_Schema_messageType) Zero() protoreflect.Message { + return (*fastReflection_Schema)(nil) +} +func (x fastReflection_Schema_messageType) New() protoreflect.Message { + return new(fastReflection_Schema) +} +func (x fastReflection_Schema_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Schema +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Schema) Descriptor() protoreflect.MessageDescriptor { + return md_Schema +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Schema) Type() protoreflect.MessageType { + return _fastReflection_Schema_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Schema) New() protoreflect.Message { + return new(fastReflection_Schema) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Schema) Interface() protoreflect.ProtoMessage { + return (*Schema)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Schema) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Version != int32(0) { + value := protoreflect.ValueOfInt32(x.Version) + if !f(fd_Schema_version, value) { + return + } + } + if x.Account != "" { + value := protoreflect.ValueOfString(x.Account) + if !f(fd_Schema_account, value) { + return + } + } + if x.Asset != "" { + value := protoreflect.ValueOfString(x.Asset) + if !f(fd_Schema_asset, value) { + return + } + } + if x.Chain != "" { + value := protoreflect.ValueOfString(x.Chain) + if !f(fd_Schema_chain, value) { + return + } + } + if x.Credential != "" { + value := protoreflect.ValueOfString(x.Credential) + if !f(fd_Schema_credential, value) { + return + } + } + if x.Did != "" { + value := protoreflect.ValueOfString(x.Did) + if !f(fd_Schema_did, value) { + return + } + } + if x.Jwk != "" { + value := protoreflect.ValueOfString(x.Jwk) + if !f(fd_Schema_jwk, value) { + return + } + } + if x.Grant != "" { + value := protoreflect.ValueOfString(x.Grant) + if !f(fd_Schema_grant, value) { + return + } + } + if x.Keyshare != "" { + value := protoreflect.ValueOfString(x.Keyshare) + if !f(fd_Schema_keyshare, value) { + return + } + } + if x.Profile != "" { + value := protoreflect.ValueOfString(x.Profile) + if !f(fd_Schema_profile, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Schema) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.Schema.version": + return x.Version != int32(0) + case "dwn.v1.Schema.account": + return x.Account != "" + case "dwn.v1.Schema.asset": + return x.Asset != "" + case "dwn.v1.Schema.chain": + return x.Chain != "" + case "dwn.v1.Schema.credential": + return x.Credential != "" + case "dwn.v1.Schema.did": + return x.Did != "" + case "dwn.v1.Schema.jwk": + return x.Jwk != "" + case "dwn.v1.Schema.grant": + return x.Grant != "" + case "dwn.v1.Schema.keyshare": + return x.Keyshare != "" + case "dwn.v1.Schema.profile": + return x.Profile != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Schema")) + } + panic(fmt.Errorf("message dwn.v1.Schema does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Schema) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.Schema.version": + x.Version = int32(0) + case "dwn.v1.Schema.account": + x.Account = "" + case "dwn.v1.Schema.asset": + x.Asset = "" + case "dwn.v1.Schema.chain": + x.Chain = "" + case "dwn.v1.Schema.credential": + x.Credential = "" + case "dwn.v1.Schema.did": + x.Did = "" + case "dwn.v1.Schema.jwk": + x.Jwk = "" + case "dwn.v1.Schema.grant": + x.Grant = "" + case "dwn.v1.Schema.keyshare": + x.Keyshare = "" + case "dwn.v1.Schema.profile": + x.Profile = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Schema")) + } + panic(fmt.Errorf("message dwn.v1.Schema does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Schema) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.Schema.version": + value := x.Version + return protoreflect.ValueOfInt32(value) + case "dwn.v1.Schema.account": + value := x.Account + return protoreflect.ValueOfString(value) + case "dwn.v1.Schema.asset": + value := x.Asset + return protoreflect.ValueOfString(value) + case "dwn.v1.Schema.chain": + value := x.Chain + return protoreflect.ValueOfString(value) + case "dwn.v1.Schema.credential": + value := x.Credential + return protoreflect.ValueOfString(value) + case "dwn.v1.Schema.did": + value := x.Did + return protoreflect.ValueOfString(value) + case "dwn.v1.Schema.jwk": + value := x.Jwk + return protoreflect.ValueOfString(value) + case "dwn.v1.Schema.grant": + value := x.Grant + return protoreflect.ValueOfString(value) + case "dwn.v1.Schema.keyshare": + value := x.Keyshare + return protoreflect.ValueOfString(value) + case "dwn.v1.Schema.profile": + value := x.Profile + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Schema")) + } + panic(fmt.Errorf("message dwn.v1.Schema does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Schema) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.Schema.version": + x.Version = int32(value.Int()) + case "dwn.v1.Schema.account": + x.Account = value.Interface().(string) + case "dwn.v1.Schema.asset": + x.Asset = value.Interface().(string) + case "dwn.v1.Schema.chain": + x.Chain = value.Interface().(string) + case "dwn.v1.Schema.credential": + x.Credential = value.Interface().(string) + case "dwn.v1.Schema.did": + x.Did = value.Interface().(string) + case "dwn.v1.Schema.jwk": + x.Jwk = value.Interface().(string) + case "dwn.v1.Schema.grant": + x.Grant = value.Interface().(string) + case "dwn.v1.Schema.keyshare": + x.Keyshare = value.Interface().(string) + case "dwn.v1.Schema.profile": + x.Profile = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Schema")) + } + panic(fmt.Errorf("message dwn.v1.Schema does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Schema) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Schema.version": + panic(fmt.Errorf("field version of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.account": + panic(fmt.Errorf("field account of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.asset": + panic(fmt.Errorf("field asset of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.chain": + panic(fmt.Errorf("field chain of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.credential": + panic(fmt.Errorf("field credential of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.did": + panic(fmt.Errorf("field did of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.jwk": + panic(fmt.Errorf("field jwk of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.grant": + panic(fmt.Errorf("field grant of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.keyshare": + panic(fmt.Errorf("field keyshare of message dwn.v1.Schema is not mutable")) + case "dwn.v1.Schema.profile": + panic(fmt.Errorf("field profile of message dwn.v1.Schema is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Schema")) + } + panic(fmt.Errorf("message dwn.v1.Schema does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Schema) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Schema.version": + return protoreflect.ValueOfInt32(int32(0)) + case "dwn.v1.Schema.account": + return protoreflect.ValueOfString("") + case "dwn.v1.Schema.asset": + return protoreflect.ValueOfString("") + case "dwn.v1.Schema.chain": + return protoreflect.ValueOfString("") + case "dwn.v1.Schema.credential": + return protoreflect.ValueOfString("") + case "dwn.v1.Schema.did": + return protoreflect.ValueOfString("") + case "dwn.v1.Schema.jwk": + return protoreflect.ValueOfString("") + case "dwn.v1.Schema.grant": + return protoreflect.ValueOfString("") + case "dwn.v1.Schema.keyshare": + return protoreflect.ValueOfString("") + case "dwn.v1.Schema.profile": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Schema")) + } + panic(fmt.Errorf("message dwn.v1.Schema does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Schema) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.Schema", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Schema) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Schema) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Schema) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Schema) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Schema) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Version != 0 { + n += 1 + runtime.Sov(uint64(x.Version)) + } + l = len(x.Account) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Asset) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Chain) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Credential) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Did) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Jwk) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Grant) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Keyshare) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Profile) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Schema) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Profile) > 0 { + i -= len(x.Profile) + copy(dAtA[i:], x.Profile) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Profile))) + i-- + dAtA[i] = 0x52 + } + if len(x.Keyshare) > 0 { + i -= len(x.Keyshare) + copy(dAtA[i:], x.Keyshare) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Keyshare))) + i-- + dAtA[i] = 0x4a + } + if len(x.Grant) > 0 { + i -= len(x.Grant) + copy(dAtA[i:], x.Grant) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Grant))) + i-- + dAtA[i] = 0x42 + } + if len(x.Jwk) > 0 { + i -= len(x.Jwk) + copy(dAtA[i:], x.Jwk) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Jwk))) + i-- + dAtA[i] = 0x3a + } + if len(x.Did) > 0 { + i -= len(x.Did) + copy(dAtA[i:], x.Did) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Did))) + i-- + dAtA[i] = 0x32 + } + if len(x.Credential) > 0 { + i -= len(x.Credential) + copy(dAtA[i:], x.Credential) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Credential))) + i-- + dAtA[i] = 0x2a + } + if len(x.Chain) > 0 { + i -= len(x.Chain) + copy(dAtA[i:], x.Chain) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Chain))) + i-- + dAtA[i] = 0x22 + } + if len(x.Asset) > 0 { + i -= len(x.Asset) + copy(dAtA[i:], x.Asset) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Asset))) + i-- + dAtA[i] = 0x1a + } + if len(x.Account) > 0 { + i -= len(x.Account) + copy(dAtA[i:], x.Account) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Account))) + i-- + dAtA[i] = 0x12 + } + if x.Version != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Version)) + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Schema) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Schema: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Schema: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + x.Version = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Version |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Asset", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Asset = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Chain", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Chain = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Credential", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Credential = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Did", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Did = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Jwk", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Jwk = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Grant", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Grant = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Keyshare", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Keyshare = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Profile", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Profile = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: dwn/v1/genesis.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// GenesisState defines the module genesis state +type GenesisState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Params defines all the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *GenesisState) Reset() { + *x = GenesisState{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_genesis_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenesisState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenesisState) ProtoMessage() {} + +// Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. +func (*GenesisState) Descriptor() ([]byte, []int) { + return file_dwn_v1_genesis_proto_rawDescGZIP(), []int{0} +} + +func (x *GenesisState) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// Params defines the set of module parameters. +type Params struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IpfsActive bool `protobuf:"varint,1,opt,name=ipfs_active,json=ipfsActive,proto3" json:"ipfs_active,omitempty"` + LocalRegistrationEnabled bool `protobuf:"varint,2,opt,name=local_registration_enabled,json=localRegistrationEnabled,proto3" json:"local_registration_enabled,omitempty"` + Schema *Schema `protobuf:"bytes,4,opt,name=schema,proto3" json:"schema,omitempty"` +} + +func (x *Params) Reset() { + *x = Params{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_genesis_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Params) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Params) ProtoMessage() {} + +// Deprecated: Use Params.ProtoReflect.Descriptor instead. +func (*Params) Descriptor() ([]byte, []int) { + return file_dwn_v1_genesis_proto_rawDescGZIP(), []int{1} +} + +func (x *Params) GetIpfsActive() bool { + if x != nil { + return x.IpfsActive + } + return false +} + +func (x *Params) GetLocalRegistrationEnabled() bool { + if x != nil { + return x.LocalRegistrationEnabled + } + return false +} + +func (x *Params) GetSchema() *Schema { + if x != nil { + return x.Schema + } + return nil +} + +type Schema struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version int32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` + Asset string `protobuf:"bytes,3,opt,name=asset,proto3" json:"asset,omitempty"` + Chain string `protobuf:"bytes,4,opt,name=chain,proto3" json:"chain,omitempty"` + Credential string `protobuf:"bytes,5,opt,name=credential,proto3" json:"credential,omitempty"` + Did string `protobuf:"bytes,6,opt,name=did,proto3" json:"did,omitempty"` + Jwk string `protobuf:"bytes,7,opt,name=jwk,proto3" json:"jwk,omitempty"` + Grant string `protobuf:"bytes,8,opt,name=grant,proto3" json:"grant,omitempty"` + Keyshare string `protobuf:"bytes,9,opt,name=keyshare,proto3" json:"keyshare,omitempty"` + Profile string `protobuf:"bytes,10,opt,name=profile,proto3" json:"profile,omitempty"` +} + +func (x *Schema) Reset() { + *x = Schema{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_genesis_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema) ProtoMessage() {} + +// Deprecated: Use Schema.ProtoReflect.Descriptor instead. +func (*Schema) Descriptor() ([]byte, []int) { + return file_dwn_v1_genesis_proto_rawDescGZIP(), []int{2} +} + +func (x *Schema) GetVersion() int32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Schema) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *Schema) GetAsset() string { + if x != nil { + return x.Asset + } + return "" +} + +func (x *Schema) GetChain() string { + if x != nil { + return x.Chain + } + return "" +} + +func (x *Schema) GetCredential() string { + if x != nil { + return x.Credential + } + return "" +} + +func (x *Schema) GetDid() string { + if x != nil { + return x.Did + } + return "" +} + +func (x *Schema) GetJwk() string { + if x != nil { + return x.Jwk + } + return "" +} + +func (x *Schema) GetGrant() string { + if x != nil { + return x.Grant + } + return "" +} + +func (x *Schema) GetKeyshare() string { + if x != nil { + return x.Keyshare + } + return "" +} + +func (x *Schema) GetProfile() string { + if x != nil { + return x.Profile + } + return "" +} + +var File_dwn_v1_genesis_proto protoreflect.FileDescriptor + +var file_dwn_v1_genesis_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x14, + 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, + 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3c, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, + 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xaa, 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x70, 0x66, 0x73, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x70, 0x66, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x12, 0x3c, 0x0a, 0x1a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, + 0x26, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, + 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x19, 0x98, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, + 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x22, 0xf8, 0x01, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x10, 0x0a, + 0x03, 0x64, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, + 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, + 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x68, + 0x61, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x68, + 0x61, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x7c, 0x0a, + 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, + 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, + 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, + 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, + 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, + 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_dwn_v1_genesis_proto_rawDescOnce sync.Once + file_dwn_v1_genesis_proto_rawDescData = file_dwn_v1_genesis_proto_rawDesc +) + +func file_dwn_v1_genesis_proto_rawDescGZIP() []byte { + file_dwn_v1_genesis_proto_rawDescOnce.Do(func() { + file_dwn_v1_genesis_proto_rawDescData = protoimpl.X.CompressGZIP(file_dwn_v1_genesis_proto_rawDescData) + }) + return file_dwn_v1_genesis_proto_rawDescData +} + +var file_dwn_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_dwn_v1_genesis_proto_goTypes = []interface{}{ + (*GenesisState)(nil), // 0: dwn.v1.GenesisState + (*Params)(nil), // 1: dwn.v1.Params + (*Schema)(nil), // 2: dwn.v1.Schema +} +var file_dwn_v1_genesis_proto_depIdxs = []int32{ + 1, // 0: dwn.v1.GenesisState.params:type_name -> dwn.v1.Params + 2, // 1: dwn.v1.Params.schema:type_name -> dwn.v1.Schema + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_dwn_v1_genesis_proto_init() } +func file_dwn_v1_genesis_proto_init() { + if File_dwn_v1_genesis_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_dwn_v1_genesis_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GenesisState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_genesis_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Params); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_genesis_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Schema); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dwn_v1_genesis_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_dwn_v1_genesis_proto_goTypes, + DependencyIndexes: file_dwn_v1_genesis_proto_depIdxs, + MessageInfos: file_dwn_v1_genesis_proto_msgTypes, + }.Build() + File_dwn_v1_genesis_proto = out.File + file_dwn_v1_genesis_proto_rawDesc = nil + file_dwn_v1_genesis_proto_goTypes = nil + file_dwn_v1_genesis_proto_depIdxs = nil +} diff --git a/api/dwn/v1/query.pulsar.go b/api/dwn/v1/query.pulsar.go new file mode 100644 index 000000000..e28c752ad --- /dev/null +++ b/api/dwn/v1/query.pulsar.go @@ -0,0 +1,4218 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package dwnv1 + +import ( + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_QueryParamsRequest protoreflect.MessageDescriptor +) + +func init() { + file_dwn_v1_query_proto_init() + md_QueryParamsRequest = File_dwn_v1_query_proto.Messages().ByName("QueryParamsRequest") +} + +var _ protoreflect.Message = (*fastReflection_QueryParamsRequest)(nil) + +type fastReflection_QueryParamsRequest QueryParamsRequest + +func (x *QueryParamsRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryParamsRequest)(x) +} + +func (x *QueryParamsRequest) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_query_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryParamsRequest_messageType fastReflection_QueryParamsRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryParamsRequest_messageType{} + +type fastReflection_QueryParamsRequest_messageType struct{} + +func (x fastReflection_QueryParamsRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryParamsRequest)(nil) +} +func (x fastReflection_QueryParamsRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryParamsRequest) +} +func (x fastReflection_QueryParamsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryParamsRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryParamsRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryParamsRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryParamsRequest) New() protoreflect.Message { + return new(fastReflection_QueryParamsRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryParamsRequest) Interface() protoreflect.ProtoMessage { + return (*QueryParamsRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryParamsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryParamsRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryParamsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryParamsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryParamsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.QueryParamsRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryParamsRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryParamsRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryParamsRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryParamsResponse protoreflect.MessageDescriptor + fd_QueryParamsResponse_params protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_query_proto_init() + md_QueryParamsResponse = File_dwn_v1_query_proto.Messages().ByName("QueryParamsResponse") + fd_QueryParamsResponse_params = md_QueryParamsResponse.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_QueryParamsResponse)(nil) + +type fastReflection_QueryParamsResponse QueryParamsResponse + +func (x *QueryParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryParamsResponse)(x) +} + +func (x *QueryParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_query_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryParamsResponse_messageType fastReflection_QueryParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryParamsResponse_messageType{} + +type fastReflection_QueryParamsResponse_messageType struct{} + +func (x fastReflection_QueryParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryParamsResponse)(nil) +} +func (x fastReflection_QueryParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryParamsResponse) +} +func (x fastReflection_QueryParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryParamsResponse) New() protoreflect.Message { + return new(fastReflection_QueryParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryParamsResponse) Interface() protoreflect.ProtoMessage { + return (*QueryParamsResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_QueryParamsResponse_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.QueryParamsResponse.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.QueryParamsResponse.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.QueryParamsResponse.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.QueryParamsResponse.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QueryParamsResponse.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QueryParamsResponse.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.QueryParamsResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryParamsResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryParamsResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QuerySchemaRequest protoreflect.MessageDescriptor +) + +func init() { + file_dwn_v1_query_proto_init() + md_QuerySchemaRequest = File_dwn_v1_query_proto.Messages().ByName("QuerySchemaRequest") +} + +var _ protoreflect.Message = (*fastReflection_QuerySchemaRequest)(nil) + +type fastReflection_QuerySchemaRequest QuerySchemaRequest + +func (x *QuerySchemaRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QuerySchemaRequest)(x) +} + +func (x *QuerySchemaRequest) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_query_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QuerySchemaRequest_messageType fastReflection_QuerySchemaRequest_messageType +var _ protoreflect.MessageType = fastReflection_QuerySchemaRequest_messageType{} + +type fastReflection_QuerySchemaRequest_messageType struct{} + +func (x fastReflection_QuerySchemaRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QuerySchemaRequest)(nil) +} +func (x fastReflection_QuerySchemaRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QuerySchemaRequest) +} +func (x fastReflection_QuerySchemaRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QuerySchemaRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QuerySchemaRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QuerySchemaRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QuerySchemaRequest) Type() protoreflect.MessageType { + return _fastReflection_QuerySchemaRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QuerySchemaRequest) New() protoreflect.Message { + return new(fastReflection_QuerySchemaRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QuerySchemaRequest) Interface() protoreflect.ProtoMessage { + return (*QuerySchemaRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QuerySchemaRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QuerySchemaRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySchemaRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QuerySchemaRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySchemaRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySchemaRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QuerySchemaRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QuerySchemaRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.QuerySchemaRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QuerySchemaRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySchemaRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QuerySchemaRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QuerySchemaRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QuerySchemaRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QuerySchemaRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QuerySchemaRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySchemaRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySchemaRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QuerySchemaResponse protoreflect.MessageDescriptor + fd_QuerySchemaResponse_schema protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_query_proto_init() + md_QuerySchemaResponse = File_dwn_v1_query_proto.Messages().ByName("QuerySchemaResponse") + fd_QuerySchemaResponse_schema = md_QuerySchemaResponse.Fields().ByName("schema") +} + +var _ protoreflect.Message = (*fastReflection_QuerySchemaResponse)(nil) + +type fastReflection_QuerySchemaResponse QuerySchemaResponse + +func (x *QuerySchemaResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QuerySchemaResponse)(x) +} + +func (x *QuerySchemaResponse) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_query_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QuerySchemaResponse_messageType fastReflection_QuerySchemaResponse_messageType +var _ protoreflect.MessageType = fastReflection_QuerySchemaResponse_messageType{} + +type fastReflection_QuerySchemaResponse_messageType struct{} + +func (x fastReflection_QuerySchemaResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QuerySchemaResponse)(nil) +} +func (x fastReflection_QuerySchemaResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QuerySchemaResponse) +} +func (x fastReflection_QuerySchemaResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QuerySchemaResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QuerySchemaResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QuerySchemaResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QuerySchemaResponse) Type() protoreflect.MessageType { + return _fastReflection_QuerySchemaResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QuerySchemaResponse) New() protoreflect.Message { + return new(fastReflection_QuerySchemaResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QuerySchemaResponse) Interface() protoreflect.ProtoMessage { + return (*QuerySchemaResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QuerySchemaResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Schema != nil { + value := protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) + if !f(fd_QuerySchemaResponse_schema, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QuerySchemaResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.QuerySchemaResponse.schema": + return x.Schema != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySchemaResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.QuerySchemaResponse.schema": + x.Schema = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QuerySchemaResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.QuerySchemaResponse.schema": + value := x.Schema + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySchemaResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.QuerySchemaResponse.schema": + x.Schema = value.Message().Interface().(*Schema) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySchemaResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QuerySchemaResponse.schema": + if x.Schema == nil { + x.Schema = new(Schema) + } + return protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QuerySchemaResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QuerySchemaResponse.schema": + m := new(Schema) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySchemaResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QuerySchemaResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.QuerySchemaResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QuerySchemaResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySchemaResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QuerySchemaResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QuerySchemaResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QuerySchemaResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Schema != nil { + l = options.Size(x.Schema) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QuerySchemaResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Schema != nil { + encoded, err := options.Marshal(x.Schema) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QuerySchemaResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySchemaResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySchemaResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Schema == nil { + x.Schema = &Schema{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Schema); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryAllocateRequest protoreflect.MessageDescriptor +) + +func init() { + file_dwn_v1_query_proto_init() + md_QueryAllocateRequest = File_dwn_v1_query_proto.Messages().ByName("QueryAllocateRequest") +} + +var _ protoreflect.Message = (*fastReflection_QueryAllocateRequest)(nil) + +type fastReflection_QueryAllocateRequest QueryAllocateRequest + +func (x *QueryAllocateRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryAllocateRequest)(x) +} + +func (x *QueryAllocateRequest) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_query_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryAllocateRequest_messageType fastReflection_QueryAllocateRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryAllocateRequest_messageType{} + +type fastReflection_QueryAllocateRequest_messageType struct{} + +func (x fastReflection_QueryAllocateRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryAllocateRequest)(nil) +} +func (x fastReflection_QueryAllocateRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryAllocateRequest) +} +func (x fastReflection_QueryAllocateRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryAllocateRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryAllocateRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryAllocateRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryAllocateRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryAllocateRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryAllocateRequest) New() protoreflect.Message { + return new(fastReflection_QueryAllocateRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryAllocateRequest) Interface() protoreflect.ProtoMessage { + return (*QueryAllocateRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryAllocateRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryAllocateRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllocateRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryAllocateRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllocateRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllocateRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryAllocateRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateRequest")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryAllocateRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.QueryAllocateRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryAllocateRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllocateRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryAllocateRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryAllocateRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryAllocateRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryAllocateRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryAllocateRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllocateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllocateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryAllocateResponse protoreflect.MessageDescriptor + fd_QueryAllocateResponse_success protoreflect.FieldDescriptor + fd_QueryAllocateResponse_cid protoreflect.FieldDescriptor + fd_QueryAllocateResponse_macaroon protoreflect.FieldDescriptor + fd_QueryAllocateResponse_public_uri protoreflect.FieldDescriptor + fd_QueryAllocateResponse_expiry_block protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_query_proto_init() + md_QueryAllocateResponse = File_dwn_v1_query_proto.Messages().ByName("QueryAllocateResponse") + fd_QueryAllocateResponse_success = md_QueryAllocateResponse.Fields().ByName("success") + fd_QueryAllocateResponse_cid = md_QueryAllocateResponse.Fields().ByName("cid") + fd_QueryAllocateResponse_macaroon = md_QueryAllocateResponse.Fields().ByName("macaroon") + fd_QueryAllocateResponse_public_uri = md_QueryAllocateResponse.Fields().ByName("public_uri") + fd_QueryAllocateResponse_expiry_block = md_QueryAllocateResponse.Fields().ByName("expiry_block") +} + +var _ protoreflect.Message = (*fastReflection_QueryAllocateResponse)(nil) + +type fastReflection_QueryAllocateResponse QueryAllocateResponse + +func (x *QueryAllocateResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryAllocateResponse)(x) +} + +func (x *QueryAllocateResponse) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_query_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryAllocateResponse_messageType fastReflection_QueryAllocateResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryAllocateResponse_messageType{} + +type fastReflection_QueryAllocateResponse_messageType struct{} + +func (x fastReflection_QueryAllocateResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryAllocateResponse)(nil) +} +func (x fastReflection_QueryAllocateResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryAllocateResponse) +} +func (x fastReflection_QueryAllocateResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryAllocateResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryAllocateResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryAllocateResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryAllocateResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryAllocateResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryAllocateResponse) New() protoreflect.Message { + return new(fastReflection_QueryAllocateResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryAllocateResponse) Interface() protoreflect.ProtoMessage { + return (*QueryAllocateResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryAllocateResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Success != false { + value := protoreflect.ValueOfBool(x.Success) + if !f(fd_QueryAllocateResponse_success, value) { + return + } + } + if x.Cid != "" { + value := protoreflect.ValueOfString(x.Cid) + if !f(fd_QueryAllocateResponse_cid, value) { + return + } + } + if x.Macaroon != "" { + value := protoreflect.ValueOfString(x.Macaroon) + if !f(fd_QueryAllocateResponse_macaroon, value) { + return + } + } + if x.PublicUri != "" { + value := protoreflect.ValueOfString(x.PublicUri) + if !f(fd_QueryAllocateResponse_public_uri, value) { + return + } + } + if x.ExpiryBlock != int64(0) { + value := protoreflect.ValueOfInt64(x.ExpiryBlock) + if !f(fd_QueryAllocateResponse_expiry_block, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryAllocateResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.QueryAllocateResponse.success": + return x.Success != false + case "dwn.v1.QueryAllocateResponse.cid": + return x.Cid != "" + case "dwn.v1.QueryAllocateResponse.macaroon": + return x.Macaroon != "" + case "dwn.v1.QueryAllocateResponse.public_uri": + return x.PublicUri != "" + case "dwn.v1.QueryAllocateResponse.expiry_block": + return x.ExpiryBlock != int64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllocateResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.QueryAllocateResponse.success": + x.Success = false + case "dwn.v1.QueryAllocateResponse.cid": + x.Cid = "" + case "dwn.v1.QueryAllocateResponse.macaroon": + x.Macaroon = "" + case "dwn.v1.QueryAllocateResponse.public_uri": + x.PublicUri = "" + case "dwn.v1.QueryAllocateResponse.expiry_block": + x.ExpiryBlock = int64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryAllocateResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.QueryAllocateResponse.success": + value := x.Success + return protoreflect.ValueOfBool(value) + case "dwn.v1.QueryAllocateResponse.cid": + value := x.Cid + return protoreflect.ValueOfString(value) + case "dwn.v1.QueryAllocateResponse.macaroon": + value := x.Macaroon + return protoreflect.ValueOfString(value) + case "dwn.v1.QueryAllocateResponse.public_uri": + value := x.PublicUri + return protoreflect.ValueOfString(value) + case "dwn.v1.QueryAllocateResponse.expiry_block": + value := x.ExpiryBlock + return protoreflect.ValueOfInt64(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllocateResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.QueryAllocateResponse.success": + x.Success = value.Bool() + case "dwn.v1.QueryAllocateResponse.cid": + x.Cid = value.Interface().(string) + case "dwn.v1.QueryAllocateResponse.macaroon": + x.Macaroon = value.Interface().(string) + case "dwn.v1.QueryAllocateResponse.public_uri": + x.PublicUri = value.Interface().(string) + case "dwn.v1.QueryAllocateResponse.expiry_block": + x.ExpiryBlock = value.Int() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllocateResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QueryAllocateResponse.success": + panic(fmt.Errorf("field success of message dwn.v1.QueryAllocateResponse is not mutable")) + case "dwn.v1.QueryAllocateResponse.cid": + panic(fmt.Errorf("field cid of message dwn.v1.QueryAllocateResponse is not mutable")) + case "dwn.v1.QueryAllocateResponse.macaroon": + panic(fmt.Errorf("field macaroon of message dwn.v1.QueryAllocateResponse is not mutable")) + case "dwn.v1.QueryAllocateResponse.public_uri": + panic(fmt.Errorf("field public_uri of message dwn.v1.QueryAllocateResponse is not mutable")) + case "dwn.v1.QueryAllocateResponse.expiry_block": + panic(fmt.Errorf("field expiry_block of message dwn.v1.QueryAllocateResponse is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryAllocateResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QueryAllocateResponse.success": + return protoreflect.ValueOfBool(false) + case "dwn.v1.QueryAllocateResponse.cid": + return protoreflect.ValueOfString("") + case "dwn.v1.QueryAllocateResponse.macaroon": + return protoreflect.ValueOfString("") + case "dwn.v1.QueryAllocateResponse.public_uri": + return protoreflect.ValueOfString("") + case "dwn.v1.QueryAllocateResponse.expiry_block": + return protoreflect.ValueOfInt64(int64(0)) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QueryAllocateResponse")) + } + panic(fmt.Errorf("message dwn.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryAllocateResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.QueryAllocateResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryAllocateResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllocateResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryAllocateResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryAllocateResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryAllocateResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Success { + n += 2 + } + l = len(x.Cid) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Macaroon) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.PublicUri) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.ExpiryBlock != 0 { + n += 1 + runtime.Sov(uint64(x.ExpiryBlock)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryAllocateResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.ExpiryBlock != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryBlock)) + i-- + dAtA[i] = 0x28 + } + if len(x.PublicUri) > 0 { + i -= len(x.PublicUri) + copy(dAtA[i:], x.PublicUri) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicUri))) + i-- + dAtA[i] = 0x22 + } + if len(x.Macaroon) > 0 { + i -= len(x.Macaroon) + copy(dAtA[i:], x.Macaroon) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Macaroon))) + i-- + dAtA[i] = 0x1a + } + if len(x.Cid) > 0 { + i -= len(x.Cid) + copy(dAtA[i:], x.Cid) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Cid))) + i-- + dAtA[i] = 0x12 + } + if x.Success { + i-- + if x.Success { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryAllocateResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllocateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllocateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.Success = bool(v != 0) + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Cid", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Cid = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Macaroon", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Macaroon = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicUri", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PublicUri = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryBlock", wireType) + } + x.ExpiryBlock = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.ExpiryBlock |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QuerySyncRequest protoreflect.MessageDescriptor + fd_QuerySyncRequest_did protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_query_proto_init() + md_QuerySyncRequest = File_dwn_v1_query_proto.Messages().ByName("QuerySyncRequest") + fd_QuerySyncRequest_did = md_QuerySyncRequest.Fields().ByName("did") +} + +var _ protoreflect.Message = (*fastReflection_QuerySyncRequest)(nil) + +type fastReflection_QuerySyncRequest QuerySyncRequest + +func (x *QuerySyncRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QuerySyncRequest)(x) +} + +func (x *QuerySyncRequest) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_query_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QuerySyncRequest_messageType fastReflection_QuerySyncRequest_messageType +var _ protoreflect.MessageType = fastReflection_QuerySyncRequest_messageType{} + +type fastReflection_QuerySyncRequest_messageType struct{} + +func (x fastReflection_QuerySyncRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QuerySyncRequest)(nil) +} +func (x fastReflection_QuerySyncRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QuerySyncRequest) +} +func (x fastReflection_QuerySyncRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QuerySyncRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QuerySyncRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QuerySyncRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QuerySyncRequest) Type() protoreflect.MessageType { + return _fastReflection_QuerySyncRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QuerySyncRequest) New() protoreflect.Message { + return new(fastReflection_QuerySyncRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QuerySyncRequest) Interface() protoreflect.ProtoMessage { + return (*QuerySyncRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QuerySyncRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Did != "" { + value := protoreflect.ValueOfString(x.Did) + if !f(fd_QuerySyncRequest_did, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QuerySyncRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.QuerySyncRequest.did": + return x.Did != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySyncRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.QuerySyncRequest.did": + x.Did = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QuerySyncRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.QuerySyncRequest.did": + value := x.Did + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySyncRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.QuerySyncRequest.did": + x.Did = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySyncRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QuerySyncRequest.did": + panic(fmt.Errorf("field did of message dwn.v1.QuerySyncRequest is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QuerySyncRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QuerySyncRequest.did": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncRequest")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QuerySyncRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.QuerySyncRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QuerySyncRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySyncRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QuerySyncRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QuerySyncRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QuerySyncRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Did) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QuerySyncRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Did) > 0 { + i -= len(x.Did) + copy(dAtA[i:], x.Did) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Did))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QuerySyncRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySyncRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySyncRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Did", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Did = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QuerySyncResponse protoreflect.MessageDescriptor + fd_QuerySyncResponse_success protoreflect.FieldDescriptor + fd_QuerySyncResponse_schema protoreflect.FieldDescriptor + fd_QuerySyncResponse_address protoreflect.FieldDescriptor + fd_QuerySyncResponse_chainID protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_query_proto_init() + md_QuerySyncResponse = File_dwn_v1_query_proto.Messages().ByName("QuerySyncResponse") + fd_QuerySyncResponse_success = md_QuerySyncResponse.Fields().ByName("success") + fd_QuerySyncResponse_schema = md_QuerySyncResponse.Fields().ByName("schema") + fd_QuerySyncResponse_address = md_QuerySyncResponse.Fields().ByName("address") + fd_QuerySyncResponse_chainID = md_QuerySyncResponse.Fields().ByName("chainID") +} + +var _ protoreflect.Message = (*fastReflection_QuerySyncResponse)(nil) + +type fastReflection_QuerySyncResponse QuerySyncResponse + +func (x *QuerySyncResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QuerySyncResponse)(x) +} + +func (x *QuerySyncResponse) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_query_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QuerySyncResponse_messageType fastReflection_QuerySyncResponse_messageType +var _ protoreflect.MessageType = fastReflection_QuerySyncResponse_messageType{} + +type fastReflection_QuerySyncResponse_messageType struct{} + +func (x fastReflection_QuerySyncResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QuerySyncResponse)(nil) +} +func (x fastReflection_QuerySyncResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QuerySyncResponse) +} +func (x fastReflection_QuerySyncResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QuerySyncResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QuerySyncResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QuerySyncResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QuerySyncResponse) Type() protoreflect.MessageType { + return _fastReflection_QuerySyncResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QuerySyncResponse) New() protoreflect.Message { + return new(fastReflection_QuerySyncResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QuerySyncResponse) Interface() protoreflect.ProtoMessage { + return (*QuerySyncResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QuerySyncResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Success != false { + value := protoreflect.ValueOfBool(x.Success) + if !f(fd_QuerySyncResponse_success, value) { + return + } + } + if x.Schema != nil { + value := protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) + if !f(fd_QuerySyncResponse_schema, value) { + return + } + } + if x.Address != "" { + value := protoreflect.ValueOfString(x.Address) + if !f(fd_QuerySyncResponse_address, value) { + return + } + } + if x.ChainID != "" { + value := protoreflect.ValueOfString(x.ChainID) + if !f(fd_QuerySyncResponse_chainID, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QuerySyncResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.QuerySyncResponse.success": + return x.Success != false + case "dwn.v1.QuerySyncResponse.schema": + return x.Schema != nil + case "dwn.v1.QuerySyncResponse.address": + return x.Address != "" + case "dwn.v1.QuerySyncResponse.chainID": + return x.ChainID != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySyncResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.QuerySyncResponse.success": + x.Success = false + case "dwn.v1.QuerySyncResponse.schema": + x.Schema = nil + case "dwn.v1.QuerySyncResponse.address": + x.Address = "" + case "dwn.v1.QuerySyncResponse.chainID": + x.ChainID = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QuerySyncResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.QuerySyncResponse.success": + value := x.Success + return protoreflect.ValueOfBool(value) + case "dwn.v1.QuerySyncResponse.schema": + value := x.Schema + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "dwn.v1.QuerySyncResponse.address": + value := x.Address + return protoreflect.ValueOfString(value) + case "dwn.v1.QuerySyncResponse.chainID": + value := x.ChainID + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySyncResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.QuerySyncResponse.success": + x.Success = value.Bool() + case "dwn.v1.QuerySyncResponse.schema": + x.Schema = value.Message().Interface().(*Schema) + case "dwn.v1.QuerySyncResponse.address": + x.Address = value.Interface().(string) + case "dwn.v1.QuerySyncResponse.chainID": + x.ChainID = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySyncResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QuerySyncResponse.schema": + if x.Schema == nil { + x.Schema = new(Schema) + } + return protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) + case "dwn.v1.QuerySyncResponse.success": + panic(fmt.Errorf("field success of message dwn.v1.QuerySyncResponse is not mutable")) + case "dwn.v1.QuerySyncResponse.address": + panic(fmt.Errorf("field address of message dwn.v1.QuerySyncResponse is not mutable")) + case "dwn.v1.QuerySyncResponse.chainID": + panic(fmt.Errorf("field chainID of message dwn.v1.QuerySyncResponse is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QuerySyncResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.QuerySyncResponse.success": + return protoreflect.ValueOfBool(false) + case "dwn.v1.QuerySyncResponse.schema": + m := new(Schema) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "dwn.v1.QuerySyncResponse.address": + return protoreflect.ValueOfString("") + case "dwn.v1.QuerySyncResponse.chainID": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.QuerySyncResponse")) + } + panic(fmt.Errorf("message dwn.v1.QuerySyncResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QuerySyncResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.QuerySyncResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QuerySyncResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QuerySyncResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QuerySyncResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QuerySyncResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QuerySyncResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Success { + n += 2 + } + if x.Schema != nil { + l = options.Size(x.Schema) + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Address) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.ChainID) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QuerySyncResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.ChainID) > 0 { + i -= len(x.ChainID) + copy(dAtA[i:], x.ChainID) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ChainID))) + i-- + dAtA[i] = 0x22 + } + if len(x.Address) > 0 { + i -= len(x.Address) + copy(dAtA[i:], x.Address) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Address))) + i-- + dAtA[i] = 0x1a + } + if x.Schema != nil { + encoded, err := options.Marshal(x.Schema) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if x.Success { + i-- + if x.Success { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QuerySyncResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySyncResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySyncResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.Success = bool(v != 0) + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Schema == nil { + x.Schema = &Schema{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Schema); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ChainID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.ChainID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: dwn/v1/query.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *QueryParamsRequest) Reset() { + *x = QueryParamsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_query_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryParamsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryParamsRequest) ProtoMessage() {} + +// Deprecated: Use QueryParamsRequest.ProtoReflect.Descriptor instead. +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return file_dwn_v1_query_proto_rawDescGZIP(), []int{0} +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // params defines the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *QueryParamsResponse) Reset() { + *x = QueryParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_query_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryParamsResponse) ProtoMessage() {} + +// Deprecated: Use QueryParamsResponse.ProtoReflect.Descriptor instead. +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return file_dwn_v1_query_proto_rawDescGZIP(), []int{1} +} + +func (x *QueryParamsResponse) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// QuerySchemaRequest is the request type for the Query/Schema RPC method. +type QuerySchemaRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *QuerySchemaRequest) Reset() { + *x = QuerySchemaRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_query_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QuerySchemaRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuerySchemaRequest) ProtoMessage() {} + +// Deprecated: Use QuerySchemaRequest.ProtoReflect.Descriptor instead. +func (*QuerySchemaRequest) Descriptor() ([]byte, []int) { + return file_dwn_v1_query_proto_rawDescGZIP(), []int{2} +} + +// QuerySchemaResponse is the response type for the Query/Schema RPC method. +type QuerySchemaResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Schema is the DID document. + Schema *Schema `protobuf:"bytes,1,opt,name=schema,proto3" json:"schema,omitempty"` +} + +func (x *QuerySchemaResponse) Reset() { + *x = QuerySchemaResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_query_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QuerySchemaResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuerySchemaResponse) ProtoMessage() {} + +// Deprecated: Use QuerySchemaResponse.ProtoReflect.Descriptor instead. +func (*QuerySchemaResponse) Descriptor() ([]byte, []int) { + return file_dwn_v1_query_proto_rawDescGZIP(), []int{3} +} + +func (x *QuerySchemaResponse) GetSchema() *Schema { + if x != nil { + return x.Schema + } + return nil +} + +// QueryAllocateRequest is the request type for the Allocate RPC method. +type QueryAllocateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *QueryAllocateRequest) Reset() { + *x = QueryAllocateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_query_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryAllocateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAllocateRequest) ProtoMessage() {} + +// Deprecated: Use QueryAllocateRequest.ProtoReflect.Descriptor instead. +func (*QueryAllocateRequest) Descriptor() ([]byte, []int) { + return file_dwn_v1_query_proto_rawDescGZIP(), []int{4} +} + +// AllocateResponse is the response type for the Allocate RPC method. +type QueryAllocateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Cid string `protobuf:"bytes,2,opt,name=cid,proto3" json:"cid,omitempty"` + Macaroon string `protobuf:"bytes,3,opt,name=macaroon,proto3" json:"macaroon,omitempty"` + PublicUri string `protobuf:"bytes,4,opt,name=public_uri,json=publicUri,proto3" json:"public_uri,omitempty"` + ExpiryBlock int64 `protobuf:"varint,5,opt,name=expiry_block,json=expiryBlock,proto3" json:"expiry_block,omitempty"` +} + +func (x *QueryAllocateResponse) Reset() { + *x = QueryAllocateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_query_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryAllocateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAllocateResponse) ProtoMessage() {} + +// Deprecated: Use QueryAllocateResponse.ProtoReflect.Descriptor instead. +func (*QueryAllocateResponse) Descriptor() ([]byte, []int) { + return file_dwn_v1_query_proto_rawDescGZIP(), []int{5} +} + +func (x *QueryAllocateResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *QueryAllocateResponse) GetCid() string { + if x != nil { + return x.Cid + } + return "" +} + +func (x *QueryAllocateResponse) GetMacaroon() string { + if x != nil { + return x.Macaroon + } + return "" +} + +func (x *QueryAllocateResponse) GetPublicUri() string { + if x != nil { + return x.PublicUri + } + return "" +} + +func (x *QueryAllocateResponse) GetExpiryBlock() int64 { + if x != nil { + return x.ExpiryBlock + } + return 0 +} + +// SyncRequest is the request type for the Sync RPC method. +type QuerySyncRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Did string `protobuf:"bytes,1,opt,name=did,proto3" json:"did,omitempty"` +} + +func (x *QuerySyncRequest) Reset() { + *x = QuerySyncRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_query_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QuerySyncRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuerySyncRequest) ProtoMessage() {} + +// Deprecated: Use QuerySyncRequest.ProtoReflect.Descriptor instead. +func (*QuerySyncRequest) Descriptor() ([]byte, []int) { + return file_dwn_v1_query_proto_rawDescGZIP(), []int{6} +} + +func (x *QuerySyncRequest) GetDid() string { + if x != nil { + return x.Did + } + return "" +} + +// SyncResponse is the response type for the Sync RPC method. +type QuerySyncResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + // Schema is the DID document. + Schema *Schema `protobuf:"bytes,2,opt,name=schema,proto3" json:"schema,omitempty"` + // Address is the address of the calling DID. + Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` + // ChainID is the chain ID of the current network. + ChainID string `protobuf:"bytes,4,opt,name=chainID,proto3" json:"chainID,omitempty"` +} + +func (x *QuerySyncResponse) Reset() { + *x = QuerySyncResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_query_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QuerySyncResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuerySyncResponse) ProtoMessage() {} + +// Deprecated: Use QuerySyncResponse.ProtoReflect.Descriptor instead. +func (*QuerySyncResponse) Descriptor() ([]byte, []int) { + return file_dwn_v1_query_proto_rawDescGZIP(), []int{7} +} + +func (x *QuerySyncResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *QuerySyncResponse) GetSchema() *Schema { + if x != nil { + return x.Schema + } + return nil +} + +func (x *QuerySyncResponse) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *QuerySyncResponse) GetChainID() string { + if x != nil { + return x.ChainID + } + return "" +} + +var File_dwn_v1_query_proto protoreflect.FileDescriptor + +var file_dwn_v1_query_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x64, 0x77, 0x6e, 0x2f, + 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x14, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, + 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x13, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x16, 0x0a, 0x14, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x75, + 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x55, 0x72, 0x69, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x79, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x24, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, + 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0x89, 0x01, 0x0a, + 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x26, 0x0a, 0x06, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, + 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x32, 0xfb, 0x02, 0x0a, 0x05, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x5b, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1a, 0x2e, 0x64, + 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, + 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x5b, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1a, 0x2e, 0x64, 0x77, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x61, 0x75, + 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x63, 0x0a, 0x08, + 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, + 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x65, 0x12, 0x53, 0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x18, 0x2e, 0x64, 0x77, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, + 0x31, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x77, + 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, + 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, + 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, + 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, 0x6e, + 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_dwn_v1_query_proto_rawDescOnce sync.Once + file_dwn_v1_query_proto_rawDescData = file_dwn_v1_query_proto_rawDesc +) + +func file_dwn_v1_query_proto_rawDescGZIP() []byte { + file_dwn_v1_query_proto_rawDescOnce.Do(func() { + file_dwn_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_dwn_v1_query_proto_rawDescData) + }) + return file_dwn_v1_query_proto_rawDescData +} + +var file_dwn_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_dwn_v1_query_proto_goTypes = []interface{}{ + (*QueryParamsRequest)(nil), // 0: dwn.v1.QueryParamsRequest + (*QueryParamsResponse)(nil), // 1: dwn.v1.QueryParamsResponse + (*QuerySchemaRequest)(nil), // 2: dwn.v1.QuerySchemaRequest + (*QuerySchemaResponse)(nil), // 3: dwn.v1.QuerySchemaResponse + (*QueryAllocateRequest)(nil), // 4: dwn.v1.QueryAllocateRequest + (*QueryAllocateResponse)(nil), // 5: dwn.v1.QueryAllocateResponse + (*QuerySyncRequest)(nil), // 6: dwn.v1.QuerySyncRequest + (*QuerySyncResponse)(nil), // 7: dwn.v1.QuerySyncResponse + (*Params)(nil), // 8: dwn.v1.Params + (*Schema)(nil), // 9: dwn.v1.Schema +} +var file_dwn_v1_query_proto_depIdxs = []int32{ + 8, // 0: dwn.v1.QueryParamsResponse.params:type_name -> dwn.v1.Params + 9, // 1: dwn.v1.QuerySchemaResponse.schema:type_name -> dwn.v1.Schema + 9, // 2: dwn.v1.QuerySyncResponse.schema:type_name -> dwn.v1.Schema + 0, // 3: dwn.v1.Query.Params:input_type -> dwn.v1.QueryParamsRequest + 2, // 4: dwn.v1.Query.Schema:input_type -> dwn.v1.QuerySchemaRequest + 4, // 5: dwn.v1.Query.Allocate:input_type -> dwn.v1.QueryAllocateRequest + 6, // 6: dwn.v1.Query.Sync:input_type -> dwn.v1.QuerySyncRequest + 1, // 7: dwn.v1.Query.Params:output_type -> dwn.v1.QueryParamsResponse + 3, // 8: dwn.v1.Query.Schema:output_type -> dwn.v1.QuerySchemaResponse + 5, // 9: dwn.v1.Query.Allocate:output_type -> dwn.v1.QueryAllocateResponse + 7, // 10: dwn.v1.Query.Sync:output_type -> dwn.v1.QuerySyncResponse + 7, // [7:11] is the sub-list for method output_type + 3, // [3:7] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_dwn_v1_query_proto_init() } +func file_dwn_v1_query_proto_init() { + if File_dwn_v1_query_proto != nil { + return + } + file_dwn_v1_genesis_proto_init() + if !protoimpl.UnsafeEnabled { + file_dwn_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryParamsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryParamsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuerySchemaRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuerySchemaResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryAllocateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryAllocateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_query_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuerySyncRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_query_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuerySyncResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dwn_v1_query_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_dwn_v1_query_proto_goTypes, + DependencyIndexes: file_dwn_v1_query_proto_depIdxs, + MessageInfos: file_dwn_v1_query_proto_msgTypes, + }.Build() + File_dwn_v1_query_proto = out.File + file_dwn_v1_query_proto_rawDesc = nil + file_dwn_v1_query_proto_goTypes = nil + file_dwn_v1_query_proto_depIdxs = nil +} diff --git a/api/dwn/v1/query_grpc.pb.go b/api/dwn/v1/query_grpc.pb.go new file mode 100644 index 000000000..00eca0d77 --- /dev/null +++ b/api/dwn/v1/query_grpc.pb.go @@ -0,0 +1,253 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: dwn/v1/query.proto + +package dwnv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Query_Params_FullMethodName = "/dwn.v1.Query/Params" + Query_Schema_FullMethodName = "/dwn.v1.Query/Schema" + Query_Allocate_FullMethodName = "/dwn.v1.Query/Allocate" + Query_Sync_FullMethodName = "/dwn.v1.Query/Sync" +) + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// Query provides defines the gRPC querier service. +type QueryClient interface { + // Params queries all parameters of the module. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // Schema queries the DID document by its id. And returns the required PKL + // information + Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error) + // Allocate initializes a Target Vault available for claims with a compatible + // Authentication mechanism. The default authentication mechanism is WebAuthn. + Allocate(ctx context.Context, in *QueryAllocateRequest, opts ...grpc.CallOption) (*QueryAllocateResponse, error) + // Sync queries the DID document by its id. And returns the required PKL + // information + Sync(ctx context.Context, in *QuerySyncRequest, opts ...grpc.CallOption) (*QuerySyncResponse, error) +} + +type queryClient struct { + cc grpc.ClientConnInterface +} + +func NewQueryClient(cc grpc.ClientConnInterface) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, Query_Params_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QuerySchemaResponse) + err := c.cc.Invoke(ctx, Query_Schema_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Allocate(ctx context.Context, in *QueryAllocateRequest, opts ...grpc.CallOption) (*QueryAllocateResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryAllocateResponse) + err := c.cc.Invoke(ctx, Query_Allocate_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Sync(ctx context.Context, in *QuerySyncRequest, opts ...grpc.CallOption) (*QuerySyncResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QuerySyncResponse) + err := c.cc.Invoke(ctx, Query_Sync_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +// All implementations must embed UnimplementedQueryServer +// for forward compatibility. +// +// Query provides defines the gRPC querier service. +type QueryServer interface { + // Params queries all parameters of the module. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // Schema queries the DID document by its id. And returns the required PKL + // information + Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) + // Allocate initializes a Target Vault available for claims with a compatible + // Authentication mechanism. The default authentication mechanism is WebAuthn. + Allocate(context.Context, *QueryAllocateRequest) (*QueryAllocateResponse, error) + // Sync queries the DID document by its id. And returns the required PKL + // information + Sync(context.Context, *QuerySyncRequest) (*QuerySyncResponse, error) + mustEmbedUnimplementedQueryServer() +} + +// UnimplementedQueryServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedQueryServer struct{} + +func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (UnimplementedQueryServer) Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Schema not implemented") +} +func (UnimplementedQueryServer) Allocate(context.Context, *QueryAllocateRequest) (*QueryAllocateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Allocate not implemented") +} +func (UnimplementedQueryServer) Sync(context.Context, *QuerySyncRequest) (*QuerySyncResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Sync not implemented") +} +func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {} +func (UnimplementedQueryServer) testEmbeddedByValue() {} + +// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to QueryServer will +// result in compilation errors. +type UnsafeQueryServer interface { + mustEmbedUnimplementedQueryServer() +} + +func RegisterQueryServer(s grpc.ServiceRegistrar, srv QueryServer) { + // If the following call pancis, it indicates UnimplementedQueryServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Query_ServiceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_Params_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Schema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySchemaRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Schema(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_Schema_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Schema(ctx, req.(*QuerySchemaRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Allocate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllocateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Allocate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_Allocate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Allocate(ctx, req.(*QueryAllocateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Sync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySyncRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Sync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_Sync_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Sync(ctx, req.(*QuerySyncRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Query_ServiceDesc is the grpc.ServiceDesc for Query service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Query_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "dwn.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "Schema", + Handler: _Query_Schema_Handler, + }, + { + MethodName: "Allocate", + Handler: _Query_Allocate_Handler, + }, + { + MethodName: "Sync", + Handler: _Query_Sync_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dwn/v1/query.proto", +} diff --git a/api/dwn/v1/state.cosmos_orm.go b/api/dwn/v1/state.cosmos_orm.go new file mode 100644 index 000000000..8bf5048fc --- /dev/null +++ b/api/dwn/v1/state.cosmos_orm.go @@ -0,0 +1,166 @@ +// Code generated by protoc-gen-go-cosmos-orm. DO NOT EDIT. + +package dwnv1 + +import ( + context "context" + ormlist "cosmossdk.io/orm/model/ormlist" + ormtable "cosmossdk.io/orm/model/ormtable" + ormerrors "cosmossdk.io/orm/types/ormerrors" +) + +type ExampleDataTable interface { + Insert(ctx context.Context, exampleData *ExampleData) error + Update(ctx context.Context, exampleData *ExampleData) error + Save(ctx context.Context, exampleData *ExampleData) error + Delete(ctx context.Context, exampleData *ExampleData) error + Has(ctx context.Context, account []byte) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, account []byte) (*ExampleData, error) + List(ctx context.Context, prefixKey ExampleDataIndexKey, opts ...ormlist.Option) (ExampleDataIterator, error) + ListRange(ctx context.Context, from, to ExampleDataIndexKey, opts ...ormlist.Option) (ExampleDataIterator, error) + DeleteBy(ctx context.Context, prefixKey ExampleDataIndexKey) error + DeleteRange(ctx context.Context, from, to ExampleDataIndexKey) error + + doNotImplement() +} + +type ExampleDataIterator struct { + ormtable.Iterator +} + +func (i ExampleDataIterator) Value() (*ExampleData, error) { + var exampleData ExampleData + err := i.UnmarshalMessage(&exampleData) + return &exampleData, err +} + +type ExampleDataIndexKey interface { + id() uint32 + values() []interface{} + exampleDataIndexKey() +} + +// primary key starting index.. +type ExampleDataPrimaryKey = ExampleDataAccountIndexKey + +type ExampleDataAccountIndexKey struct { + vs []interface{} +} + +func (x ExampleDataAccountIndexKey) id() uint32 { return 0 } +func (x ExampleDataAccountIndexKey) values() []interface{} { return x.vs } +func (x ExampleDataAccountIndexKey) exampleDataIndexKey() {} + +func (this ExampleDataAccountIndexKey) WithAccount(account []byte) ExampleDataAccountIndexKey { + this.vs = []interface{}{account} + return this +} + +type ExampleDataAmountIndexKey struct { + vs []interface{} +} + +func (x ExampleDataAmountIndexKey) id() uint32 { return 1 } +func (x ExampleDataAmountIndexKey) values() []interface{} { return x.vs } +func (x ExampleDataAmountIndexKey) exampleDataIndexKey() {} + +func (this ExampleDataAmountIndexKey) WithAmount(amount uint64) ExampleDataAmountIndexKey { + this.vs = []interface{}{amount} + return this +} + +type exampleDataTable struct { + table ormtable.Table +} + +func (this exampleDataTable) Insert(ctx context.Context, exampleData *ExampleData) error { + return this.table.Insert(ctx, exampleData) +} + +func (this exampleDataTable) Update(ctx context.Context, exampleData *ExampleData) error { + return this.table.Update(ctx, exampleData) +} + +func (this exampleDataTable) Save(ctx context.Context, exampleData *ExampleData) error { + return this.table.Save(ctx, exampleData) +} + +func (this exampleDataTable) Delete(ctx context.Context, exampleData *ExampleData) error { + return this.table.Delete(ctx, exampleData) +} + +func (this exampleDataTable) Has(ctx context.Context, account []byte) (found bool, err error) { + return this.table.PrimaryKey().Has(ctx, account) +} + +func (this exampleDataTable) Get(ctx context.Context, account []byte) (*ExampleData, error) { + var exampleData ExampleData + found, err := this.table.PrimaryKey().Get(ctx, &exampleData, account) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &exampleData, nil +} + +func (this exampleDataTable) List(ctx context.Context, prefixKey ExampleDataIndexKey, opts ...ormlist.Option) (ExampleDataIterator, error) { + it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) + return ExampleDataIterator{it}, err +} + +func (this exampleDataTable) ListRange(ctx context.Context, from, to ExampleDataIndexKey, opts ...ormlist.Option) (ExampleDataIterator, error) { + it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) + return ExampleDataIterator{it}, err +} + +func (this exampleDataTable) DeleteBy(ctx context.Context, prefixKey ExampleDataIndexKey) error { + return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) +} + +func (this exampleDataTable) DeleteRange(ctx context.Context, from, to ExampleDataIndexKey) error { + return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) +} + +func (this exampleDataTable) doNotImplement() {} + +var _ ExampleDataTable = exampleDataTable{} + +func NewExampleDataTable(db ormtable.Schema) (ExampleDataTable, error) { + table := db.GetTable(&ExampleData{}) + if table == nil { + return nil, ormerrors.TableNotFound.Wrap(string((&ExampleData{}).ProtoReflect().Descriptor().FullName())) + } + return exampleDataTable{table}, nil +} + +type StateStore interface { + ExampleDataTable() ExampleDataTable + + doNotImplement() +} + +type stateStore struct { + exampleData ExampleDataTable +} + +func (x stateStore) ExampleDataTable() ExampleDataTable { + return x.exampleData +} + +func (stateStore) doNotImplement() {} + +var _ StateStore = stateStore{} + +func NewStateStore(db ormtable.Schema) (StateStore, error) { + exampleDataTable, err := NewExampleDataTable(db) + if err != nil { + return nil, err + } + + return stateStore{ + exampleDataTable, + }, nil +} diff --git a/api/dwn/v1/state.pulsar.go b/api/dwn/v1/state.pulsar.go new file mode 100644 index 000000000..77acde27b --- /dev/null +++ b/api/dwn/v1/state.pulsar.go @@ -0,0 +1,626 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package dwnv1 + +import ( + _ "cosmossdk.io/api/cosmos/orm/v1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_ExampleData protoreflect.MessageDescriptor + fd_ExampleData_account protoreflect.FieldDescriptor + fd_ExampleData_amount protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_state_proto_init() + md_ExampleData = File_dwn_v1_state_proto.Messages().ByName("ExampleData") + fd_ExampleData_account = md_ExampleData.Fields().ByName("account") + fd_ExampleData_amount = md_ExampleData.Fields().ByName("amount") +} + +var _ protoreflect.Message = (*fastReflection_ExampleData)(nil) + +type fastReflection_ExampleData ExampleData + +func (x *ExampleData) ProtoReflect() protoreflect.Message { + return (*fastReflection_ExampleData)(x) +} + +func (x *ExampleData) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_state_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_ExampleData_messageType fastReflection_ExampleData_messageType +var _ protoreflect.MessageType = fastReflection_ExampleData_messageType{} + +type fastReflection_ExampleData_messageType struct{} + +func (x fastReflection_ExampleData_messageType) Zero() protoreflect.Message { + return (*fastReflection_ExampleData)(nil) +} +func (x fastReflection_ExampleData_messageType) New() protoreflect.Message { + return new(fastReflection_ExampleData) +} +func (x fastReflection_ExampleData_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_ExampleData +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_ExampleData) Descriptor() protoreflect.MessageDescriptor { + return md_ExampleData +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_ExampleData) Type() protoreflect.MessageType { + return _fastReflection_ExampleData_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_ExampleData) New() protoreflect.Message { + return new(fastReflection_ExampleData) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_ExampleData) Interface() protoreflect.ProtoMessage { + return (*ExampleData)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_ExampleData) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Account) != 0 { + value := protoreflect.ValueOfBytes(x.Account) + if !f(fd_ExampleData_account, value) { + return + } + } + if x.Amount != uint64(0) { + value := protoreflect.ValueOfUint64(x.Amount) + if !f(fd_ExampleData_amount, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_ExampleData) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.ExampleData.account": + return len(x.Account) != 0 + case "dwn.v1.ExampleData.amount": + return x.Amount != uint64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + } + panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ExampleData) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.ExampleData.account": + x.Account = nil + case "dwn.v1.ExampleData.amount": + x.Amount = uint64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + } + panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_ExampleData) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.ExampleData.account": + value := x.Account + return protoreflect.ValueOfBytes(value) + case "dwn.v1.ExampleData.amount": + value := x.Amount + return protoreflect.ValueOfUint64(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + } + panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ExampleData) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.ExampleData.account": + x.Account = value.Bytes() + case "dwn.v1.ExampleData.amount": + x.Amount = value.Uint() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + } + panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ExampleData) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.ExampleData.account": + panic(fmt.Errorf("field account of message dwn.v1.ExampleData is not mutable")) + case "dwn.v1.ExampleData.amount": + panic(fmt.Errorf("field amount of message dwn.v1.ExampleData is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + } + panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_ExampleData) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.ExampleData.account": + return protoreflect.ValueOfBytes(nil) + case "dwn.v1.ExampleData.amount": + return protoreflect.ValueOfUint64(uint64(0)) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + } + panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_ExampleData) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.ExampleData", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_ExampleData) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ExampleData) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_ExampleData) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_ExampleData) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*ExampleData) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Account) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Amount != 0 { + n += 1 + runtime.Sov(uint64(x.Amount)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*ExampleData) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Amount != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Amount)) + i-- + dAtA[i] = 0x10 + } + if len(x.Account) > 0 { + i -= len(x.Account) + copy(dAtA[i:], x.Account) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Account))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*ExampleData) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ExampleData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ExampleData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Account = append(x.Account[:0], dAtA[iNdEx:postIndex]...) + if x.Account == nil { + x.Account = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + x.Amount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Amount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: dwn/v1/state.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ExampleData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Account []byte `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` +} + +func (x *ExampleData) Reset() { + *x = ExampleData{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_state_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExampleData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExampleData) ProtoMessage() {} + +// Deprecated: Use ExampleData.ProtoReflect.Descriptor instead. +func (*ExampleData) Descriptor() ([]byte, []int) { + return file_dwn_v1_state_proto_rawDescGZIP(), []int{0} +} + +func (x *ExampleData) GetAccount() []byte { + if x != nil { + return x.Account + } + return nil +} + +func (x *ExampleData) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + +var File_dwn_v1_state_proto protoreflect.FileDescriptor + +var file_dwn_v1_state_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x09, + 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x10, 0x01, 0x18, 0x01, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, + 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, + 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, + 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_dwn_v1_state_proto_rawDescOnce sync.Once + file_dwn_v1_state_proto_rawDescData = file_dwn_v1_state_proto_rawDesc +) + +func file_dwn_v1_state_proto_rawDescGZIP() []byte { + file_dwn_v1_state_proto_rawDescOnce.Do(func() { + file_dwn_v1_state_proto_rawDescData = protoimpl.X.CompressGZIP(file_dwn_v1_state_proto_rawDescData) + }) + return file_dwn_v1_state_proto_rawDescData +} + +var file_dwn_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_dwn_v1_state_proto_goTypes = []interface{}{ + (*ExampleData)(nil), // 0: dwn.v1.ExampleData +} +var file_dwn_v1_state_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_dwn_v1_state_proto_init() } +func file_dwn_v1_state_proto_init() { + if File_dwn_v1_state_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_dwn_v1_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExampleData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dwn_v1_state_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_dwn_v1_state_proto_goTypes, + DependencyIndexes: file_dwn_v1_state_proto_depIdxs, + MessageInfos: file_dwn_v1_state_proto_msgTypes, + }.Build() + File_dwn_v1_state_proto = out.File + file_dwn_v1_state_proto_rawDesc = nil + file_dwn_v1_state_proto_goTypes = nil + file_dwn_v1_state_proto_depIdxs = nil +} diff --git a/api/dwn/v1/tx.pulsar.go b/api/dwn/v1/tx.pulsar.go new file mode 100644 index 000000000..c7a328668 --- /dev/null +++ b/api/dwn/v1/tx.pulsar.go @@ -0,0 +1,2061 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package dwnv1 + +import ( + _ "cosmossdk.io/api/cosmos/msg/v1" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_MsgUpdateParams protoreflect.MessageDescriptor + fd_MsgUpdateParams_authority protoreflect.FieldDescriptor + fd_MsgUpdateParams_params protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_tx_proto_init() + md_MsgUpdateParams = File_dwn_v1_tx_proto.Messages().ByName("MsgUpdateParams") + fd_MsgUpdateParams_authority = md_MsgUpdateParams.Fields().ByName("authority") + fd_MsgUpdateParams_params = md_MsgUpdateParams.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParams)(nil) + +type fastReflection_MsgUpdateParams MsgUpdateParams + +func (x *MsgUpdateParams) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(x) +} + +func (x *MsgUpdateParams) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_tx_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgUpdateParams_messageType fastReflection_MsgUpdateParams_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParams_messageType{} + +type fastReflection_MsgUpdateParams_messageType struct{} + +func (x fastReflection_MsgUpdateParams_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(nil) +} +func (x fastReflection_MsgUpdateParams_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} +func (x fastReflection_MsgUpdateParams_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParams) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgUpdateParams) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParams_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParams) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParams) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParams)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgUpdateParams) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Authority != "" { + value := protoreflect.ValueOfString(x.Authority) + if !f(fd_MsgUpdateParams_authority, value) { + return + } + } + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_MsgUpdateParams_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.MsgUpdateParams.authority": + return x.Authority != "" + case "dwn.v1.MsgUpdateParams.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.MsgUpdateParams.authority": + x.Authority = "" + case "dwn.v1.MsgUpdateParams.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgUpdateParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.MsgUpdateParams.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "dwn.v1.MsgUpdateParams.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParams does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.MsgUpdateParams.authority": + x.Authority = value.Interface().(string) + case "dwn.v1.MsgUpdateParams.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.MsgUpdateParams.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "dwn.v1.MsgUpdateParams.authority": + panic(fmt.Errorf("field authority of message dwn.v1.MsgUpdateParams is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgUpdateParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.MsgUpdateParams.authority": + return protoreflect.ValueOfString("") + case "dwn.v1.MsgUpdateParams.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgUpdateParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.MsgUpdateParams", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgUpdateParams) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgUpdateParams) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgUpdateParams) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Authority) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Authority) > 0 { + i -= len(x.Authority) + copy(dAtA[i:], x.Authority) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgUpdateParamsResponse protoreflect.MessageDescriptor +) + +func init() { + file_dwn_v1_tx_proto_init() + md_MsgUpdateParamsResponse = File_dwn_v1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParamsResponse)(nil) + +type fastReflection_MsgUpdateParamsResponse MsgUpdateParamsResponse + +func (x *MsgUpdateParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(x) +} + +func (x *MsgUpdateParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_tx_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgUpdateParamsResponse_messageType fastReflection_MsgUpdateParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParamsResponse_messageType{} + +type fastReflection_MsgUpdateParamsResponse_messageType struct{} + +func (x fastReflection_MsgUpdateParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(nil) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgUpdateParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParamsResponse) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParamsResponse) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParamsResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgUpdateParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgUpdateParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgUpdateParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParamsResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgUpdateParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.MsgUpdateParamsResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgUpdateParamsResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgUpdateParamsResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgInitialize protoreflect.MessageDescriptor + fd_MsgInitialize_authority protoreflect.FieldDescriptor + fd_MsgInitialize_params protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_tx_proto_init() + md_MsgInitialize = File_dwn_v1_tx_proto.Messages().ByName("MsgInitialize") + fd_MsgInitialize_authority = md_MsgInitialize.Fields().ByName("authority") + fd_MsgInitialize_params = md_MsgInitialize.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_MsgInitialize)(nil) + +type fastReflection_MsgInitialize MsgInitialize + +func (x *MsgInitialize) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgInitialize)(x) +} + +func (x *MsgInitialize) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_tx_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgInitialize_messageType fastReflection_MsgInitialize_messageType +var _ protoreflect.MessageType = fastReflection_MsgInitialize_messageType{} + +type fastReflection_MsgInitialize_messageType struct{} + +func (x fastReflection_MsgInitialize_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgInitialize)(nil) +} +func (x fastReflection_MsgInitialize_messageType) New() protoreflect.Message { + return new(fastReflection_MsgInitialize) +} +func (x fastReflection_MsgInitialize_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgInitialize +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgInitialize) Descriptor() protoreflect.MessageDescriptor { + return md_MsgInitialize +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgInitialize) Type() protoreflect.MessageType { + return _fastReflection_MsgInitialize_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgInitialize) New() protoreflect.Message { + return new(fastReflection_MsgInitialize) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgInitialize) Interface() protoreflect.ProtoMessage { + return (*MsgInitialize)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgInitialize) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Authority != "" { + value := protoreflect.ValueOfString(x.Authority) + if !f(fd_MsgInitialize_authority, value) { + return + } + } + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_MsgInitialize_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgInitialize) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.MsgInitialize.authority": + return x.Authority != "" + case "dwn.v1.MsgInitialize.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitialize")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitialize) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.MsgInitialize.authority": + x.Authority = "" + case "dwn.v1.MsgInitialize.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitialize")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgInitialize) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.MsgInitialize.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "dwn.v1.MsgInitialize.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitialize")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitialize does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitialize) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.MsgInitialize.authority": + x.Authority = value.Interface().(string) + case "dwn.v1.MsgInitialize.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitialize")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitialize) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.MsgInitialize.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "dwn.v1.MsgInitialize.authority": + panic(fmt.Errorf("field authority of message dwn.v1.MsgInitialize is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitialize")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgInitialize) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.MsgInitialize.authority": + return protoreflect.ValueOfString("") + case "dwn.v1.MsgInitialize.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitialize")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgInitialize) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.MsgInitialize", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgInitialize) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitialize) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgInitialize) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgInitialize) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgInitialize) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Authority) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgInitialize) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Authority) > 0 { + i -= len(x.Authority) + copy(dAtA[i:], x.Authority) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgInitialize) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitialize: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitialize: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgInitializeResponse protoreflect.MessageDescriptor +) + +func init() { + file_dwn_v1_tx_proto_init() + md_MsgInitializeResponse = File_dwn_v1_tx_proto.Messages().ByName("MsgInitializeResponse") +} + +var _ protoreflect.Message = (*fastReflection_MsgInitializeResponse)(nil) + +type fastReflection_MsgInitializeResponse MsgInitializeResponse + +func (x *MsgInitializeResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgInitializeResponse)(x) +} + +func (x *MsgInitializeResponse) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_tx_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgInitializeResponse_messageType fastReflection_MsgInitializeResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgInitializeResponse_messageType{} + +type fastReflection_MsgInitializeResponse_messageType struct{} + +func (x fastReflection_MsgInitializeResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgInitializeResponse)(nil) +} +func (x fastReflection_MsgInitializeResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgInitializeResponse) +} +func (x fastReflection_MsgInitializeResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgInitializeResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgInitializeResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgInitializeResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgInitializeResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgInitializeResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgInitializeResponse) New() protoreflect.Message { + return new(fastReflection_MsgInitializeResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgInitializeResponse) Interface() protoreflect.ProtoMessage { + return (*MsgInitializeResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgInitializeResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgInitializeResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitializeResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgInitializeResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitializeResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitializeResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitializeResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgInitializeResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message dwn.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgInitializeResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.MsgInitializeResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgInitializeResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitializeResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgInitializeResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgInitializeResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgInitializeResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgInitializeResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgInitializeResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitializeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitializeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: dwn/v1/tx.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// MsgUpdateParams is the Msg/UpdateParams request type. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *MsgUpdateParams) Reset() { + *x = MsgUpdateParams{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_tx_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParams) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParams.ProtoReflect.Descriptor instead. +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return file_dwn_v1_tx_proto_rawDescGZIP(), []int{0} +} + +func (x *MsgUpdateParams) GetAuthority() string { + if x != nil { + return x.Authority + } + return "" +} + +func (x *MsgUpdateParams) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MsgUpdateParamsResponse) Reset() { + *x = MsgUpdateParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_tx_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParamsResponse) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParamsResponse.ProtoReflect.Descriptor instead. +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return file_dwn_v1_tx_proto_rawDescGZIP(), []int{1} +} + +// MsgInitialize spawns a New Vault with Unclaimed State. This is a one-time +// operation that must be performed interacting with the Vault. +// +// Since: cosmos-sdk 0.47 +type MsgInitialize struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *MsgInitialize) Reset() { + *x = MsgInitialize{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_tx_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgInitialize) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgInitialize) ProtoMessage() {} + +// Deprecated: Use MsgInitialize.ProtoReflect.Descriptor instead. +func (*MsgInitialize) Descriptor() ([]byte, []int) { + return file_dwn_v1_tx_proto_rawDescGZIP(), []int{2} +} + +func (x *MsgInitialize) GetAuthority() string { + if x != nil { + return x.Authority + } + return "" +} + +func (x *MsgInitialize) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// MsgInitializeResponse defines the response structure for executing a +// MsgInitialize message. +// +// Since: cosmos-sdk 0.47 +type MsgInitializeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MsgInitializeResponse) Reset() { + *x = MsgInitializeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_tx_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgInitializeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgInitializeResponse) ProtoMessage() {} + +// Deprecated: Use MsgInitializeResponse.ProtoReflect.Descriptor instead. +func (*MsgInitializeResponse) Descriptor() ([]byte, []int) { + return file_dwn_v1_tx_proto_rawDescGZIP(), []int{3} +} + +var File_dwn_v1_tx_proto protoreflect.FileDescriptor + +var file_dwn_v1_tx_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x06, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x14, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, + 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x87, 0x01, 0x0a, 0x0f, 0x4d, 0x73, + 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x85, + 0x01, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, + 0x9a, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x48, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x17, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x1a, 0x1f, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, + 0x15, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x1a, 0x1d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x77, 0x0a, 0x0a, + 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, + 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, + 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, + 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_dwn_v1_tx_proto_rawDescOnce sync.Once + file_dwn_v1_tx_proto_rawDescData = file_dwn_v1_tx_proto_rawDesc +) + +func file_dwn_v1_tx_proto_rawDescGZIP() []byte { + file_dwn_v1_tx_proto_rawDescOnce.Do(func() { + file_dwn_v1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_dwn_v1_tx_proto_rawDescData) + }) + return file_dwn_v1_tx_proto_rawDescData +} + +var file_dwn_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_dwn_v1_tx_proto_goTypes = []interface{}{ + (*MsgUpdateParams)(nil), // 0: dwn.v1.MsgUpdateParams + (*MsgUpdateParamsResponse)(nil), // 1: dwn.v1.MsgUpdateParamsResponse + (*MsgInitialize)(nil), // 2: dwn.v1.MsgInitialize + (*MsgInitializeResponse)(nil), // 3: dwn.v1.MsgInitializeResponse + (*Params)(nil), // 4: dwn.v1.Params +} +var file_dwn_v1_tx_proto_depIdxs = []int32{ + 4, // 0: dwn.v1.MsgUpdateParams.params:type_name -> dwn.v1.Params + 4, // 1: dwn.v1.MsgInitialize.params:type_name -> dwn.v1.Params + 0, // 2: dwn.v1.Msg.UpdateParams:input_type -> dwn.v1.MsgUpdateParams + 2, // 3: dwn.v1.Msg.Initialize:input_type -> dwn.v1.MsgInitialize + 1, // 4: dwn.v1.Msg.UpdateParams:output_type -> dwn.v1.MsgUpdateParamsResponse + 3, // 5: dwn.v1.Msg.Initialize:output_type -> dwn.v1.MsgInitializeResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_dwn_v1_tx_proto_init() } +func file_dwn_v1_tx_proto_init() { + if File_dwn_v1_tx_proto != nil { + return + } + file_dwn_v1_genesis_proto_init() + if !protoimpl.UnsafeEnabled { + file_dwn_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParamsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_tx_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgInitialize); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_tx_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgInitializeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_dwn_v1_tx_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_dwn_v1_tx_proto_goTypes, + DependencyIndexes: file_dwn_v1_tx_proto_depIdxs, + MessageInfos: file_dwn_v1_tx_proto_msgTypes, + }.Build() + File_dwn_v1_tx_proto = out.File + file_dwn_v1_tx_proto_rawDesc = nil + file_dwn_v1_tx_proto_goTypes = nil + file_dwn_v1_tx_proto_depIdxs = nil +} diff --git a/api/dwn/v1/tx_grpc.pb.go b/api/dwn/v1/tx_grpc.pb.go new file mode 100644 index 000000000..852cb75a5 --- /dev/null +++ b/api/dwn/v1/tx_grpc.pb.go @@ -0,0 +1,171 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: dwn/v1/tx.proto + +package dwnv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Msg_UpdateParams_FullMethodName = "/dwn.v1.Msg/UpdateParams" + Msg_Initialize_FullMethodName = "/dwn.v1.Msg/Initialize" +) + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// Msg defines the Msg service. +type MsgClient interface { + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + // Initialize spawns a new Vault + Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error) +} + +type msgClient struct { + cc grpc.ClientConnInterface +} + +func NewMsgClient(cc grpc.ClientConnInterface) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, Msg_UpdateParams_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MsgInitializeResponse) + err := c.cc.Invoke(ctx, Msg_Initialize_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +// All implementations must embed UnimplementedMsgServer +// for forward compatibility. +// +// Msg defines the Msg service. +type MsgServer interface { + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + // Initialize spawns a new Vault + Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error) + mustEmbedUnimplementedMsgServer() +} + +// UnimplementedMsgServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedMsgServer struct{} + +func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} +func (UnimplementedMsgServer) Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Initialize not implemented") +} +func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} +func (UnimplementedMsgServer) testEmbeddedByValue() {} + +// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MsgServer will +// result in compilation errors. +type UnsafeMsgServer interface { + mustEmbedUnimplementedMsgServer() +} + +func RegisterMsgServer(s grpc.ServiceRegistrar, srv MsgServer) { + // If the following call pancis, it indicates UnimplementedMsgServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Msg_ServiceDesc, srv) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_UpdateParams_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_Initialize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgInitialize) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Initialize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_Initialize_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Initialize(ctx, req.(*MsgInitialize)) + } + return interceptor(ctx, in, info, handler) +} + +// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Msg_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "dwn.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + { + MethodName: "Initialize", + Handler: _Msg_Initialize_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dwn/v1/tx.proto", +} diff --git a/api/svc/module/v1/module.pulsar.go b/api/svc/module/v1/module.pulsar.go new file mode 100644 index 000000000..d28ce9067 --- /dev/null +++ b/api/svc/module/v1/module.pulsar.go @@ -0,0 +1,498 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package modulev1 + +import ( + _ "cosmossdk.io/api/cosmos/app/v1alpha1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_Module protoreflect.MessageDescriptor +) + +func init() { + file_svc_module_v1_module_proto_init() + md_Module = File_svc_module_v1_module_proto.Messages().ByName("Module") +} + +var _ protoreflect.Message = (*fastReflection_Module)(nil) + +type fastReflection_Module Module + +func (x *Module) ProtoReflect() protoreflect.Message { + return (*fastReflection_Module)(x) +} + +func (x *Module) slowProtoReflect() protoreflect.Message { + mi := &file_svc_module_v1_module_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Module_messageType fastReflection_Module_messageType +var _ protoreflect.MessageType = fastReflection_Module_messageType{} + +type fastReflection_Module_messageType struct{} + +func (x fastReflection_Module_messageType) Zero() protoreflect.Message { + return (*fastReflection_Module)(nil) +} +func (x fastReflection_Module_messageType) New() protoreflect.Message { + return new(fastReflection_Module) +} +func (x fastReflection_Module_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Module +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Module) Descriptor() protoreflect.MessageDescriptor { + return md_Module +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Module) Type() protoreflect.MessageType { + return _fastReflection_Module_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Module) New() protoreflect.Message { + return new(fastReflection_Module) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage { + return (*Module)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.module.v1.Module")) + } + panic(fmt.Errorf("message svc.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.module.v1.Module")) + } + panic(fmt.Errorf("message svc.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.module.v1.Module")) + } + panic(fmt.Errorf("message svc.module.v1.Module does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.module.v1.Module")) + } + panic(fmt.Errorf("message svc.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.module.v1.Module")) + } + panic(fmt.Errorf("message svc.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.module.v1.Module")) + } + panic(fmt.Errorf("message svc.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.module.v1.Module", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Module) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Module) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: svc/module/v1/module.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Module is the app config object of the module. +// Learn more: https://docs.cosmos.network/main/building-modules/depinject +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_module_v1_module_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_svc_module_v1_module_proto_rawDescGZIP(), []int{0} +} + +var File_svc_module_v1_module_proto protoreflect.FileDescriptor + +var file_svc_module_v1_module_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x73, 0x76, 0x63, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x76, + 0x63, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, + 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a, + 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, + 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, 0xa9, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, + 0x73, 0x76, 0x63, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, + 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x76, 0x63, 0x2f, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x53, 0x4d, 0x58, 0xaa, 0x02, 0x0d, 0x53, 0x76, 0x63, 0x2e, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x53, 0x76, 0x63, 0x5c, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x53, 0x76, 0x63, 0x5c, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x0f, 0x53, 0x76, 0x63, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_svc_module_v1_module_proto_rawDescOnce sync.Once + file_svc_module_v1_module_proto_rawDescData = file_svc_module_v1_module_proto_rawDesc +) + +func file_svc_module_v1_module_proto_rawDescGZIP() []byte { + file_svc_module_v1_module_proto_rawDescOnce.Do(func() { + file_svc_module_v1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_svc_module_v1_module_proto_rawDescData) + }) + return file_svc_module_v1_module_proto_rawDescData +} + +var file_svc_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_svc_module_v1_module_proto_goTypes = []interface{}{ + (*Module)(nil), // 0: svc.module.v1.Module +} +var file_svc_module_v1_module_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_svc_module_v1_module_proto_init() } +func file_svc_module_v1_module_proto_init() { + if File_svc_module_v1_module_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_svc_module_v1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Module); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_svc_module_v1_module_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_svc_module_v1_module_proto_goTypes, + DependencyIndexes: file_svc_module_v1_module_proto_depIdxs, + MessageInfos: file_svc_module_v1_module_proto_msgTypes, + }.Build() + File_svc_module_v1_module_proto = out.File + file_svc_module_v1_module_proto_rawDesc = nil + file_svc_module_v1_module_proto_goTypes = nil + file_svc_module_v1_module_proto_depIdxs = nil +} diff --git a/api/svc/v1/genesis.pulsar.go b/api/svc/v1/genesis.pulsar.go new file mode 100644 index 000000000..1a1a05e3d --- /dev/null +++ b/api/svc/v1/genesis.pulsar.go @@ -0,0 +1,3264 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package svcv1 + +import ( + _ "cosmossdk.io/api/amino" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_GenesisState protoreflect.MessageDescriptor + fd_GenesisState_params protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_genesis_proto_init() + md_GenesisState = File_svc_v1_genesis_proto.Messages().ByName("GenesisState") + fd_GenesisState_params = md_GenesisState.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_GenesisState)(nil) + +type fastReflection_GenesisState GenesisState + +func (x *GenesisState) ProtoReflect() protoreflect.Message { + return (*fastReflection_GenesisState)(x) +} + +func (x *GenesisState) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_genesis_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_GenesisState_messageType fastReflection_GenesisState_messageType +var _ protoreflect.MessageType = fastReflection_GenesisState_messageType{} + +type fastReflection_GenesisState_messageType struct{} + +func (x fastReflection_GenesisState_messageType) Zero() protoreflect.Message { + return (*fastReflection_GenesisState)(nil) +} +func (x fastReflection_GenesisState_messageType) New() protoreflect.Message { + return new(fastReflection_GenesisState) +} +func (x fastReflection_GenesisState_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_GenesisState +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_GenesisState) Descriptor() protoreflect.MessageDescriptor { + return md_GenesisState +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_GenesisState) Type() protoreflect.MessageType { + return _fastReflection_GenesisState_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_GenesisState) New() protoreflect.Message { + return new(fastReflection_GenesisState) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_GenesisState) Interface() protoreflect.ProtoMessage { + return (*GenesisState)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_GenesisState_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.GenesisState.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.GenesisState")) + } + panic(fmt.Errorf("message svc.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.GenesisState.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.GenesisState")) + } + panic(fmt.Errorf("message svc.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.GenesisState.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.GenesisState")) + } + panic(fmt.Errorf("message svc.v1.GenesisState does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.GenesisState.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.GenesisState")) + } + panic(fmt.Errorf("message svc.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.GenesisState.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.GenesisState")) + } + panic(fmt.Errorf("message svc.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.GenesisState.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.GenesisState")) + } + panic(fmt.Errorf("message svc.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_GenesisState) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.GenesisState", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_GenesisState) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_GenesisState) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_Params protoreflect.MessageDescriptor + fd_Params_categories protoreflect.FieldDescriptor + fd_Params_types protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_genesis_proto_init() + md_Params = File_svc_v1_genesis_proto.Messages().ByName("Params") + fd_Params_categories = md_Params.Fields().ByName("categories") + fd_Params_types = md_Params.Fields().ByName("types") +} + +var _ protoreflect.Message = (*fastReflection_Params)(nil) + +type fastReflection_Params Params + +func (x *Params) ProtoReflect() protoreflect.Message { + return (*fastReflection_Params)(x) +} + +func (x *Params) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_genesis_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Params_messageType fastReflection_Params_messageType +var _ protoreflect.MessageType = fastReflection_Params_messageType{} + +type fastReflection_Params_messageType struct{} + +func (x fastReflection_Params_messageType) Zero() protoreflect.Message { + return (*fastReflection_Params)(nil) +} +func (x fastReflection_Params_messageType) New() protoreflect.Message { + return new(fastReflection_Params) +} +func (x fastReflection_Params_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Params) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Params) Type() protoreflect.MessageType { + return _fastReflection_Params_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Params) New() protoreflect.Message { + return new(fastReflection_Params) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { + return (*Params)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Categories != nil { + value := protoreflect.ValueOfMessage(x.Categories.ProtoReflect()) + if !f(fd_Params_categories, value) { + return + } + } + if x.Types != nil { + value := protoreflect.ValueOfMessage(x.Types.ProtoReflect()) + if !f(fd_Params_types, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.Params.categories": + return x.Categories != nil + case "svc.v1.Params.types": + return x.Types != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Params")) + } + panic(fmt.Errorf("message svc.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.Params.categories": + x.Categories = nil + case "svc.v1.Params.types": + x.Types = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Params")) + } + panic(fmt.Errorf("message svc.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.Params.categories": + value := x.Categories + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "svc.v1.Params.types": + value := x.Types + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Params")) + } + panic(fmt.Errorf("message svc.v1.Params does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.Params.categories": + x.Categories = value.Message().Interface().(*ServiceCategories) + case "svc.v1.Params.types": + x.Types = value.Message().Interface().(*ServiceTypes) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Params")) + } + panic(fmt.Errorf("message svc.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.Params.categories": + if x.Categories == nil { + x.Categories = new(ServiceCategories) + } + return protoreflect.ValueOfMessage(x.Categories.ProtoReflect()) + case "svc.v1.Params.types": + if x.Types == nil { + x.Types = new(ServiceTypes) + } + return protoreflect.ValueOfMessage(x.Types.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Params")) + } + panic(fmt.Errorf("message svc.v1.Params does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.Params.categories": + m := new(ServiceCategories) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "svc.v1.Params.types": + m := new(ServiceTypes) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Params")) + } + panic(fmt.Errorf("message svc.v1.Params does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.Params", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Params) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Params) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Categories != nil { + l = options.Size(x.Categories) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Types != nil { + l = options.Size(x.Types) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Types != nil { + encoded, err := options.Marshal(x.Types) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if x.Categories != nil { + encoded, err := options.Marshal(x.Categories) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Categories", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Categories == nil { + x.Categories = &ServiceCategories{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Categories); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Types", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Types == nil { + x.Types = &ServiceTypes{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Types); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_ServiceCategories_1_list)(nil) + +type _ServiceCategories_1_list struct { + list *[]string +} + +func (x *_ServiceCategories_1_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_ServiceCategories_1_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_ServiceCategories_1_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_ServiceCategories_1_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_ServiceCategories_1_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message ServiceCategories at list field Categories as it is not of Message kind")) +} + +func (x *_ServiceCategories_1_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_ServiceCategories_1_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_ServiceCategories_1_list) IsValid() bool { + return x.list != nil +} + +var ( + md_ServiceCategories protoreflect.MessageDescriptor + fd_ServiceCategories_categories protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_genesis_proto_init() + md_ServiceCategories = File_svc_v1_genesis_proto.Messages().ByName("ServiceCategories") + fd_ServiceCategories_categories = md_ServiceCategories.Fields().ByName("categories") +} + +var _ protoreflect.Message = (*fastReflection_ServiceCategories)(nil) + +type fastReflection_ServiceCategories ServiceCategories + +func (x *ServiceCategories) ProtoReflect() protoreflect.Message { + return (*fastReflection_ServiceCategories)(x) +} + +func (x *ServiceCategories) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_genesis_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_ServiceCategories_messageType fastReflection_ServiceCategories_messageType +var _ protoreflect.MessageType = fastReflection_ServiceCategories_messageType{} + +type fastReflection_ServiceCategories_messageType struct{} + +func (x fastReflection_ServiceCategories_messageType) Zero() protoreflect.Message { + return (*fastReflection_ServiceCategories)(nil) +} +func (x fastReflection_ServiceCategories_messageType) New() protoreflect.Message { + return new(fastReflection_ServiceCategories) +} +func (x fastReflection_ServiceCategories_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_ServiceCategories +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_ServiceCategories) Descriptor() protoreflect.MessageDescriptor { + return md_ServiceCategories +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_ServiceCategories) Type() protoreflect.MessageType { + return _fastReflection_ServiceCategories_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_ServiceCategories) New() protoreflect.Message { + return new(fastReflection_ServiceCategories) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_ServiceCategories) Interface() protoreflect.ProtoMessage { + return (*ServiceCategories)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_ServiceCategories) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Categories) != 0 { + value := protoreflect.ValueOfList(&_ServiceCategories_1_list{list: &x.Categories}) + if !f(fd_ServiceCategories_categories, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_ServiceCategories) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.ServiceCategories.categories": + return len(x.Categories) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceCategories")) + } + panic(fmt.Errorf("message svc.v1.ServiceCategories does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ServiceCategories) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.ServiceCategories.categories": + x.Categories = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceCategories")) + } + panic(fmt.Errorf("message svc.v1.ServiceCategories does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_ServiceCategories) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.ServiceCategories.categories": + if len(x.Categories) == 0 { + return protoreflect.ValueOfList(&_ServiceCategories_1_list{}) + } + listValue := &_ServiceCategories_1_list{list: &x.Categories} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceCategories")) + } + panic(fmt.Errorf("message svc.v1.ServiceCategories does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ServiceCategories) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.ServiceCategories.categories": + lv := value.List() + clv := lv.(*_ServiceCategories_1_list) + x.Categories = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceCategories")) + } + panic(fmt.Errorf("message svc.v1.ServiceCategories does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ServiceCategories) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.ServiceCategories.categories": + if x.Categories == nil { + x.Categories = []string{} + } + value := &_ServiceCategories_1_list{list: &x.Categories} + return protoreflect.ValueOfList(value) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceCategories")) + } + panic(fmt.Errorf("message svc.v1.ServiceCategories does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_ServiceCategories) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.ServiceCategories.categories": + list := []string{} + return protoreflect.ValueOfList(&_ServiceCategories_1_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceCategories")) + } + panic(fmt.Errorf("message svc.v1.ServiceCategories does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_ServiceCategories) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.ServiceCategories", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_ServiceCategories) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ServiceCategories) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_ServiceCategories) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_ServiceCategories) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*ServiceCategories) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.Categories) > 0 { + for _, s := range x.Categories { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*ServiceCategories) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Categories) > 0 { + for iNdEx := len(x.Categories) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Categories[iNdEx]) + copy(dAtA[i:], x.Categories[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Categories[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*ServiceCategories) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ServiceCategories: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ServiceCategories: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Categories", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Categories = append(x.Categories, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_ServiceTypes_1_list)(nil) + +type _ServiceTypes_1_list struct { + list *[]string +} + +func (x *_ServiceTypes_1_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_ServiceTypes_1_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_ServiceTypes_1_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_ServiceTypes_1_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_ServiceTypes_1_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message ServiceTypes at list field Types as it is not of Message kind")) +} + +func (x *_ServiceTypes_1_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_ServiceTypes_1_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_ServiceTypes_1_list) IsValid() bool { + return x.list != nil +} + +var ( + md_ServiceTypes protoreflect.MessageDescriptor + fd_ServiceTypes_types protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_genesis_proto_init() + md_ServiceTypes = File_svc_v1_genesis_proto.Messages().ByName("ServiceTypes") + fd_ServiceTypes_types = md_ServiceTypes.Fields().ByName("types") +} + +var _ protoreflect.Message = (*fastReflection_ServiceTypes)(nil) + +type fastReflection_ServiceTypes ServiceTypes + +func (x *ServiceTypes) ProtoReflect() protoreflect.Message { + return (*fastReflection_ServiceTypes)(x) +} + +func (x *ServiceTypes) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_genesis_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_ServiceTypes_messageType fastReflection_ServiceTypes_messageType +var _ protoreflect.MessageType = fastReflection_ServiceTypes_messageType{} + +type fastReflection_ServiceTypes_messageType struct{} + +func (x fastReflection_ServiceTypes_messageType) Zero() protoreflect.Message { + return (*fastReflection_ServiceTypes)(nil) +} +func (x fastReflection_ServiceTypes_messageType) New() protoreflect.Message { + return new(fastReflection_ServiceTypes) +} +func (x fastReflection_ServiceTypes_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_ServiceTypes +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_ServiceTypes) Descriptor() protoreflect.MessageDescriptor { + return md_ServiceTypes +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_ServiceTypes) Type() protoreflect.MessageType { + return _fastReflection_ServiceTypes_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_ServiceTypes) New() protoreflect.Message { + return new(fastReflection_ServiceTypes) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_ServiceTypes) Interface() protoreflect.ProtoMessage { + return (*ServiceTypes)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_ServiceTypes) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Types) != 0 { + value := protoreflect.ValueOfList(&_ServiceTypes_1_list{list: &x.Types}) + if !f(fd_ServiceTypes_types, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_ServiceTypes) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.ServiceTypes.types": + return len(x.Types) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceTypes")) + } + panic(fmt.Errorf("message svc.v1.ServiceTypes does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ServiceTypes) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.ServiceTypes.types": + x.Types = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceTypes")) + } + panic(fmt.Errorf("message svc.v1.ServiceTypes does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_ServiceTypes) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.ServiceTypes.types": + if len(x.Types) == 0 { + return protoreflect.ValueOfList(&_ServiceTypes_1_list{}) + } + listValue := &_ServiceTypes_1_list{list: &x.Types} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceTypes")) + } + panic(fmt.Errorf("message svc.v1.ServiceTypes does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ServiceTypes) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.ServiceTypes.types": + lv := value.List() + clv := lv.(*_ServiceTypes_1_list) + x.Types = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceTypes")) + } + panic(fmt.Errorf("message svc.v1.ServiceTypes does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ServiceTypes) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.ServiceTypes.types": + if x.Types == nil { + x.Types = []string{} + } + value := &_ServiceTypes_1_list{list: &x.Types} + return protoreflect.ValueOfList(value) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceTypes")) + } + panic(fmt.Errorf("message svc.v1.ServiceTypes does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_ServiceTypes) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.ServiceTypes.types": + list := []string{} + return protoreflect.ValueOfList(&_ServiceTypes_1_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.ServiceTypes")) + } + panic(fmt.Errorf("message svc.v1.ServiceTypes does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_ServiceTypes) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.ServiceTypes", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_ServiceTypes) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ServiceTypes) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_ServiceTypes) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_ServiceTypes) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*ServiceTypes) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.Types) > 0 { + for _, s := range x.Types { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*ServiceTypes) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Types) > 0 { + for iNdEx := len(x.Types) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Types[iNdEx]) + copy(dAtA[i:], x.Types[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Types[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*ServiceTypes) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ServiceTypes: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ServiceTypes: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Types", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Types = append(x.Types, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_Service_7_list)(nil) + +type _Service_7_list struct { + list *[]string +} + +func (x *_Service_7_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Service_7_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Service_7_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Service_7_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Service_7_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Service at list field Tags as it is not of Message kind")) +} + +func (x *_Service_7_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Service_7_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Service_7_list) IsValid() bool { + return x.list != nil +} + +var ( + md_Service protoreflect.MessageDescriptor + fd_Service_id protoreflect.FieldDescriptor + fd_Service_authority protoreflect.FieldDescriptor + fd_Service_origin protoreflect.FieldDescriptor + fd_Service_name protoreflect.FieldDescriptor + fd_Service_description protoreflect.FieldDescriptor + fd_Service_category protoreflect.FieldDescriptor + fd_Service_tags protoreflect.FieldDescriptor + fd_Service_expiry_height protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_genesis_proto_init() + md_Service = File_svc_v1_genesis_proto.Messages().ByName("Service") + fd_Service_id = md_Service.Fields().ByName("id") + fd_Service_authority = md_Service.Fields().ByName("authority") + fd_Service_origin = md_Service.Fields().ByName("origin") + fd_Service_name = md_Service.Fields().ByName("name") + fd_Service_description = md_Service.Fields().ByName("description") + fd_Service_category = md_Service.Fields().ByName("category") + fd_Service_tags = md_Service.Fields().ByName("tags") + fd_Service_expiry_height = md_Service.Fields().ByName("expiry_height") +} + +var _ protoreflect.Message = (*fastReflection_Service)(nil) + +type fastReflection_Service Service + +func (x *Service) ProtoReflect() protoreflect.Message { + return (*fastReflection_Service)(x) +} + +func (x *Service) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_genesis_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Service_messageType fastReflection_Service_messageType +var _ protoreflect.MessageType = fastReflection_Service_messageType{} + +type fastReflection_Service_messageType struct{} + +func (x fastReflection_Service_messageType) Zero() protoreflect.Message { + return (*fastReflection_Service)(nil) +} +func (x fastReflection_Service_messageType) New() protoreflect.Message { + return new(fastReflection_Service) +} +func (x fastReflection_Service_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Service +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Service) Descriptor() protoreflect.MessageDescriptor { + return md_Service +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Service) Type() protoreflect.MessageType { + return _fastReflection_Service_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Service) New() protoreflect.Message { + return new(fastReflection_Service) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Service) Interface() protoreflect.ProtoMessage { + return (*Service)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Service) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Id != "" { + value := protoreflect.ValueOfString(x.Id) + if !f(fd_Service_id, value) { + return + } + } + if x.Authority != "" { + value := protoreflect.ValueOfString(x.Authority) + if !f(fd_Service_authority, value) { + return + } + } + if x.Origin != "" { + value := protoreflect.ValueOfString(x.Origin) + if !f(fd_Service_origin, value) { + return + } + } + if x.Name != "" { + value := protoreflect.ValueOfString(x.Name) + if !f(fd_Service_name, value) { + return + } + } + if x.Description != "" { + value := protoreflect.ValueOfString(x.Description) + if !f(fd_Service_description, value) { + return + } + } + if x.Category != "" { + value := protoreflect.ValueOfString(x.Category) + if !f(fd_Service_category, value) { + return + } + } + if len(x.Tags) != 0 { + value := protoreflect.ValueOfList(&_Service_7_list{list: &x.Tags}) + if !f(fd_Service_tags, value) { + return + } + } + if x.ExpiryHeight != int64(0) { + value := protoreflect.ValueOfInt64(x.ExpiryHeight) + if !f(fd_Service_expiry_height, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Service) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.Service.id": + return x.Id != "" + case "svc.v1.Service.authority": + return x.Authority != "" + case "svc.v1.Service.origin": + return x.Origin != "" + case "svc.v1.Service.name": + return x.Name != "" + case "svc.v1.Service.description": + return x.Description != "" + case "svc.v1.Service.category": + return x.Category != "" + case "svc.v1.Service.tags": + return len(x.Tags) != 0 + case "svc.v1.Service.expiry_height": + return x.ExpiryHeight != int64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Service")) + } + panic(fmt.Errorf("message svc.v1.Service does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Service) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.Service.id": + x.Id = "" + case "svc.v1.Service.authority": + x.Authority = "" + case "svc.v1.Service.origin": + x.Origin = "" + case "svc.v1.Service.name": + x.Name = "" + case "svc.v1.Service.description": + x.Description = "" + case "svc.v1.Service.category": + x.Category = "" + case "svc.v1.Service.tags": + x.Tags = nil + case "svc.v1.Service.expiry_height": + x.ExpiryHeight = int64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Service")) + } + panic(fmt.Errorf("message svc.v1.Service does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Service) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.Service.id": + value := x.Id + return protoreflect.ValueOfString(value) + case "svc.v1.Service.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "svc.v1.Service.origin": + value := x.Origin + return protoreflect.ValueOfString(value) + case "svc.v1.Service.name": + value := x.Name + return protoreflect.ValueOfString(value) + case "svc.v1.Service.description": + value := x.Description + return protoreflect.ValueOfString(value) + case "svc.v1.Service.category": + value := x.Category + return protoreflect.ValueOfString(value) + case "svc.v1.Service.tags": + if len(x.Tags) == 0 { + return protoreflect.ValueOfList(&_Service_7_list{}) + } + listValue := &_Service_7_list{list: &x.Tags} + return protoreflect.ValueOfList(listValue) + case "svc.v1.Service.expiry_height": + value := x.ExpiryHeight + return protoreflect.ValueOfInt64(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Service")) + } + panic(fmt.Errorf("message svc.v1.Service does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Service) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.Service.id": + x.Id = value.Interface().(string) + case "svc.v1.Service.authority": + x.Authority = value.Interface().(string) + case "svc.v1.Service.origin": + x.Origin = value.Interface().(string) + case "svc.v1.Service.name": + x.Name = value.Interface().(string) + case "svc.v1.Service.description": + x.Description = value.Interface().(string) + case "svc.v1.Service.category": + x.Category = value.Interface().(string) + case "svc.v1.Service.tags": + lv := value.List() + clv := lv.(*_Service_7_list) + x.Tags = *clv.list + case "svc.v1.Service.expiry_height": + x.ExpiryHeight = value.Int() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Service")) + } + panic(fmt.Errorf("message svc.v1.Service does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Service) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.Service.tags": + if x.Tags == nil { + x.Tags = []string{} + } + value := &_Service_7_list{list: &x.Tags} + return protoreflect.ValueOfList(value) + case "svc.v1.Service.id": + panic(fmt.Errorf("field id of message svc.v1.Service is not mutable")) + case "svc.v1.Service.authority": + panic(fmt.Errorf("field authority of message svc.v1.Service is not mutable")) + case "svc.v1.Service.origin": + panic(fmt.Errorf("field origin of message svc.v1.Service is not mutable")) + case "svc.v1.Service.name": + panic(fmt.Errorf("field name of message svc.v1.Service is not mutable")) + case "svc.v1.Service.description": + panic(fmt.Errorf("field description of message svc.v1.Service is not mutable")) + case "svc.v1.Service.category": + panic(fmt.Errorf("field category of message svc.v1.Service is not mutable")) + case "svc.v1.Service.expiry_height": + panic(fmt.Errorf("field expiry_height of message svc.v1.Service is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Service")) + } + panic(fmt.Errorf("message svc.v1.Service does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Service) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.Service.id": + return protoreflect.ValueOfString("") + case "svc.v1.Service.authority": + return protoreflect.ValueOfString("") + case "svc.v1.Service.origin": + return protoreflect.ValueOfString("") + case "svc.v1.Service.name": + return protoreflect.ValueOfString("") + case "svc.v1.Service.description": + return protoreflect.ValueOfString("") + case "svc.v1.Service.category": + return protoreflect.ValueOfString("") + case "svc.v1.Service.tags": + list := []string{} + return protoreflect.ValueOfList(&_Service_7_list{list: &list}) + case "svc.v1.Service.expiry_height": + return protoreflect.ValueOfInt64(int64(0)) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Service")) + } + panic(fmt.Errorf("message svc.v1.Service does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Service) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.Service", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Service) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Service) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Service) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Service) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Service) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Id) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Authority) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Origin) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Name) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Description) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Category) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.Tags) > 0 { + for _, s := range x.Tags { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.ExpiryHeight != 0 { + n += 1 + runtime.Sov(uint64(x.ExpiryHeight)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Service) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.ExpiryHeight != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryHeight)) + i-- + dAtA[i] = 0x40 + } + if len(x.Tags) > 0 { + for iNdEx := len(x.Tags) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Tags[iNdEx]) + copy(dAtA[i:], x.Tags[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Tags[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if len(x.Category) > 0 { + i -= len(x.Category) + copy(dAtA[i:], x.Category) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Category))) + i-- + dAtA[i] = 0x32 + } + if len(x.Description) > 0 { + i -= len(x.Description) + copy(dAtA[i:], x.Description) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Description))) + i-- + dAtA[i] = 0x2a + } + if len(x.Name) > 0 { + i -= len(x.Name) + copy(dAtA[i:], x.Name) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) + i-- + dAtA[i] = 0x22 + } + if len(x.Origin) > 0 { + i -= len(x.Origin) + copy(dAtA[i:], x.Origin) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) + i-- + dAtA[i] = 0x1a + } + if len(x.Authority) > 0 { + i -= len(x.Authority) + copy(dAtA[i:], x.Authority) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) + i-- + dAtA[i] = 0x12 + } + if len(x.Id) > 0 { + i -= len(x.Id) + copy(dAtA[i:], x.Id) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Id))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Service) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Service: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Service: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Origin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Category", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Category = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Tags = append(x.Tags, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) + } + x.ExpiryHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.ExpiryHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: svc/v1/genesis.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// GenesisState defines the module genesis state +type GenesisState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Params defines all the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *GenesisState) Reset() { + *x = GenesisState{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_genesis_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenesisState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenesisState) ProtoMessage() {} + +// Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. +func (*GenesisState) Descriptor() ([]byte, []int) { + return file_svc_v1_genesis_proto_rawDescGZIP(), []int{0} +} + +func (x *GenesisState) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// Params defines the set of module parameters. +type Params struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Categories *ServiceCategories `protobuf:"bytes,1,opt,name=categories,proto3" json:"categories,omitempty"` + Types *ServiceTypes `protobuf:"bytes,2,opt,name=types,proto3" json:"types,omitempty"` +} + +func (x *Params) Reset() { + *x = Params{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_genesis_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Params) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Params) ProtoMessage() {} + +// Deprecated: Use Params.ProtoReflect.Descriptor instead. +func (*Params) Descriptor() ([]byte, []int) { + return file_svc_v1_genesis_proto_rawDescGZIP(), []int{1} +} + +func (x *Params) GetCategories() *ServiceCategories { + if x != nil { + return x.Categories + } + return nil +} + +func (x *Params) GetTypes() *ServiceTypes { + if x != nil { + return x.Types + } + return nil +} + +type ServiceCategories struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Categories []string `protobuf:"bytes,1,rep,name=categories,proto3" json:"categories,omitempty"` +} + +func (x *ServiceCategories) Reset() { + *x = ServiceCategories{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_genesis_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServiceCategories) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceCategories) ProtoMessage() {} + +// Deprecated: Use ServiceCategories.ProtoReflect.Descriptor instead. +func (*ServiceCategories) Descriptor() ([]byte, []int) { + return file_svc_v1_genesis_proto_rawDescGZIP(), []int{2} +} + +func (x *ServiceCategories) GetCategories() []string { + if x != nil { + return x.Categories + } + return nil +} + +type ServiceTypes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Types []string `protobuf:"bytes,1,rep,name=types,proto3" json:"types,omitempty"` +} + +func (x *ServiceTypes) Reset() { + *x = ServiceTypes{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_genesis_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServiceTypes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceTypes) ProtoMessage() {} + +// Deprecated: Use ServiceTypes.ProtoReflect.Descriptor instead. +func (*ServiceTypes) Descriptor() ([]byte, []int) { + return file_svc_v1_genesis_proto_rawDescGZIP(), []int{3} +} + +func (x *ServiceTypes) GetTypes() []string { + if x != nil { + return x.Types + } + return nil +} + +// Service defines a Decentralized Service on the Sonr Blockchain +type Service struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Authority string `protobuf:"bytes,2,opt,name=authority,proto3" json:"authority,omitempty"` + Origin string `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + Category string `protobuf:"bytes,6,opt,name=category,proto3" json:"category,omitempty"` + Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` + ExpiryHeight int64 `protobuf:"varint,8,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` +} + +func (x *Service) Reset() { + *x = Service{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_genesis_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Service) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Service) ProtoMessage() {} + +// Deprecated: Use Service.ProtoReflect.Descriptor instead. +func (*Service) Descriptor() ([]byte, []int) { + return file_svc_v1_genesis_proto_rawDescGZIP(), []int{4} +} + +func (x *Service) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Service) GetAuthority() string { + if x != nil { + return x.Authority + } + return "" +} + +func (x *Service) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *Service) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Service) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Service) GetCategory() string { + if x != nil { + return x.Category + } + return "" +} + +func (x *Service) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Service) GetExpiryHeight() int64 { + if x != nil { + return x.ExpiryHeight + } + return 0 +} + +var File_svc_v1_genesis_proto protoreflect.FileDescriptor + +var file_svc_v1_genesis_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x14, + 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, + 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3c, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, + 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, + 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x05, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x76, 0x63, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x1b, 0x98, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, + 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x22, 0x50, 0x0a, 0x11, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, 0x74, + 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x1b, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, + 0xe7, 0xb0, 0x2a, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x63, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x16, 0xe8, 0xa0, + 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x22, 0xda, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, + 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x42, 0x7c, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x42, + 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, + 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x76, 0x63, 0x2f, + 0x76, 0x31, 0x3b, 0x73, 0x76, 0x63, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, + 0x06, 0x53, 0x76, 0x63, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x53, 0x76, 0x63, 0x5c, 0x56, 0x31, + 0xe2, 0x02, 0x12, 0x53, 0x76, 0x63, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x53, 0x76, 0x63, 0x3a, 0x3a, 0x56, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_svc_v1_genesis_proto_rawDescOnce sync.Once + file_svc_v1_genesis_proto_rawDescData = file_svc_v1_genesis_proto_rawDesc +) + +func file_svc_v1_genesis_proto_rawDescGZIP() []byte { + file_svc_v1_genesis_proto_rawDescOnce.Do(func() { + file_svc_v1_genesis_proto_rawDescData = protoimpl.X.CompressGZIP(file_svc_v1_genesis_proto_rawDescData) + }) + return file_svc_v1_genesis_proto_rawDescData +} + +var file_svc_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_svc_v1_genesis_proto_goTypes = []interface{}{ + (*GenesisState)(nil), // 0: svc.v1.GenesisState + (*Params)(nil), // 1: svc.v1.Params + (*ServiceCategories)(nil), // 2: svc.v1.ServiceCategories + (*ServiceTypes)(nil), // 3: svc.v1.ServiceTypes + (*Service)(nil), // 4: svc.v1.Service +} +var file_svc_v1_genesis_proto_depIdxs = []int32{ + 1, // 0: svc.v1.GenesisState.params:type_name -> svc.v1.Params + 2, // 1: svc.v1.Params.categories:type_name -> svc.v1.ServiceCategories + 3, // 2: svc.v1.Params.types:type_name -> svc.v1.ServiceTypes + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_svc_v1_genesis_proto_init() } +func file_svc_v1_genesis_proto_init() { + if File_svc_v1_genesis_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_svc_v1_genesis_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GenesisState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_genesis_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Params); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_genesis_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceCategories); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_genesis_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceTypes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_genesis_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Service); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_svc_v1_genesis_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_svc_v1_genesis_proto_goTypes, + DependencyIndexes: file_svc_v1_genesis_proto_depIdxs, + MessageInfos: file_svc_v1_genesis_proto_msgTypes, + }.Build() + File_svc_v1_genesis_proto = out.File + file_svc_v1_genesis_proto_rawDesc = nil + file_svc_v1_genesis_proto_goTypes = nil + file_svc_v1_genesis_proto_depIdxs = nil +} diff --git a/api/svc/v1/query.pulsar.go b/api/svc/v1/query.pulsar.go new file mode 100644 index 000000000..88deef4ac --- /dev/null +++ b/api/svc/v1/query.pulsar.go @@ -0,0 +1,993 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package svcv1 + +import ( + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_QueryParamsRequest protoreflect.MessageDescriptor +) + +func init() { + file_svc_v1_query_proto_init() + md_QueryParamsRequest = File_svc_v1_query_proto.Messages().ByName("QueryParamsRequest") +} + +var _ protoreflect.Message = (*fastReflection_QueryParamsRequest)(nil) + +type fastReflection_QueryParamsRequest QueryParamsRequest + +func (x *QueryParamsRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryParamsRequest)(x) +} + +func (x *QueryParamsRequest) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_query_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryParamsRequest_messageType fastReflection_QueryParamsRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryParamsRequest_messageType{} + +type fastReflection_QueryParamsRequest_messageType struct{} + +func (x fastReflection_QueryParamsRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryParamsRequest)(nil) +} +func (x fastReflection_QueryParamsRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryParamsRequest) +} +func (x fastReflection_QueryParamsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryParamsRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryParamsRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryParamsRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryParamsRequest) New() protoreflect.Message { + return new(fastReflection_QueryParamsRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryParamsRequest) Interface() protoreflect.ProtoMessage { + return (*QueryParamsRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryParamsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryParamsRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryParamsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryParamsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryParamsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.QueryParamsRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryParamsRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryParamsRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryParamsRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryParamsResponse protoreflect.MessageDescriptor + fd_QueryParamsResponse_params protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_query_proto_init() + md_QueryParamsResponse = File_svc_v1_query_proto.Messages().ByName("QueryParamsResponse") + fd_QueryParamsResponse_params = md_QueryParamsResponse.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_QueryParamsResponse)(nil) + +type fastReflection_QueryParamsResponse QueryParamsResponse + +func (x *QueryParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryParamsResponse)(x) +} + +func (x *QueryParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_query_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryParamsResponse_messageType fastReflection_QueryParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryParamsResponse_messageType{} + +type fastReflection_QueryParamsResponse_messageType struct{} + +func (x fastReflection_QueryParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryParamsResponse)(nil) +} +func (x fastReflection_QueryParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryParamsResponse) +} +func (x fastReflection_QueryParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryParamsResponse) New() protoreflect.Message { + return new(fastReflection_QueryParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryParamsResponse) Interface() protoreflect.ProtoMessage { + return (*QueryParamsResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_QueryParamsResponse_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.QueryParamsResponse.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.QueryParamsResponse.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.QueryParamsResponse.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.QueryParamsResponse.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.QueryParamsResponse.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.QueryParamsResponse.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.QueryParamsResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryParamsResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryParamsResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: svc/v1/query.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *QueryParamsRequest) Reset() { + *x = QueryParamsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_query_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryParamsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryParamsRequest) ProtoMessage() {} + +// Deprecated: Use QueryParamsRequest.ProtoReflect.Descriptor instead. +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return file_svc_v1_query_proto_rawDescGZIP(), []int{0} +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // params defines the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *QueryParamsResponse) Reset() { + *x = QueryParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_query_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryParamsResponse) ProtoMessage() {} + +// Deprecated: Use QueryParamsResponse.ProtoReflect.Descriptor instead. +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return file_svc_v1_query_proto_rawDescGZIP(), []int{1} +} + +func (x *QueryParamsResponse) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +var File_svc_v1_query_proto protoreflect.FileDescriptor + +var file_svc_v1_query_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x73, 0x76, 0x63, 0x2f, + 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x14, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, + 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x32, 0x62, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x59, + 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1a, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x73, 0x76, 0x63, 0x2f, + 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, + 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x76, 0x63, 0x76, 0x31, 0xa2, 0x02, + 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x53, 0x76, 0x63, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, + 0x53, 0x76, 0x63, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x53, 0x76, 0x63, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x53, 0x76, + 0x63, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_svc_v1_query_proto_rawDescOnce sync.Once + file_svc_v1_query_proto_rawDescData = file_svc_v1_query_proto_rawDesc +) + +func file_svc_v1_query_proto_rawDescGZIP() []byte { + file_svc_v1_query_proto_rawDescOnce.Do(func() { + file_svc_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_svc_v1_query_proto_rawDescData) + }) + return file_svc_v1_query_proto_rawDescData +} + +var file_svc_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_svc_v1_query_proto_goTypes = []interface{}{ + (*QueryParamsRequest)(nil), // 0: svc.v1.QueryParamsRequest + (*QueryParamsResponse)(nil), // 1: svc.v1.QueryParamsResponse + (*Params)(nil), // 2: svc.v1.Params +} +var file_svc_v1_query_proto_depIdxs = []int32{ + 2, // 0: svc.v1.QueryParamsResponse.params:type_name -> svc.v1.Params + 0, // 1: svc.v1.Query.Params:input_type -> svc.v1.QueryParamsRequest + 1, // 2: svc.v1.Query.Params:output_type -> svc.v1.QueryParamsResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_svc_v1_query_proto_init() } +func file_svc_v1_query_proto_init() { + if File_svc_v1_query_proto != nil { + return + } + file_svc_v1_genesis_proto_init() + if !protoimpl.UnsafeEnabled { + file_svc_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryParamsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryParamsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_svc_v1_query_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_svc_v1_query_proto_goTypes, + DependencyIndexes: file_svc_v1_query_proto_depIdxs, + MessageInfos: file_svc_v1_query_proto_msgTypes, + }.Build() + File_svc_v1_query_proto = out.File + file_svc_v1_query_proto_rawDesc = nil + file_svc_v1_query_proto_goTypes = nil + file_svc_v1_query_proto_depIdxs = nil +} diff --git a/api/svc/v1/query_grpc.pb.go b/api/svc/v1/query_grpc.pb.go new file mode 100644 index 000000000..ef7b606c7 --- /dev/null +++ b/api/svc/v1/query_grpc.pb.go @@ -0,0 +1,127 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: svc/v1/query.proto + +package svcv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Query_Params_FullMethodName = "/svc.v1.Query/Params" +) + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// Query provides defines the gRPC querier service. +type QueryClient interface { + // Params queries all parameters of the module. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) +} + +type queryClient struct { + cc grpc.ClientConnInterface +} + +func NewQueryClient(cc grpc.ClientConnInterface) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, Query_Params_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +// All implementations must embed UnimplementedQueryServer +// for forward compatibility. +// +// Query provides defines the gRPC querier service. +type QueryServer interface { + // Params queries all parameters of the module. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + mustEmbedUnimplementedQueryServer() +} + +// UnimplementedQueryServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedQueryServer struct{} + +func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {} +func (UnimplementedQueryServer) testEmbeddedByValue() {} + +// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to QueryServer will +// result in compilation errors. +type UnsafeQueryServer interface { + mustEmbedUnimplementedQueryServer() +} + +func RegisterQueryServer(s grpc.ServiceRegistrar, srv QueryServer) { + // If the following call pancis, it indicates UnimplementedQueryServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Query_ServiceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_Params_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Query_ServiceDesc is the grpc.ServiceDesc for Query service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Query_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "svc.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "svc/v1/query.proto", +} diff --git a/api/svc/v1/state.cosmos_orm.go b/api/svc/v1/state.cosmos_orm.go new file mode 100644 index 000000000..156ecf278 --- /dev/null +++ b/api/svc/v1/state.cosmos_orm.go @@ -0,0 +1,368 @@ +// Code generated by protoc-gen-go-cosmos-orm. DO NOT EDIT. + +package svcv1 + +import ( + context "context" + ormlist "cosmossdk.io/orm/model/ormlist" + ormtable "cosmossdk.io/orm/model/ormtable" + ormerrors "cosmossdk.io/orm/types/ormerrors" +) + +type MetadataTable interface { + Insert(ctx context.Context, metadata *Metadata) error + InsertReturningId(ctx context.Context, metadata *Metadata) (uint64, error) + LastInsertedSequence(ctx context.Context) (uint64, error) + Update(ctx context.Context, metadata *Metadata) error + Save(ctx context.Context, metadata *Metadata) error + Delete(ctx context.Context, metadata *Metadata) error + Has(ctx context.Context, id uint64) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, id uint64) (*Metadata, error) + HasByOrigin(ctx context.Context, origin string) (found bool, err error) + // GetByOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + GetByOrigin(ctx context.Context, origin string) (*Metadata, error) + List(ctx context.Context, prefixKey MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) + ListRange(ctx context.Context, from, to MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) + DeleteBy(ctx context.Context, prefixKey MetadataIndexKey) error + DeleteRange(ctx context.Context, from, to MetadataIndexKey) error + + doNotImplement() +} + +type MetadataIterator struct { + ormtable.Iterator +} + +func (i MetadataIterator) Value() (*Metadata, error) { + var metadata Metadata + err := i.UnmarshalMessage(&metadata) + return &metadata, err +} + +type MetadataIndexKey interface { + id() uint32 + values() []interface{} + metadataIndexKey() +} + +// primary key starting index.. +type MetadataPrimaryKey = MetadataIdIndexKey + +type MetadataIdIndexKey struct { + vs []interface{} +} + +func (x MetadataIdIndexKey) id() uint32 { return 0 } +func (x MetadataIdIndexKey) values() []interface{} { return x.vs } +func (x MetadataIdIndexKey) metadataIndexKey() {} + +func (this MetadataIdIndexKey) WithId(id uint64) MetadataIdIndexKey { + this.vs = []interface{}{id} + return this +} + +type MetadataOriginIndexKey struct { + vs []interface{} +} + +func (x MetadataOriginIndexKey) id() uint32 { return 1 } +func (x MetadataOriginIndexKey) values() []interface{} { return x.vs } +func (x MetadataOriginIndexKey) metadataIndexKey() {} + +func (this MetadataOriginIndexKey) WithOrigin(origin string) MetadataOriginIndexKey { + this.vs = []interface{}{origin} + return this +} + +type metadataTable struct { + table ormtable.AutoIncrementTable +} + +func (this metadataTable) Insert(ctx context.Context, metadata *Metadata) error { + return this.table.Insert(ctx, metadata) +} + +func (this metadataTable) Update(ctx context.Context, metadata *Metadata) error { + return this.table.Update(ctx, metadata) +} + +func (this metadataTable) Save(ctx context.Context, metadata *Metadata) error { + return this.table.Save(ctx, metadata) +} + +func (this metadataTable) Delete(ctx context.Context, metadata *Metadata) error { + return this.table.Delete(ctx, metadata) +} + +func (this metadataTable) InsertReturningId(ctx context.Context, metadata *Metadata) (uint64, error) { + return this.table.InsertReturningPKey(ctx, metadata) +} + +func (this metadataTable) LastInsertedSequence(ctx context.Context) (uint64, error) { + return this.table.LastInsertedSequence(ctx) +} + +func (this metadataTable) Has(ctx context.Context, id uint64) (found bool, err error) { + return this.table.PrimaryKey().Has(ctx, id) +} + +func (this metadataTable) Get(ctx context.Context, id uint64) (*Metadata, error) { + var metadata Metadata + found, err := this.table.PrimaryKey().Get(ctx, &metadata, id) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &metadata, nil +} + +func (this metadataTable) HasByOrigin(ctx context.Context, origin string) (found bool, err error) { + return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, + origin, + ) +} + +func (this metadataTable) GetByOrigin(ctx context.Context, origin string) (*Metadata, error) { + var metadata Metadata + found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &metadata, + origin, + ) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &metadata, nil +} + +func (this metadataTable) List(ctx context.Context, prefixKey MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) { + it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) + return MetadataIterator{it}, err +} + +func (this metadataTable) ListRange(ctx context.Context, from, to MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) { + it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) + return MetadataIterator{it}, err +} + +func (this metadataTable) DeleteBy(ctx context.Context, prefixKey MetadataIndexKey) error { + return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) +} + +func (this metadataTable) DeleteRange(ctx context.Context, from, to MetadataIndexKey) error { + return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) +} + +func (this metadataTable) doNotImplement() {} + +var _ MetadataTable = metadataTable{} + +func NewMetadataTable(db ormtable.Schema) (MetadataTable, error) { + table := db.GetTable(&Metadata{}) + if table == nil { + return nil, ormerrors.TableNotFound.Wrap(string((&Metadata{}).ProtoReflect().Descriptor().FullName())) + } + return metadataTable{table.(ormtable.AutoIncrementTable)}, nil +} + +type ProfileTable interface { + Insert(ctx context.Context, profile *Profile) error + Update(ctx context.Context, profile *Profile) error + Save(ctx context.Context, profile *Profile) error + Delete(ctx context.Context, profile *Profile) error + Has(ctx context.Context, id string) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, id string) (*Profile, error) + HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) + // GetBySubjectOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Profile, error) + List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) + ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) + DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error + DeleteRange(ctx context.Context, from, to ProfileIndexKey) error + + doNotImplement() +} + +type ProfileIterator struct { + ormtable.Iterator +} + +func (i ProfileIterator) Value() (*Profile, error) { + var profile Profile + err := i.UnmarshalMessage(&profile) + return &profile, err +} + +type ProfileIndexKey interface { + id() uint32 + values() []interface{} + profileIndexKey() +} + +// primary key starting index.. +type ProfilePrimaryKey = ProfileIdIndexKey + +type ProfileIdIndexKey struct { + vs []interface{} +} + +func (x ProfileIdIndexKey) id() uint32 { return 0 } +func (x ProfileIdIndexKey) values() []interface{} { return x.vs } +func (x ProfileIdIndexKey) profileIndexKey() {} + +func (this ProfileIdIndexKey) WithId(id string) ProfileIdIndexKey { + this.vs = []interface{}{id} + return this +} + +type ProfileSubjectOriginIndexKey struct { + vs []interface{} +} + +func (x ProfileSubjectOriginIndexKey) id() uint32 { return 1 } +func (x ProfileSubjectOriginIndexKey) values() []interface{} { return x.vs } +func (x ProfileSubjectOriginIndexKey) profileIndexKey() {} + +func (this ProfileSubjectOriginIndexKey) WithSubject(subject string) ProfileSubjectOriginIndexKey { + this.vs = []interface{}{subject} + return this +} + +func (this ProfileSubjectOriginIndexKey) WithSubjectOrigin(subject string, origin string) ProfileSubjectOriginIndexKey { + this.vs = []interface{}{subject, origin} + return this +} + +type profileTable struct { + table ormtable.Table +} + +func (this profileTable) Insert(ctx context.Context, profile *Profile) error { + return this.table.Insert(ctx, profile) +} + +func (this profileTable) Update(ctx context.Context, profile *Profile) error { + return this.table.Update(ctx, profile) +} + +func (this profileTable) Save(ctx context.Context, profile *Profile) error { + return this.table.Save(ctx, profile) +} + +func (this profileTable) Delete(ctx context.Context, profile *Profile) error { + return this.table.Delete(ctx, profile) +} + +func (this profileTable) Has(ctx context.Context, id string) (found bool, err error) { + return this.table.PrimaryKey().Has(ctx, id) +} + +func (this profileTable) Get(ctx context.Context, id string) (*Profile, error) { + var profile Profile + found, err := this.table.PrimaryKey().Get(ctx, &profile, id) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &profile, nil +} + +func (this profileTable) HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) { + return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, + subject, + origin, + ) +} + +func (this profileTable) GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Profile, error) { + var profile Profile + found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &profile, + subject, + origin, + ) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &profile, nil +} + +func (this profileTable) List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { + it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) + return ProfileIterator{it}, err +} + +func (this profileTable) ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { + it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) + return ProfileIterator{it}, err +} + +func (this profileTable) DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error { + return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) +} + +func (this profileTable) DeleteRange(ctx context.Context, from, to ProfileIndexKey) error { + return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) +} + +func (this profileTable) doNotImplement() {} + +var _ ProfileTable = profileTable{} + +func NewProfileTable(db ormtable.Schema) (ProfileTable, error) { + table := db.GetTable(&Profile{}) + if table == nil { + return nil, ormerrors.TableNotFound.Wrap(string((&Profile{}).ProtoReflect().Descriptor().FullName())) + } + return profileTable{table}, nil +} + +type StateStore interface { + MetadataTable() MetadataTable + ProfileTable() ProfileTable + + doNotImplement() +} + +type stateStore struct { + metadata MetadataTable + profile ProfileTable +} + +func (x stateStore) MetadataTable() MetadataTable { + return x.metadata +} + +func (x stateStore) ProfileTable() ProfileTable { + return x.profile +} + +func (stateStore) doNotImplement() {} + +var _ StateStore = stateStore{} + +func NewStateStore(db ormtable.Schema) (StateStore, error) { + metadataTable, err := NewMetadataTable(db) + if err != nil { + return nil, err + } + + profileTable, err := NewProfileTable(db) + if err != nil { + return nil, err + } + + return stateStore{ + metadataTable, + profileTable, + }, nil +} diff --git a/api/svc/v1/state.pulsar.go b/api/svc/v1/state.pulsar.go new file mode 100644 index 000000000..0af9896b1 --- /dev/null +++ b/api/svc/v1/state.pulsar.go @@ -0,0 +1,1749 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package svcv1 + +import ( + _ "cosmossdk.io/api/cosmos/orm/v1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var _ protoreflect.List = (*_Metadata_7_list)(nil) + +type _Metadata_7_list struct { + list *[]string +} + +func (x *_Metadata_7_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Metadata_7_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Metadata_7_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Metadata_7_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Metadata_7_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Metadata at list field Tags as it is not of Message kind")) +} + +func (x *_Metadata_7_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Metadata_7_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Metadata_7_list) IsValid() bool { + return x.list != nil +} + +var ( + md_Metadata protoreflect.MessageDescriptor + fd_Metadata_id protoreflect.FieldDescriptor + fd_Metadata_origin protoreflect.FieldDescriptor + fd_Metadata_name protoreflect.FieldDescriptor + fd_Metadata_description protoreflect.FieldDescriptor + fd_Metadata_category protoreflect.FieldDescriptor + fd_Metadata_icon protoreflect.FieldDescriptor + fd_Metadata_tags protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_state_proto_init() + md_Metadata = File_svc_v1_state_proto.Messages().ByName("Metadata") + fd_Metadata_id = md_Metadata.Fields().ByName("id") + fd_Metadata_origin = md_Metadata.Fields().ByName("origin") + fd_Metadata_name = md_Metadata.Fields().ByName("name") + fd_Metadata_description = md_Metadata.Fields().ByName("description") + fd_Metadata_category = md_Metadata.Fields().ByName("category") + fd_Metadata_icon = md_Metadata.Fields().ByName("icon") + fd_Metadata_tags = md_Metadata.Fields().ByName("tags") +} + +var _ protoreflect.Message = (*fastReflection_Metadata)(nil) + +type fastReflection_Metadata Metadata + +func (x *Metadata) ProtoReflect() protoreflect.Message { + return (*fastReflection_Metadata)(x) +} + +func (x *Metadata) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_state_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Metadata_messageType fastReflection_Metadata_messageType +var _ protoreflect.MessageType = fastReflection_Metadata_messageType{} + +type fastReflection_Metadata_messageType struct{} + +func (x fastReflection_Metadata_messageType) Zero() protoreflect.Message { + return (*fastReflection_Metadata)(nil) +} +func (x fastReflection_Metadata_messageType) New() protoreflect.Message { + return new(fastReflection_Metadata) +} +func (x fastReflection_Metadata_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Metadata +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Metadata) Descriptor() protoreflect.MessageDescriptor { + return md_Metadata +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Metadata) Type() protoreflect.MessageType { + return _fastReflection_Metadata_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Metadata) New() protoreflect.Message { + return new(fastReflection_Metadata) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Metadata) Interface() protoreflect.ProtoMessage { + return (*Metadata)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Metadata) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Id != uint64(0) { + value := protoreflect.ValueOfUint64(x.Id) + if !f(fd_Metadata_id, value) { + return + } + } + if x.Origin != "" { + value := protoreflect.ValueOfString(x.Origin) + if !f(fd_Metadata_origin, value) { + return + } + } + if x.Name != "" { + value := protoreflect.ValueOfString(x.Name) + if !f(fd_Metadata_name, value) { + return + } + } + if x.Description != "" { + value := protoreflect.ValueOfString(x.Description) + if !f(fd_Metadata_description, value) { + return + } + } + if x.Category != "" { + value := protoreflect.ValueOfString(x.Category) + if !f(fd_Metadata_category, value) { + return + } + } + if x.Icon != "" { + value := protoreflect.ValueOfString(x.Icon) + if !f(fd_Metadata_icon, value) { + return + } + } + if len(x.Tags) != 0 { + value := protoreflect.ValueOfList(&_Metadata_7_list{list: &x.Tags}) + if !f(fd_Metadata_tags, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Metadata) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.Metadata.id": + return x.Id != uint64(0) + case "svc.v1.Metadata.origin": + return x.Origin != "" + case "svc.v1.Metadata.name": + return x.Name != "" + case "svc.v1.Metadata.description": + return x.Description != "" + case "svc.v1.Metadata.category": + return x.Category != "" + case "svc.v1.Metadata.icon": + return x.Icon != "" + case "svc.v1.Metadata.tags": + return len(x.Tags) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + } + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.Metadata.id": + x.Id = uint64(0) + case "svc.v1.Metadata.origin": + x.Origin = "" + case "svc.v1.Metadata.name": + x.Name = "" + case "svc.v1.Metadata.description": + x.Description = "" + case "svc.v1.Metadata.category": + x.Category = "" + case "svc.v1.Metadata.icon": + x.Icon = "" + case "svc.v1.Metadata.tags": + x.Tags = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + } + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Metadata) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.Metadata.id": + value := x.Id + return protoreflect.ValueOfUint64(value) + case "svc.v1.Metadata.origin": + value := x.Origin + return protoreflect.ValueOfString(value) + case "svc.v1.Metadata.name": + value := x.Name + return protoreflect.ValueOfString(value) + case "svc.v1.Metadata.description": + value := x.Description + return protoreflect.ValueOfString(value) + case "svc.v1.Metadata.category": + value := x.Category + return protoreflect.ValueOfString(value) + case "svc.v1.Metadata.icon": + value := x.Icon + return protoreflect.ValueOfString(value) + case "svc.v1.Metadata.tags": + if len(x.Tags) == 0 { + return protoreflect.ValueOfList(&_Metadata_7_list{}) + } + listValue := &_Metadata_7_list{list: &x.Tags} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + } + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.Metadata.id": + x.Id = value.Uint() + case "svc.v1.Metadata.origin": + x.Origin = value.Interface().(string) + case "svc.v1.Metadata.name": + x.Name = value.Interface().(string) + case "svc.v1.Metadata.description": + x.Description = value.Interface().(string) + case "svc.v1.Metadata.category": + x.Category = value.Interface().(string) + case "svc.v1.Metadata.icon": + x.Icon = value.Interface().(string) + case "svc.v1.Metadata.tags": + lv := value.List() + clv := lv.(*_Metadata_7_list) + x.Tags = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + } + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.Metadata.tags": + if x.Tags == nil { + x.Tags = []string{} + } + value := &_Metadata_7_list{list: &x.Tags} + return protoreflect.ValueOfList(value) + case "svc.v1.Metadata.id": + panic(fmt.Errorf("field id of message svc.v1.Metadata is not mutable")) + case "svc.v1.Metadata.origin": + panic(fmt.Errorf("field origin of message svc.v1.Metadata is not mutable")) + case "svc.v1.Metadata.name": + panic(fmt.Errorf("field name of message svc.v1.Metadata is not mutable")) + case "svc.v1.Metadata.description": + panic(fmt.Errorf("field description of message svc.v1.Metadata is not mutable")) + case "svc.v1.Metadata.category": + panic(fmt.Errorf("field category of message svc.v1.Metadata is not mutable")) + case "svc.v1.Metadata.icon": + panic(fmt.Errorf("field icon of message svc.v1.Metadata is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + } + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Metadata) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.Metadata.id": + return protoreflect.ValueOfUint64(uint64(0)) + case "svc.v1.Metadata.origin": + return protoreflect.ValueOfString("") + case "svc.v1.Metadata.name": + return protoreflect.ValueOfString("") + case "svc.v1.Metadata.description": + return protoreflect.ValueOfString("") + case "svc.v1.Metadata.category": + return protoreflect.ValueOfString("") + case "svc.v1.Metadata.icon": + return protoreflect.ValueOfString("") + case "svc.v1.Metadata.tags": + list := []string{} + return protoreflect.ValueOfList(&_Metadata_7_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + } + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Metadata) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.Metadata", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Metadata) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Metadata) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Id != 0 { + n += 1 + runtime.Sov(uint64(x.Id)) + } + l = len(x.Origin) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Name) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Description) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Category) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Icon) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.Tags) > 0 { + for _, s := range x.Tags { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Tags) > 0 { + for iNdEx := len(x.Tags) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Tags[iNdEx]) + copy(dAtA[i:], x.Tags[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Tags[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if len(x.Icon) > 0 { + i -= len(x.Icon) + copy(dAtA[i:], x.Icon) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Icon))) + i-- + dAtA[i] = 0x32 + } + if len(x.Category) > 0 { + i -= len(x.Category) + copy(dAtA[i:], x.Category) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Category))) + i-- + dAtA[i] = 0x2a + } + if len(x.Description) > 0 { + i -= len(x.Description) + copy(dAtA[i:], x.Description) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Description))) + i-- + dAtA[i] = 0x22 + } + if len(x.Name) > 0 { + i -= len(x.Name) + copy(dAtA[i:], x.Name) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) + i-- + dAtA[i] = 0x1a + } + if len(x.Origin) > 0 { + i -= len(x.Origin) + copy(dAtA[i:], x.Origin) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) + i-- + dAtA[i] = 0x12 + } + if x.Id != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Id)) + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + x.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Origin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Category", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Category = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Icon", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Icon = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Tags = append(x.Tags, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_Profile protoreflect.MessageDescriptor + fd_Profile_id protoreflect.FieldDescriptor + fd_Profile_subject protoreflect.FieldDescriptor + fd_Profile_origin protoreflect.FieldDescriptor + fd_Profile_controller protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_state_proto_init() + md_Profile = File_svc_v1_state_proto.Messages().ByName("Profile") + fd_Profile_id = md_Profile.Fields().ByName("id") + fd_Profile_subject = md_Profile.Fields().ByName("subject") + fd_Profile_origin = md_Profile.Fields().ByName("origin") + fd_Profile_controller = md_Profile.Fields().ByName("controller") +} + +var _ protoreflect.Message = (*fastReflection_Profile)(nil) + +type fastReflection_Profile Profile + +func (x *Profile) ProtoReflect() protoreflect.Message { + return (*fastReflection_Profile)(x) +} + +func (x *Profile) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_state_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Profile_messageType fastReflection_Profile_messageType +var _ protoreflect.MessageType = fastReflection_Profile_messageType{} + +type fastReflection_Profile_messageType struct{} + +func (x fastReflection_Profile_messageType) Zero() protoreflect.Message { + return (*fastReflection_Profile)(nil) +} +func (x fastReflection_Profile_messageType) New() protoreflect.Message { + return new(fastReflection_Profile) +} +func (x fastReflection_Profile_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Profile +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Profile) Descriptor() protoreflect.MessageDescriptor { + return md_Profile +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Profile) Type() protoreflect.MessageType { + return _fastReflection_Profile_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Profile) New() protoreflect.Message { + return new(fastReflection_Profile) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Profile) Interface() protoreflect.ProtoMessage { + return (*Profile)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Profile) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Id != "" { + value := protoreflect.ValueOfString(x.Id) + if !f(fd_Profile_id, value) { + return + } + } + if x.Subject != "" { + value := protoreflect.ValueOfString(x.Subject) + if !f(fd_Profile_subject, value) { + return + } + } + if x.Origin != "" { + value := protoreflect.ValueOfString(x.Origin) + if !f(fd_Profile_origin, value) { + return + } + } + if x.Controller != "" { + value := protoreflect.ValueOfString(x.Controller) + if !f(fd_Profile_controller, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Profile) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.Profile.id": + return x.Id != "" + case "svc.v1.Profile.subject": + return x.Subject != "" + case "svc.v1.Profile.origin": + return x.Origin != "" + case "svc.v1.Profile.controller": + return x.Controller != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + } + panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Profile) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.Profile.id": + x.Id = "" + case "svc.v1.Profile.subject": + x.Subject = "" + case "svc.v1.Profile.origin": + x.Origin = "" + case "svc.v1.Profile.controller": + x.Controller = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + } + panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Profile) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.Profile.id": + value := x.Id + return protoreflect.ValueOfString(value) + case "svc.v1.Profile.subject": + value := x.Subject + return protoreflect.ValueOfString(value) + case "svc.v1.Profile.origin": + value := x.Origin + return protoreflect.ValueOfString(value) + case "svc.v1.Profile.controller": + value := x.Controller + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + } + panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Profile) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.Profile.id": + x.Id = value.Interface().(string) + case "svc.v1.Profile.subject": + x.Subject = value.Interface().(string) + case "svc.v1.Profile.origin": + x.Origin = value.Interface().(string) + case "svc.v1.Profile.controller": + x.Controller = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + } + panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Profile) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.Profile.id": + panic(fmt.Errorf("field id of message svc.v1.Profile is not mutable")) + case "svc.v1.Profile.subject": + panic(fmt.Errorf("field subject of message svc.v1.Profile is not mutable")) + case "svc.v1.Profile.origin": + panic(fmt.Errorf("field origin of message svc.v1.Profile is not mutable")) + case "svc.v1.Profile.controller": + panic(fmt.Errorf("field controller of message svc.v1.Profile is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + } + panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Profile) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.Profile.id": + return protoreflect.ValueOfString("") + case "svc.v1.Profile.subject": + return protoreflect.ValueOfString("") + case "svc.v1.Profile.origin": + return protoreflect.ValueOfString("") + case "svc.v1.Profile.controller": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + } + panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Profile) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.Profile", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Profile) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Profile) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Profile) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Profile) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Profile) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Id) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Subject) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Origin) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Controller) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Profile) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Controller) > 0 { + i -= len(x.Controller) + copy(dAtA[i:], x.Controller) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) + i-- + dAtA[i] = 0x22 + } + if len(x.Origin) > 0 { + i -= len(x.Origin) + copy(dAtA[i:], x.Origin) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) + i-- + dAtA[i] = 0x1a + } + if len(x.Subject) > 0 { + i -= len(x.Subject) + copy(dAtA[i:], x.Subject) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Subject))) + i-- + dAtA[i] = 0x12 + } + if len(x.Id) > 0 { + i -= len(x.Id) + copy(dAtA[i:], x.Id) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Id))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Profile) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Profile: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Profile: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Subject = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Origin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Controller = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: svc/v1/state.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Metadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + Category string `protobuf:"bytes,5,opt,name=category,proto3" json:"category,omitempty"` + Icon string `protobuf:"bytes,6,opt,name=icon,proto3" json:"icon,omitempty"` + Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` +} + +func (x *Metadata) Reset() { + *x = Metadata{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_state_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Metadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Metadata) ProtoMessage() {} + +// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. +func (*Metadata) Descriptor() ([]byte, []int) { + return file_svc_v1_state_proto_rawDescGZIP(), []int{0} +} + +func (x *Metadata) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Metadata) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *Metadata) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Metadata) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Metadata) GetCategory() string { + if x != nil { + return x.Category + } + return "" +} + +func (x *Metadata) GetIcon() string { + if x != nil { + return x.Icon + } + return "" +} + +func (x *Metadata) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +// Profile represents a DID alias +type Profile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The unique identifier of the alias + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The alias of the DID + Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` + // Origin of the alias + Origin string `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` + // Controller of the alias + Controller string `protobuf:"bytes,4,opt,name=controller,proto3" json:"controller,omitempty"` +} + +func (x *Profile) Reset() { + *x = Profile{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_state_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Profile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Profile) ProtoMessage() {} + +// Deprecated: Use Profile.ProtoReflect.Descriptor instead. +func (*Profile) Descriptor() ([]byte, []int) { + return file_svc_v1_state_proto_rawDescGZIP(), []int{1} +} + +func (x *Profile) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Profile) GetSubject() string { + if x != nil { + return x.Subject + } + return "" +} + +func (x *Profile) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *Profile) GetController() string { + if x != nil { + return x.Controller + } + return "" +} + +var File_svc_v1_state_proto protoreflect.FileDescriptor + +var file_svc_v1_state_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcc, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, + 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, + 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, + 0x74, 0x61, 0x67, 0x73, 0x3a, 0x1e, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x18, 0x0a, 0x06, 0x0a, 0x02, + 0x69, 0x64, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, + 0x18, 0x01, 0x18, 0x01, 0x22, 0x91, 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x65, 0x72, 0x3a, 0x24, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x1e, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, + 0x12, 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x02, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, + 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x76, 0x63, 0x76, 0x31, 0xa2, 0x02, 0x03, + 0x53, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x53, 0x76, 0x63, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x53, + 0x76, 0x63, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x53, 0x76, 0x63, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x53, 0x76, 0x63, + 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_svc_v1_state_proto_rawDescOnce sync.Once + file_svc_v1_state_proto_rawDescData = file_svc_v1_state_proto_rawDesc +) + +func file_svc_v1_state_proto_rawDescGZIP() []byte { + file_svc_v1_state_proto_rawDescOnce.Do(func() { + file_svc_v1_state_proto_rawDescData = protoimpl.X.CompressGZIP(file_svc_v1_state_proto_rawDescData) + }) + return file_svc_v1_state_proto_rawDescData +} + +var file_svc_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_svc_v1_state_proto_goTypes = []interface{}{ + (*Metadata)(nil), // 0: svc.v1.Metadata + (*Profile)(nil), // 1: svc.v1.Profile +} +var file_svc_v1_state_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_svc_v1_state_proto_init() } +func file_svc_v1_state_proto_init() { + if File_svc_v1_state_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_svc_v1_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Metadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_state_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Profile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_svc_v1_state_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_svc_v1_state_proto_goTypes, + DependencyIndexes: file_svc_v1_state_proto_depIdxs, + MessageInfos: file_svc_v1_state_proto_msgTypes, + }.Build() + File_svc_v1_state_proto = out.File + file_svc_v1_state_proto_rawDesc = nil + file_svc_v1_state_proto_goTypes = nil + file_svc_v1_state_proto_depIdxs = nil +} diff --git a/api/svc/v1/tx.pulsar.go b/api/svc/v1/tx.pulsar.go new file mode 100644 index 000000000..f6ff53eca --- /dev/null +++ b/api/svc/v1/tx.pulsar.go @@ -0,0 +1,2195 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package svcv1 + +import ( + _ "cosmossdk.io/api/cosmos/msg/v1" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_MsgUpdateParams protoreflect.MessageDescriptor + fd_MsgUpdateParams_authority protoreflect.FieldDescriptor + fd_MsgUpdateParams_params protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_tx_proto_init() + md_MsgUpdateParams = File_svc_v1_tx_proto.Messages().ByName("MsgUpdateParams") + fd_MsgUpdateParams_authority = md_MsgUpdateParams.Fields().ByName("authority") + fd_MsgUpdateParams_params = md_MsgUpdateParams.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParams)(nil) + +type fastReflection_MsgUpdateParams MsgUpdateParams + +func (x *MsgUpdateParams) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(x) +} + +func (x *MsgUpdateParams) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_tx_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgUpdateParams_messageType fastReflection_MsgUpdateParams_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParams_messageType{} + +type fastReflection_MsgUpdateParams_messageType struct{} + +func (x fastReflection_MsgUpdateParams_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(nil) +} +func (x fastReflection_MsgUpdateParams_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} +func (x fastReflection_MsgUpdateParams_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParams) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgUpdateParams) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParams_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParams) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParams) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParams)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgUpdateParams) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Authority != "" { + value := protoreflect.ValueOfString(x.Authority) + if !f(fd_MsgUpdateParams_authority, value) { + return + } + } + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_MsgUpdateParams_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.MsgUpdateParams.authority": + return x.Authority != "" + case "svc.v1.MsgUpdateParams.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.MsgUpdateParams.authority": + x.Authority = "" + case "svc.v1.MsgUpdateParams.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgUpdateParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.MsgUpdateParams.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "svc.v1.MsgUpdateParams.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParams does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.MsgUpdateParams.authority": + x.Authority = value.Interface().(string) + case "svc.v1.MsgUpdateParams.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.MsgUpdateParams.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "svc.v1.MsgUpdateParams.authority": + panic(fmt.Errorf("field authority of message svc.v1.MsgUpdateParams is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgUpdateParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.MsgUpdateParams.authority": + return protoreflect.ValueOfString("") + case "svc.v1.MsgUpdateParams.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgUpdateParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.MsgUpdateParams", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgUpdateParams) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgUpdateParams) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgUpdateParams) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Authority) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Authority) > 0 { + i -= len(x.Authority) + copy(dAtA[i:], x.Authority) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgUpdateParamsResponse protoreflect.MessageDescriptor +) + +func init() { + file_svc_v1_tx_proto_init() + md_MsgUpdateParamsResponse = File_svc_v1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParamsResponse)(nil) + +type fastReflection_MsgUpdateParamsResponse MsgUpdateParamsResponse + +func (x *MsgUpdateParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(x) +} + +func (x *MsgUpdateParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_tx_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgUpdateParamsResponse_messageType fastReflection_MsgUpdateParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParamsResponse_messageType{} + +type fastReflection_MsgUpdateParamsResponse_messageType struct{} + +func (x fastReflection_MsgUpdateParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(nil) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgUpdateParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParamsResponse) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParamsResponse) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParamsResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgUpdateParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgUpdateParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgUpdateParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParamsResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgUpdateParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.MsgUpdateParamsResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgUpdateParamsResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgUpdateParamsResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgRegisterService protoreflect.MessageDescriptor + fd_MsgRegisterService_controller protoreflect.FieldDescriptor + fd_MsgRegisterService_service protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_tx_proto_init() + md_MsgRegisterService = File_svc_v1_tx_proto.Messages().ByName("MsgRegisterService") + fd_MsgRegisterService_controller = md_MsgRegisterService.Fields().ByName("controller") + fd_MsgRegisterService_service = md_MsgRegisterService.Fields().ByName("service") +} + +var _ protoreflect.Message = (*fastReflection_MsgRegisterService)(nil) + +type fastReflection_MsgRegisterService MsgRegisterService + +func (x *MsgRegisterService) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgRegisterService)(x) +} + +func (x *MsgRegisterService) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_tx_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgRegisterService_messageType fastReflection_MsgRegisterService_messageType +var _ protoreflect.MessageType = fastReflection_MsgRegisterService_messageType{} + +type fastReflection_MsgRegisterService_messageType struct{} + +func (x fastReflection_MsgRegisterService_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgRegisterService)(nil) +} +func (x fastReflection_MsgRegisterService_messageType) New() protoreflect.Message { + return new(fastReflection_MsgRegisterService) +} +func (x fastReflection_MsgRegisterService_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgRegisterService +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgRegisterService) Descriptor() protoreflect.MessageDescriptor { + return md_MsgRegisterService +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgRegisterService) Type() protoreflect.MessageType { + return _fastReflection_MsgRegisterService_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgRegisterService) New() protoreflect.Message { + return new(fastReflection_MsgRegisterService) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgRegisterService) Interface() protoreflect.ProtoMessage { + return (*MsgRegisterService)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgRegisterService) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Controller != "" { + value := protoreflect.ValueOfString(x.Controller) + if !f(fd_MsgRegisterService_controller, value) { + return + } + } + if x.Service != nil { + value := protoreflect.ValueOfMessage(x.Service.ProtoReflect()) + if !f(fd_MsgRegisterService_service, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgRegisterService) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.MsgRegisterService.controller": + return x.Controller != "" + case "svc.v1.MsgRegisterService.service": + return x.Service != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterService")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterService does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgRegisterService) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.MsgRegisterService.controller": + x.Controller = "" + case "svc.v1.MsgRegisterService.service": + x.Service = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterService")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterService does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgRegisterService) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.MsgRegisterService.controller": + value := x.Controller + return protoreflect.ValueOfString(value) + case "svc.v1.MsgRegisterService.service": + value := x.Service + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterService")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterService does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgRegisterService) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.MsgRegisterService.controller": + x.Controller = value.Interface().(string) + case "svc.v1.MsgRegisterService.service": + x.Service = value.Message().Interface().(*Service) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterService")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterService does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgRegisterService) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.MsgRegisterService.service": + if x.Service == nil { + x.Service = new(Service) + } + return protoreflect.ValueOfMessage(x.Service.ProtoReflect()) + case "svc.v1.MsgRegisterService.controller": + panic(fmt.Errorf("field controller of message svc.v1.MsgRegisterService is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterService")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterService does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgRegisterService) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.MsgRegisterService.controller": + return protoreflect.ValueOfString("") + case "svc.v1.MsgRegisterService.service": + m := new(Service) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterService")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterService does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgRegisterService) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.MsgRegisterService", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgRegisterService) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgRegisterService) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgRegisterService) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgRegisterService) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgRegisterService) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Controller) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Service != nil { + l = options.Size(x.Service) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgRegisterService) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Service != nil { + encoded, err := options.Marshal(x.Service) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Controller) > 0 { + i -= len(x.Controller) + copy(dAtA[i:], x.Controller) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgRegisterService) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgRegisterService: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgRegisterService: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Controller = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Service == nil { + x.Service = &Service{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Service); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgRegisterServiceResponse protoreflect.MessageDescriptor + fd_MsgRegisterServiceResponse_success protoreflect.FieldDescriptor + fd_MsgRegisterServiceResponse_did protoreflect.FieldDescriptor +) + +func init() { + file_svc_v1_tx_proto_init() + md_MsgRegisterServiceResponse = File_svc_v1_tx_proto.Messages().ByName("MsgRegisterServiceResponse") + fd_MsgRegisterServiceResponse_success = md_MsgRegisterServiceResponse.Fields().ByName("success") + fd_MsgRegisterServiceResponse_did = md_MsgRegisterServiceResponse.Fields().ByName("did") +} + +var _ protoreflect.Message = (*fastReflection_MsgRegisterServiceResponse)(nil) + +type fastReflection_MsgRegisterServiceResponse MsgRegisterServiceResponse + +func (x *MsgRegisterServiceResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgRegisterServiceResponse)(x) +} + +func (x *MsgRegisterServiceResponse) slowProtoReflect() protoreflect.Message { + mi := &file_svc_v1_tx_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgRegisterServiceResponse_messageType fastReflection_MsgRegisterServiceResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgRegisterServiceResponse_messageType{} + +type fastReflection_MsgRegisterServiceResponse_messageType struct{} + +func (x fastReflection_MsgRegisterServiceResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgRegisterServiceResponse)(nil) +} +func (x fastReflection_MsgRegisterServiceResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgRegisterServiceResponse) +} +func (x fastReflection_MsgRegisterServiceResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgRegisterServiceResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgRegisterServiceResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgRegisterServiceResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgRegisterServiceResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgRegisterServiceResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgRegisterServiceResponse) New() protoreflect.Message { + return new(fastReflection_MsgRegisterServiceResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgRegisterServiceResponse) Interface() protoreflect.ProtoMessage { + return (*MsgRegisterServiceResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgRegisterServiceResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Success != false { + value := protoreflect.ValueOfBool(x.Success) + if !f(fd_MsgRegisterServiceResponse_success, value) { + return + } + } + if x.Did != "" { + value := protoreflect.ValueOfString(x.Did) + if !f(fd_MsgRegisterServiceResponse_did, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgRegisterServiceResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "svc.v1.MsgRegisterServiceResponse.success": + return x.Success != false + case "svc.v1.MsgRegisterServiceResponse.did": + return x.Did != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterServiceResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgRegisterServiceResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "svc.v1.MsgRegisterServiceResponse.success": + x.Success = false + case "svc.v1.MsgRegisterServiceResponse.did": + x.Did = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterServiceResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgRegisterServiceResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "svc.v1.MsgRegisterServiceResponse.success": + value := x.Success + return protoreflect.ValueOfBool(value) + case "svc.v1.MsgRegisterServiceResponse.did": + value := x.Did + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterServiceResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterServiceResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgRegisterServiceResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "svc.v1.MsgRegisterServiceResponse.success": + x.Success = value.Bool() + case "svc.v1.MsgRegisterServiceResponse.did": + x.Did = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterServiceResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgRegisterServiceResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.MsgRegisterServiceResponse.success": + panic(fmt.Errorf("field success of message svc.v1.MsgRegisterServiceResponse is not mutable")) + case "svc.v1.MsgRegisterServiceResponse.did": + panic(fmt.Errorf("field did of message svc.v1.MsgRegisterServiceResponse is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterServiceResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgRegisterServiceResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "svc.v1.MsgRegisterServiceResponse.success": + return protoreflect.ValueOfBool(false) + case "svc.v1.MsgRegisterServiceResponse.did": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.MsgRegisterServiceResponse")) + } + panic(fmt.Errorf("message svc.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgRegisterServiceResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in svc.v1.MsgRegisterServiceResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgRegisterServiceResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgRegisterServiceResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgRegisterServiceResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgRegisterServiceResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgRegisterServiceResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Success { + n += 2 + } + l = len(x.Did) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgRegisterServiceResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Did) > 0 { + i -= len(x.Did) + copy(dAtA[i:], x.Did) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Did))) + i-- + dAtA[i] = 0x12 + } + if x.Success { + i-- + if x.Success { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgRegisterServiceResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgRegisterServiceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgRegisterServiceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.Success = bool(v != 0) + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Did", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Did = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: svc/v1/tx.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// MsgUpdateParams is the Msg/UpdateParams request type. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *MsgUpdateParams) Reset() { + *x = MsgUpdateParams{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_tx_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParams) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParams.ProtoReflect.Descriptor instead. +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return file_svc_v1_tx_proto_rawDescGZIP(), []int{0} +} + +func (x *MsgUpdateParams) GetAuthority() string { + if x != nil { + return x.Authority + } + return "" +} + +func (x *MsgUpdateParams) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MsgUpdateParamsResponse) Reset() { + *x = MsgUpdateParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_tx_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParamsResponse) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParamsResponse.ProtoReflect.Descriptor instead. +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return file_svc_v1_tx_proto_rawDescGZIP(), []int{1} +} + +// MsgRegisterService is the message type for the RegisterService RPC. +type MsgRegisterService struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // authority is the address of the governance account. + Controller string `protobuf:"bytes,1,opt,name=controller,proto3" json:"controller,omitempty"` + // origin is the origin of the request in wildcard form. Requires valid TXT + // record in DNS. + Service *Service `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"` +} + +func (x *MsgRegisterService) Reset() { + *x = MsgRegisterService{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_tx_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgRegisterService) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgRegisterService) ProtoMessage() {} + +// Deprecated: Use MsgRegisterService.ProtoReflect.Descriptor instead. +func (*MsgRegisterService) Descriptor() ([]byte, []int) { + return file_svc_v1_tx_proto_rawDescGZIP(), []int{2} +} + +func (x *MsgRegisterService) GetController() string { + if x != nil { + return x.Controller + } + return "" +} + +func (x *MsgRegisterService) GetService() *Service { + if x != nil { + return x.Service + } + return nil +} + +// MsgRegisterServiceResponse is the response type for the RegisterService RPC. +type MsgRegisterServiceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Did string `protobuf:"bytes,2,opt,name=did,proto3" json:"did,omitempty"` +} + +func (x *MsgRegisterServiceResponse) Reset() { + *x = MsgRegisterServiceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_svc_v1_tx_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgRegisterServiceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgRegisterServiceResponse) ProtoMessage() {} + +// Deprecated: Use MsgRegisterServiceResponse.ProtoReflect.Descriptor instead. +func (*MsgRegisterServiceResponse) Descriptor() ([]byte, []int) { + return file_svc_v1_tx_proto_rawDescGZIP(), []int{3} +} + +func (x *MsgRegisterServiceResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *MsgRegisterServiceResponse) GetDid() string { + if x != nil { + return x.Did + } + return "" +} + +var File_svc_v1_tx_proto protoreflect.FileDescriptor + +var file_svc_v1_tx_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x06, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x14, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, + 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x87, 0x01, 0x0a, 0x0f, 0x4d, 0x73, + 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8a, + 0x01, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, + 0x29, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x0f, 0x82, 0xe7, 0xb0, 0x2a, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, 0x48, 0x0a, 0x1a, 0x4d, + 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x64, 0x69, 0x64, 0x32, 0xa9, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x48, 0x0a, + 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x17, 0x2e, + 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1f, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x76, 0x63, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x22, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, + 0x01, 0x42, 0x77, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x42, + 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, + 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x76, + 0x63, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x53, 0x76, 0x63, 0x2e, + 0x56, 0x31, 0xca, 0x02, 0x06, 0x53, 0x76, 0x63, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x53, 0x76, + 0x63, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x07, 0x53, 0x76, 0x63, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_svc_v1_tx_proto_rawDescOnce sync.Once + file_svc_v1_tx_proto_rawDescData = file_svc_v1_tx_proto_rawDesc +) + +func file_svc_v1_tx_proto_rawDescGZIP() []byte { + file_svc_v1_tx_proto_rawDescOnce.Do(func() { + file_svc_v1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_svc_v1_tx_proto_rawDescData) + }) + return file_svc_v1_tx_proto_rawDescData +} + +var file_svc_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_svc_v1_tx_proto_goTypes = []interface{}{ + (*MsgUpdateParams)(nil), // 0: svc.v1.MsgUpdateParams + (*MsgUpdateParamsResponse)(nil), // 1: svc.v1.MsgUpdateParamsResponse + (*MsgRegisterService)(nil), // 2: svc.v1.MsgRegisterService + (*MsgRegisterServiceResponse)(nil), // 3: svc.v1.MsgRegisterServiceResponse + (*Params)(nil), // 4: svc.v1.Params + (*Service)(nil), // 5: svc.v1.Service +} +var file_svc_v1_tx_proto_depIdxs = []int32{ + 4, // 0: svc.v1.MsgUpdateParams.params:type_name -> svc.v1.Params + 5, // 1: svc.v1.MsgRegisterService.service:type_name -> svc.v1.Service + 0, // 2: svc.v1.Msg.UpdateParams:input_type -> svc.v1.MsgUpdateParams + 2, // 3: svc.v1.Msg.RegisterService:input_type -> svc.v1.MsgRegisterService + 1, // 4: svc.v1.Msg.UpdateParams:output_type -> svc.v1.MsgUpdateParamsResponse + 3, // 5: svc.v1.Msg.RegisterService:output_type -> svc.v1.MsgRegisterServiceResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_svc_v1_tx_proto_init() } +func file_svc_v1_tx_proto_init() { + if File_svc_v1_tx_proto != nil { + return + } + file_svc_v1_genesis_proto_init() + if !protoimpl.UnsafeEnabled { + file_svc_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParamsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_tx_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgRegisterService); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_svc_v1_tx_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgRegisterServiceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_svc_v1_tx_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_svc_v1_tx_proto_goTypes, + DependencyIndexes: file_svc_v1_tx_proto_depIdxs, + MessageInfos: file_svc_v1_tx_proto_msgTypes, + }.Build() + File_svc_v1_tx_proto = out.File + file_svc_v1_tx_proto_rawDesc = nil + file_svc_v1_tx_proto_goTypes = nil + file_svc_v1_tx_proto_depIdxs = nil +} diff --git a/api/svc/v1/tx_grpc.pb.go b/api/svc/v1/tx_grpc.pb.go new file mode 100644 index 000000000..d180765e2 --- /dev/null +++ b/api/svc/v1/tx_grpc.pb.go @@ -0,0 +1,173 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: svc/v1/tx.proto + +package svcv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Msg_UpdateParams_FullMethodName = "/svc.v1.Msg/UpdateParams" + Msg_RegisterService_FullMethodName = "/svc.v1.Msg/RegisterService" +) + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// Msg defines the Msg service. +type MsgClient interface { + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + // RegisterService initializes a Service with a given permission scope and + // URI. The domain must have a valid TXT record containing the public key. + RegisterService(ctx context.Context, in *MsgRegisterService, opts ...grpc.CallOption) (*MsgRegisterServiceResponse, error) +} + +type msgClient struct { + cc grpc.ClientConnInterface +} + +func NewMsgClient(cc grpc.ClientConnInterface) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, Msg_UpdateParams_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) RegisterService(ctx context.Context, in *MsgRegisterService, opts ...grpc.CallOption) (*MsgRegisterServiceResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MsgRegisterServiceResponse) + err := c.cc.Invoke(ctx, Msg_RegisterService_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +// All implementations must embed UnimplementedMsgServer +// for forward compatibility. +// +// Msg defines the Msg service. +type MsgServer interface { + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + // RegisterService initializes a Service with a given permission scope and + // URI. The domain must have a valid TXT record containing the public key. + RegisterService(context.Context, *MsgRegisterService) (*MsgRegisterServiceResponse, error) + mustEmbedUnimplementedMsgServer() +} + +// UnimplementedMsgServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedMsgServer struct{} + +func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} +func (UnimplementedMsgServer) RegisterService(context.Context, *MsgRegisterService) (*MsgRegisterServiceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterService not implemented") +} +func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} +func (UnimplementedMsgServer) testEmbeddedByValue() {} + +// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MsgServer will +// result in compilation errors. +type UnsafeMsgServer interface { + mustEmbedUnimplementedMsgServer() +} + +func RegisterMsgServer(s grpc.ServiceRegistrar, srv MsgServer) { + // If the following call pancis, it indicates UnimplementedMsgServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Msg_ServiceDesc, srv) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_UpdateParams_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_RegisterService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRegisterService) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RegisterService(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_RegisterService_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RegisterService(ctx, req.(*MsgRegisterService)) + } + return interceptor(ctx, in, info, handler) +} + +// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Msg_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "svc.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + { + MethodName: "RegisterService", + Handler: _Msg_RegisterService_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "svc/v1/tx.proto", +} diff --git a/api/vault/v1/tx.pulsar.go b/api/vault/v1/tx.pulsar.go index 3cc1f3899..56a4ef6b0 100644 --- a/api/vault/v1/tx.pulsar.go +++ b/api/vault/v1/tx.pulsar.go @@ -871,6 +871,861 @@ func (x *fastReflection_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Meth } } +var ( + md_MsgInitialize protoreflect.MessageDescriptor + fd_MsgInitialize_authority protoreflect.FieldDescriptor + fd_MsgInitialize_params protoreflect.FieldDescriptor +) + +func init() { + file_vault_v1_tx_proto_init() + md_MsgInitialize = File_vault_v1_tx_proto.Messages().ByName("MsgInitialize") + fd_MsgInitialize_authority = md_MsgInitialize.Fields().ByName("authority") + fd_MsgInitialize_params = md_MsgInitialize.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_MsgInitialize)(nil) + +type fastReflection_MsgInitialize MsgInitialize + +func (x *MsgInitialize) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgInitialize)(x) +} + +func (x *MsgInitialize) slowProtoReflect() protoreflect.Message { + mi := &file_vault_v1_tx_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgInitialize_messageType fastReflection_MsgInitialize_messageType +var _ protoreflect.MessageType = fastReflection_MsgInitialize_messageType{} + +type fastReflection_MsgInitialize_messageType struct{} + +func (x fastReflection_MsgInitialize_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgInitialize)(nil) +} +func (x fastReflection_MsgInitialize_messageType) New() protoreflect.Message { + return new(fastReflection_MsgInitialize) +} +func (x fastReflection_MsgInitialize_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgInitialize +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgInitialize) Descriptor() protoreflect.MessageDescriptor { + return md_MsgInitialize +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgInitialize) Type() protoreflect.MessageType { + return _fastReflection_MsgInitialize_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgInitialize) New() protoreflect.Message { + return new(fastReflection_MsgInitialize) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgInitialize) Interface() protoreflect.ProtoMessage { + return (*MsgInitialize)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgInitialize) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Authority != "" { + value := protoreflect.ValueOfString(x.Authority) + if !f(fd_MsgInitialize_authority, value) { + return + } + } + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_MsgInitialize_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgInitialize) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "vault.v1.MsgInitialize.authority": + return x.Authority != "" + case "vault.v1.MsgInitialize.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) + } + panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitialize) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "vault.v1.MsgInitialize.authority": + x.Authority = "" + case "vault.v1.MsgInitialize.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) + } + panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgInitialize) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "vault.v1.MsgInitialize.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "vault.v1.MsgInitialize.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) + } + panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitialize) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "vault.v1.MsgInitialize.authority": + x.Authority = value.Interface().(string) + case "vault.v1.MsgInitialize.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) + } + panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitialize) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "vault.v1.MsgInitialize.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "vault.v1.MsgInitialize.authority": + panic(fmt.Errorf("field authority of message vault.v1.MsgInitialize is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) + } + panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgInitialize) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "vault.v1.MsgInitialize.authority": + return protoreflect.ValueOfString("") + case "vault.v1.MsgInitialize.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) + } + panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgInitialize) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in vault.v1.MsgInitialize", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgInitialize) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitialize) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgInitialize) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgInitialize) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgInitialize) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Authority) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgInitialize) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Authority) > 0 { + i -= len(x.Authority) + copy(dAtA[i:], x.Authority) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgInitialize) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitialize: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitialize: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgInitializeResponse protoreflect.MessageDescriptor +) + +func init() { + file_vault_v1_tx_proto_init() + md_MsgInitializeResponse = File_vault_v1_tx_proto.Messages().ByName("MsgInitializeResponse") +} + +var _ protoreflect.Message = (*fastReflection_MsgInitializeResponse)(nil) + +type fastReflection_MsgInitializeResponse MsgInitializeResponse + +func (x *MsgInitializeResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgInitializeResponse)(x) +} + +func (x *MsgInitializeResponse) slowProtoReflect() protoreflect.Message { + mi := &file_vault_v1_tx_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgInitializeResponse_messageType fastReflection_MsgInitializeResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgInitializeResponse_messageType{} + +type fastReflection_MsgInitializeResponse_messageType struct{} + +func (x fastReflection_MsgInitializeResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgInitializeResponse)(nil) +} +func (x fastReflection_MsgInitializeResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgInitializeResponse) +} +func (x fastReflection_MsgInitializeResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgInitializeResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgInitializeResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgInitializeResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgInitializeResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgInitializeResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgInitializeResponse) New() protoreflect.Message { + return new(fastReflection_MsgInitializeResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgInitializeResponse) Interface() protoreflect.ProtoMessage { + return (*MsgInitializeResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgInitializeResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgInitializeResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitializeResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgInitializeResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitializeResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitializeResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgInitializeResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) + } + panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgInitializeResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in vault.v1.MsgInitializeResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgInitializeResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgInitializeResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgInitializeResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgInitializeResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgInitializeResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgInitializeResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgInitializeResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitializeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitializeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.0 @@ -964,6 +1819,87 @@ func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { return file_vault_v1_tx_proto_rawDescGZIP(), []int{1} } +// MsgInitialize spawns a New Vault with Unclaimed State. This is a one-time +// operation that must be performed interacting with the Vault. +// +// Since: cosmos-sdk 0.47 +type MsgInitialize struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *MsgInitialize) Reset() { + *x = MsgInitialize{} + if protoimpl.UnsafeEnabled { + mi := &file_vault_v1_tx_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgInitialize) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgInitialize) ProtoMessage() {} + +// Deprecated: Use MsgInitialize.ProtoReflect.Descriptor instead. +func (*MsgInitialize) Descriptor() ([]byte, []int) { + return file_vault_v1_tx_proto_rawDescGZIP(), []int{2} +} + +func (x *MsgInitialize) GetAuthority() string { + if x != nil { + return x.Authority + } + return "" +} + +func (x *MsgInitialize) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// MsgInitializeResponse defines the response structure for executing a +// MsgInitialize message. +// +// Since: cosmos-sdk 0.47 +type MsgInitializeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MsgInitializeResponse) Reset() { + *x = MsgInitializeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vault_v1_tx_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgInitializeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgInitializeResponse) ProtoMessage() {} + +// Deprecated: Use MsgInitializeResponse.ProtoReflect.Descriptor instead. +func (*MsgInitializeResponse) Descriptor() ([]byte, []int) { + return file_vault_v1_tx_proto_rawDescGZIP(), []int{3} +} + var File_vault_v1_tx_proto protoreflect.FileDescriptor var file_vault_v1_tx_proto_rawDesc = []byte{ @@ -987,21 +1923,36 @@ var file_vault_v1_tx_proto_rawDesc = []byte{ 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x5a, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x4c, 0x0a, 0x0c, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x19, 0x2e, 0x76, 0x61, - 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x21, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, - 0x42, 0x85, 0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, - 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, - 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, - 0x31, 0x3b, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x56, 0x58, 0x58, 0xaa, - 0x02, 0x08, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x56, 0x61, 0x75, - 0x6c, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x56, - 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2e, + 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x0e, + 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x17, + 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa2, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, + 0x4c, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x19, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x21, 0x2e, 0x76, 0x61, 0x75, + 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, + 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x17, 0x2e, 0x76, 0x61, + 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x1a, 0x1f, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x85, 0x01, 0x0a, + 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, + 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x61, + 0x75, 0x6c, 0x74, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x56, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x56, 0x61, + 0x75, 0x6c, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x14, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x56, 0x61, 0x75, 0x6c, 0x74, + 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1016,21 +1967,26 @@ func file_vault_v1_tx_proto_rawDescGZIP() []byte { return file_vault_v1_tx_proto_rawDescData } -var file_vault_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_vault_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_vault_v1_tx_proto_goTypes = []interface{}{ (*MsgUpdateParams)(nil), // 0: vault.v1.MsgUpdateParams (*MsgUpdateParamsResponse)(nil), // 1: vault.v1.MsgUpdateParamsResponse - (*Params)(nil), // 2: vault.v1.Params + (*MsgInitialize)(nil), // 2: vault.v1.MsgInitialize + (*MsgInitializeResponse)(nil), // 3: vault.v1.MsgInitializeResponse + (*Params)(nil), // 4: vault.v1.Params } var file_vault_v1_tx_proto_depIdxs = []int32{ - 2, // 0: vault.v1.MsgUpdateParams.params:type_name -> vault.v1.Params - 0, // 1: vault.v1.Msg.UpdateParams:input_type -> vault.v1.MsgUpdateParams - 1, // 2: vault.v1.Msg.UpdateParams:output_type -> vault.v1.MsgUpdateParamsResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 4, // 0: vault.v1.MsgUpdateParams.params:type_name -> vault.v1.Params + 4, // 1: vault.v1.MsgInitialize.params:type_name -> vault.v1.Params + 0, // 2: vault.v1.Msg.UpdateParams:input_type -> vault.v1.MsgUpdateParams + 2, // 3: vault.v1.Msg.Initialize:input_type -> vault.v1.MsgInitialize + 1, // 4: vault.v1.Msg.UpdateParams:output_type -> vault.v1.MsgUpdateParamsResponse + 3, // 5: vault.v1.Msg.Initialize:output_type -> vault.v1.MsgInitializeResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_vault_v1_tx_proto_init() } @@ -1064,6 +2020,30 @@ func file_vault_v1_tx_proto_init() { return nil } } + file_vault_v1_tx_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgInitialize); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vault_v1_tx_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgInitializeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1071,7 +2051,7 @@ func file_vault_v1_tx_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vault_v1_tx_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 4, NumExtensions: 0, NumServices: 1, }, diff --git a/api/vault/v1/tx_grpc.pb.go b/api/vault/v1/tx_grpc.pb.go index 1d0528abe..958bd6cd2 100644 --- a/api/vault/v1/tx_grpc.pb.go +++ b/api/vault/v1/tx_grpc.pb.go @@ -20,6 +20,7 @@ const _ = grpc.SupportPackageIsVersion9 const ( Msg_UpdateParams_FullMethodName = "/vault.v1.Msg/UpdateParams" + Msg_Initialize_FullMethodName = "/vault.v1.Msg/Initialize" ) // MsgClient is the client API for Msg service. @@ -32,6 +33,8 @@ type MsgClient interface { // // Since: cosmos-sdk 0.47 UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + // Initialize spawns a new Vault + Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error) } type msgClient struct { @@ -52,6 +55,16 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts return out, nil } +func (c *msgClient) Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MsgInitializeResponse) + err := c.cc.Invoke(ctx, Msg_Initialize_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. // All implementations must embed UnimplementedMsgServer // for forward compatibility. @@ -62,6 +75,8 @@ type MsgServer interface { // // Since: cosmos-sdk 0.47 UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + // Initialize spawns a new Vault + Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error) mustEmbedUnimplementedMsgServer() } @@ -75,6 +90,9 @@ type UnimplementedMsgServer struct{} func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") } +func (UnimplementedMsgServer) Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Initialize not implemented") +} func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} func (UnimplementedMsgServer) testEmbeddedByValue() {} @@ -114,6 +132,24 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_Initialize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgInitialize) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Initialize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_Initialize_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Initialize(ctx, req.(*MsgInitialize)) + } + return interceptor(ctx, in, info, handler) +} + // Msg_ServiceDesc is the grpc.ServiceDesc for Msg service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -125,6 +161,10 @@ var Msg_ServiceDesc = grpc.ServiceDesc{ MethodName: "UpdateParams", Handler: _Msg_UpdateParams_Handler, }, + { + MethodName: "Initialize", + Handler: _Msg_Initialize_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "vault/v1/tx.proto", diff --git a/app/app.go b/app/app.go index 29a60e11c..6a983b746 100644 --- a/app/app.go +++ b/app/app.go @@ -134,6 +134,15 @@ import ( ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + did "github.com/onsonr/sonr/x/did" + didkeeper "github.com/onsonr/sonr/x/did/keeper" + didtypes "github.com/onsonr/sonr/x/did/types" + dwn "github.com/onsonr/sonr/x/dwn" + dwnkeeper "github.com/onsonr/sonr/x/dwn/keeper" + dwntypes "github.com/onsonr/sonr/x/dwn/types" + svc "github.com/onsonr/sonr/x/svc" + svckeeper "github.com/onsonr/sonr/x/svc/keeper" + svctypes "github.com/onsonr/sonr/x/svc/types" "github.com/spf13/cast" globalfee "github.com/strangelove-ventures/globalfee/x/globalfee" globalfeekeeper "github.com/strangelove-ventures/globalfee/x/globalfee/keeper" @@ -144,16 +153,6 @@ import ( tokenfactory "github.com/strangelove-ventures/tokenfactory/x/tokenfactory" tokenfactorykeeper "github.com/strangelove-ventures/tokenfactory/x/tokenfactory/keeper" tokenfactorytypes "github.com/strangelove-ventures/tokenfactory/x/tokenfactory/types" - - did "github.com/onsonr/sonr/x/did" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - didtypes "github.com/onsonr/sonr/x/did/types" - service "github.com/onsonr/sonr/x/service" - servicekeeper "github.com/onsonr/sonr/x/service/keeper" - servicetypes "github.com/onsonr/sonr/x/service/types" - vault "github.com/onsonr/sonr/x/vault" - vaultkeeper "github.com/onsonr/sonr/x/vault/keeper" - vaulttypes "github.com/onsonr/sonr/x/vault/types" ) const appName = "sonr" @@ -232,8 +231,8 @@ type SonrApp struct { CrisisKeeper *crisiskeeper.Keeper UpgradeKeeper *upgradekeeper.Keeper legacyAmino *codec.LegacyAmino - VaultKeeper vaultkeeper.Keeper - ServiceKeeper servicekeeper.Keeper + DwnKeeper dwnkeeper.Keeper + SvcKeeper svckeeper.Keeper sm *module.SimulationManager BasicModuleManager module.BasicManager ModuleManager *module.Manager @@ -366,8 +365,8 @@ func NewChainApp( globalfeetypes.StoreKey, packetforwardtypes.StoreKey, didtypes.StoreKey, - vaulttypes.StoreKey, - servicetypes.StoreKey, + dwntypes.StoreKey, + svctypes.StoreKey, ) tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey) @@ -627,28 +626,43 @@ func NewChainApp( app.StakingKeeper, ) - // Create the vault Keeper - app.VaultKeeper = vaultkeeper.NewKeeper( + // Create the svc Keeper + app.SvcKeeper = svckeeper.NewKeeper( appCodec, - sdkruntime.NewKVStoreService(keys[vaulttypes.StoreKey]), + sdkruntime.NewKVStoreService(keys[svctypes.StoreKey]), logger, authtypes.NewModuleAddress(govtypes.ModuleName).String(), - app.AccountKeeper, - app.DidKeeper, ) - // Create the service Keeper - app.ServiceKeeper = servicekeeper.NewKeeper( + // Create the dwn Keeper + app.DwnKeeper = dwnkeeper.NewKeeper( appCodec, - sdkruntime.NewKVStoreService(keys[servicetypes.StoreKey]), + sdkruntime.NewKVStoreService(keys[dwntypes.StoreKey]), logger, authtypes.NewModuleAddress(govtypes.ModuleName).String(), - app.DidKeeper, - app.GroupKeeper, - app.NFTKeeper, - app.VaultKeeper, ) - + // // Create the vault Keeper + // app.VaultKeeper = vaultkeeper.NewKeeper( + // appCodec, + // sdkruntime.NewKVStoreService(keys[vaulttypes.StoreKey]), + // logger, + // authtypes.NewModuleAddress(govtypes.ModuleName).String(), + // app.AccountKeeper, + // app.DidKeeper, + // ) + // + // // Create the service Keeper + // app.ServiceKeeper = servicekeeper.NewKeeper( + // appCodec, + // sdkruntime.NewKVStoreService(keys[servicetypes.StoreKey]), + // logger, + // authtypes.NewModuleAddress(govtypes.ModuleName).String(), + // app.DidKeeper, + // app.GroupKeeper, + // app.NFTKeeper, + // app.VaultKeeper, + // ) + // // Create the globalfee keeper app.GlobalFeeKeeper = globalfeekeeper.NewKeeper( appCodec, @@ -906,10 +920,8 @@ func NewChainApp( ), did.NewAppModule(appCodec, app.DidKeeper, app.NFTKeeper), - - vault.NewAppModule(appCodec, app.VaultKeeper, app.DidKeeper), - - service.NewAppModule(appCodec, app.ServiceKeeper, app.DidKeeper), + dwn.NewAppModule(appCodec, app.DwnKeeper), + svc.NewAppModule(appCodec, app.SvcKeeper), ) // BasicModuleManager defines the module BasicManager is in charge of setting up basic, @@ -958,8 +970,8 @@ func NewChainApp( tokenfactorytypes.ModuleName, packetforwardtypes.ModuleName, didtypes.ModuleName, - vaulttypes.ModuleName, - servicetypes.ModuleName, + dwntypes.ModuleName, + svctypes.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( @@ -979,8 +991,8 @@ func NewChainApp( tokenfactorytypes.ModuleName, packetforwardtypes.ModuleName, didtypes.ModuleName, - vaulttypes.ModuleName, - servicetypes.ModuleName, + dwntypes.ModuleName, + svctypes.ModuleName, ) // NOTE: The genutils module must occur after staking so that pools are @@ -1009,8 +1021,8 @@ func NewChainApp( globalfeetypes.ModuleName, packetforwardtypes.ModuleName, didtypes.ModuleName, - vaulttypes.ModuleName, - servicetypes.ModuleName, + dwntypes.ModuleName, + svctypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...) @@ -1469,8 +1481,8 @@ func initParamsKeeper( paramsKeeper.Subspace(packetforwardtypes.ModuleName). WithKeyTable(packetforwardtypes.ParamKeyTable()) paramsKeeper.Subspace(didtypes.ModuleName) - paramsKeeper.Subspace(vaulttypes.ModuleName) - paramsKeeper.Subspace(servicetypes.ModuleName) + paramsKeeper.Subspace(dwntypes.ModuleName) + paramsKeeper.Subspace(svctypes.ModuleName) return paramsKeeper } diff --git a/proto/README.md b/proto/README.md index d99969d9a..ebc553d74 100644 --- a/proto/README.md +++ b/proto/README.md @@ -10,10 +10,10 @@ This directory contains the protobuf definitions for the Sonr blockchain. The `did` directory contains the protobuf definitions for the DID module. -### `service` +### `dwn` + +The `dwn` directory contains the protobuf definitions for the Vault module. + +### `svc` The `service` directory contains the protobuf definitions for the Service module. - -### `vault` - -The `vault` directory contains the protobuf definitions for the Vault module. diff --git a/proto/service/module/v1/module.proto b/proto/dwn/module/v1/module.proto similarity index 64% rename from proto/service/module/v1/module.proto rename to proto/dwn/module/v1/module.proto index 15a603131..9d5c54aaa 100644 --- a/proto/service/module/v1/module.proto +++ b/proto/dwn/module/v1/module.proto @@ -1,11 +1,13 @@ syntax = "proto3"; -package service.module.v1; +package dwn.module.v1; import "cosmos/app/v1alpha1/module.proto"; // Module is the app config object of the module. // Learn more: https://docs.cosmos.network/main/building-modules/depinject message Module { - option (cosmos.app.v1alpha1.module) = {go_import: "github.com/onsonr/sonr"}; -} + option (cosmos.app.v1alpha1.module) = { + go_import : "github.com/onsonr/sonr" + }; +} \ No newline at end of file diff --git a/proto/vault/v1/genesis.proto b/proto/dwn/v1/genesis.proto similarity index 84% rename from proto/vault/v1/genesis.proto rename to proto/dwn/v1/genesis.proto index 1381baba8..5a8198483 100644 --- a/proto/vault/v1/genesis.proto +++ b/proto/dwn/v1/genesis.proto @@ -1,17 +1,16 @@ syntax = "proto3"; -package vault.v1; +package dwn.v1; -import "amino/amino.proto"; import "gogoproto/gogo.proto"; +import "amino/amino.proto"; -option go_package = "github.com/onsonr/sonr/x/vault/types"; +option go_package = "github.com/onsonr/sonr/x/dwn/types"; // GenesisState defines the module genesis state message GenesisState { // Params defines all the parameters of the module. - Params params = 1 [ (gogoproto.nullable) = false ]; + Params params = 1 [(gogoproto.nullable) = false]; } - // Params defines the set of module parameters. message Params { option (amino.name) = "vault/params"; @@ -35,3 +34,4 @@ message Schema { string keyshare = 9; string profile = 10; } + diff --git a/proto/vault/v1/query.proto b/proto/dwn/v1/query.proto similarity index 96% rename from proto/vault/v1/query.proto rename to proto/dwn/v1/query.proto index 3792c6d8f..d7819098f 100644 --- a/proto/vault/v1/query.proto +++ b/proto/dwn/v1/query.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package vault.v1; +package dwn.v1; import "google/api/annotations.proto"; -import "vault/v1/genesis.proto"; +import "dwn/v1/genesis.proto"; -option go_package = "github.com/onsonr/sonr/x/vault/types"; +option go_package = "github.com/onsonr/sonr/x/dwn/types"; // ╭─────────────────────────────────────────────────────────╮ // │ RPC Query Service │ diff --git a/proto/dwn/v1/state.proto b/proto/dwn/v1/state.proto new file mode 100644 index 000000000..fa5ba9440 --- /dev/null +++ b/proto/dwn/v1/state.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package dwn.v1; + +import "cosmos/orm/v1/orm.proto"; + +option go_package = "github.com/onsonr/sonr/x/dwn/types"; + +// https://github.com/cosmos/cosmos-sdk/blob/main/orm/README.md + +message ExampleData { + option (cosmos.orm.v1.table) = { + id: 1; + primary_key: { fields: "account" } + index: { id: 1 fields: "amount" } + }; + + bytes account = 1; + uint64 amount = 2; +} \ No newline at end of file diff --git a/proto/vault/v1/tx.proto b/proto/dwn/v1/tx.proto similarity index 92% rename from proto/vault/v1/tx.proto rename to proto/dwn/v1/tx.proto index 71a94dadb..b23424a44 100644 --- a/proto/vault/v1/tx.proto +++ b/proto/dwn/v1/tx.proto @@ -1,13 +1,12 @@ syntax = "proto3"; -package vault.v1; +package dwn.v1; import "cosmos/msg/v1/msg.proto"; -import "cosmos_proto/cosmos.proto"; +import "dwn/v1/genesis.proto"; import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "vault/v1/genesis.proto"; +import "cosmos_proto/cosmos.proto"; -option go_package = "github.com/onsonr/sonr/x/vault/types"; +option go_package = "github.com/onsonr/sonr/x/dwn/types"; // Msg defines the Msg service. service Msg { diff --git a/proto/vault/module/v1/module.proto b/proto/svc/module/v1/module.proto similarity index 64% rename from proto/vault/module/v1/module.proto rename to proto/svc/module/v1/module.proto index c3d0166ee..e9a87b178 100644 --- a/proto/vault/module/v1/module.proto +++ b/proto/svc/module/v1/module.proto @@ -1,11 +1,13 @@ syntax = "proto3"; -package vault.module.v1; +package svc.module.v1; import "cosmos/app/v1alpha1/module.proto"; // Module is the app config object of the module. // Learn more: https://docs.cosmos.network/main/building-modules/depinject message Module { - option (cosmos.app.v1alpha1.module) = {go_import: "github.com/onsonr/sonr"}; -} + option (cosmos.app.v1alpha1.module) = { + go_import : "github.com/onsonr/sonr" + }; +} \ No newline at end of file diff --git a/proto/service/v1/genesis.proto b/proto/svc/v1/genesis.proto similarity index 92% rename from proto/service/v1/genesis.proto rename to proto/svc/v1/genesis.proto index 236b258f3..e6c114868 100644 --- a/proto/service/v1/genesis.proto +++ b/proto/svc/v1/genesis.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package service.v1; +package svc.v1; -import "amino/amino.proto"; import "gogoproto/gogo.proto"; +import "amino/amino.proto"; -option go_package = "github.com/onsonr/sonr/x/service/types"; +option go_package = "github.com/onsonr/sonr/x/svc/types"; // GenesisState defines the module genesis state message GenesisState { diff --git a/proto/service/v1/query.proto b/proto/svc/v1/query.proto similarity index 75% rename from proto/service/v1/query.proto rename to proto/svc/v1/query.proto index ab9072cdb..079ec22cf 100644 --- a/proto/service/v1/query.proto +++ b/proto/svc/v1/query.proto @@ -1,16 +1,16 @@ syntax = "proto3"; -package service.v1; +package svc.v1; import "google/api/annotations.proto"; -import "service/v1/genesis.proto"; +import "svc/v1/genesis.proto"; -option go_package = "github.com/onsonr/sonr/x/service/types"; +option go_package = "github.com/onsonr/sonr/x/svc/types"; // Query provides defines the gRPC querier service. service Query { // Params queries all parameters of the module. rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/service/v1/params"; + option (google.api.http).get = "/svc/v1/params"; } } diff --git a/proto/service/v1/state.proto b/proto/svc/v1/state.proto similarity index 91% rename from proto/service/v1/state.proto rename to proto/svc/v1/state.proto index b9a84b191..d1067bba4 100644 --- a/proto/service/v1/state.proto +++ b/proto/svc/v1/state.proto @@ -1,9 +1,10 @@ syntax = "proto3"; -package service.v1; +package svc.v1; import "cosmos/orm/v1/orm.proto"; -option go_package = "github.com/onsonr/sonr/x/service/types"; +option go_package = "github.com/onsonr/sonr/x/svc/types"; + // https://github.com/cosmos/cosmos-sdk/blob/main/orm/README.md diff --git a/proto/service/v1/tx.proto b/proto/svc/v1/tx.proto similarity index 93% rename from proto/service/v1/tx.proto rename to proto/svc/v1/tx.proto index 063b48c61..9fa4e7dc2 100644 --- a/proto/service/v1/tx.proto +++ b/proto/svc/v1/tx.proto @@ -1,12 +1,12 @@ syntax = "proto3"; -package service.v1; +package svc.v1; import "cosmos/msg/v1/msg.proto"; -import "cosmos_proto/cosmos.proto"; +import "svc/v1/genesis.proto"; import "gogoproto/gogo.proto"; -import "service/v1/genesis.proto"; +import "cosmos_proto/cosmos.proto"; -option go_package = "github.com/onsonr/sonr/x/service/types"; +option go_package = "github.com/onsonr/sonr/x/svc/types"; // Msg defines the Msg service. service Msg { diff --git a/proto/vault/v1/state.proto b/proto/vault/v1/state.proto deleted file mode 100644 index 5f0677133..000000000 --- a/proto/vault/v1/state.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; -package vault.v1; - -import "cosmos/orm/v1/orm.proto"; - -option go_package = "github.com/onsonr/sonr/x/vault/types"; - -// https://github.com/cosmos/cosmos-sdk/blob/main/orm/README.md - -message DWN { - option (cosmos.orm.v1.table) = { - id : 1 - primary_key : {fields : "id" auto_increment : true} - index : {id : 1 fields : "alias" unique : true} - index : {id : 2 fields : "cid" unique : true} - }; - uint64 id = 1; - string alias = 2; - string cid = 3; - string resolver = 4; -} diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index b1a7762ce..3f66f38b1 100644 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -50,17 +50,3 @@ for module in $base_namespace; do rm -rf $module done -cd $ROOT_DIR - -echo "Generating third-party proto code" -cd third_party/proto -buf generate - -echo "Copying generated proto code" -cd $ROOT_DIR/github.com/onsonr/sonr/pkg - -cp -r hway/types/* $ROOT_DIR/pkg/hway/types -cp -r common/types/* $ROOT_DIR/pkg/common/types - -echo "Cleaning up" -rm -rf $ROOT_DIR/github.com diff --git a/web/workers/noble-client/.gitignore b/web/workers/noble-client/.gitignore deleted file mode 100644 index 90cfa7c2d..000000000 --- a/web/workers/noble-client/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules -.DS_Store -.env -dist -out diff --git a/web/workers/noble-client/README.md b/web/workers/noble-client/README.md deleted file mode 100644 index e83bd8757..000000000 --- a/web/workers/noble-client/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# `noble-client` - -This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. - -It uses `noble-es` to provide a simple interface to interact with the Sonr network. - -## Usage - -### Deploying to Cloudflare diff --git a/web/workers/noble-client/package.json b/web/workers/noble-client/package.json deleted file mode 100644 index b8b7b285d..000000000 --- a/web/workers/noble-client/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "noble-client", - "version": "0.0.0", - "private": true, - "scripts": { - "deploy": "wrangler deploy", - "dev": "wrangler dev", - "start": "wrangler dev" - }, - "devDependencies": { - "wrangler": "^3.60.3" - }, - "dependencies": { - "sonr-es": "^0.5.3" - } -} diff --git a/web/workers/noble-client/src/index.js b/web/workers/noble-client/src/index.js deleted file mode 100644 index 2ae2b739e..000000000 --- a/web/workers/noble-client/src/index.js +++ /dev/null @@ -1,45 +0,0 @@ -export * from "./stub.js"; - -/** - * Welcome to Cloudflare Workers! This is your first Durable Objects application. - * - * - Run `npm run dev` in your terminal to start a development server - * - Open a browser tab at http://localhost:8787/ to see your Durable Object in action - * - Run `npm run deploy` to publish your application - * - * Learn more at https://developers.cloudflare.com/durable-objects - */ - -/** - * Env provides a mechanism to reference bindings declared in wrangler.toml within JavaScript - * - * @typedef {Object} Env - * @property {DurableObjectNamespace} NOBLE_DURABLE_CLIENT - The Durable Object namespace binding - */ - - -export default { - /** - * This is the standard fetch handler for a Cloudflare Worker - * - * @param {Request} request - The request submitted to the Worker from the client - * @param {Env} env - The interface to reference bindings declared in wrangler.toml - * @param {ExecutionContext} ctx - The execution context of the Worker - * @returns {Promise} The response to be sent back to the client - */ - async fetch(request, env, ctx) { - // We will create a `DurableObjectId` using the pathname from the Worker request - // This id refers to a unique instance of our 'MyDurableObject' class above - let id = env.NOBLE_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); - - // This stub creates a communication channel with the Durable Object instance - // The Durable Object constructor will be invoked upon the first call for a given id - let stub = env.NOBLE_DURABLE_CLIENT.get(id); - - // We call the `sayHello()` RPC method on the stub to invoke the method on the remote - // Durable Object instance - let greeting = await stub.sayHello("world"); - - return new Response(greeting); - }, -}; diff --git a/web/workers/noble-client/src/stub.js b/web/workers/noble-client/src/stub.js deleted file mode 100644 index 10d27bb12..000000000 --- a/web/workers/noble-client/src/stub.js +++ /dev/null @@ -1,26 +0,0 @@ -import { DurableObject } from "cloudflare:workers"; - -/** A Durable Object's behavior is defined in an exported Javascript class */ -export class NobleDurableClient extends DurableObject { - /** - * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to - * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) - * - * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state - * @param {Env} env - The interface to reference bindings declared in wrangler.toml - */ - constructor(ctx, env) { - super(ctx, env); - } - - /** - * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable - * Object instance receives a request from a Worker via the same method invocation on the stub - * - * @param {string} name - The name provided to a Durable Object instance from a Worker - * @returns {Promise} The greeting to be sent back to the Worker - */ - async sayHello(name) { - return `Hello, ${name}!`; - } -} diff --git a/web/workers/noble-client/wrangler.toml b/web/workers/noble-client/wrangler.toml deleted file mode 100644 index 8f4a4020a..000000000 --- a/web/workers/noble-client/wrangler.toml +++ /dev/null @@ -1,113 +0,0 @@ -#:schema node_modules/wrangler/config-schema.json -name = "noble-client" -main = "src/index.js" -compatibility_date = "2024-11-12" - -# Workers Logs -# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ -# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs -[observability] -enabled = true - -# Automatically place your workloads in an optimal location to minimize latency. -# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure -# rather than the end user may result in better performance. -# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement -# [placement] -# mode = "smart" - -# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) -# Docs: -# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables -# Note: Use secrets to store sensitive data. -# - https://developers.cloudflare.com/workers/configuration/secrets/ -# [vars] -# MY_VARIABLE = "production_value" - -# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai -# [ai] -# binding = "AI" - -# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets -# [[analytics_engine_datasets]] -# binding = "MY_DATASET" - -# Bind a headless browser instance running on Cloudflare's global network. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering -# [browser] -# binding = "MY_BROWSER" - -# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases -# [[d1_databases]] -# binding = "MY_DB" -# database_name = "my-database" -# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - -# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms -# [[dispatch_namespaces]] -# binding = "MY_DISPATCHER" -# namespace = "my-namespace" - -# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. -# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects -[[durable_objects.bindings]] -name = "NOBLE_DURABLE_CLIENT" -class_name = "NobleDurableClient" - -# Durable Object migrations. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations -[[migrations]] -tag = "v1" -new_classes = ["NobleDurableClient"] - -# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive -# [[hyperdrive]] -# binding = "MY_HYPERDRIVE" -# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces -# [[kv_namespaces]] -# binding = "MY_KV_NAMESPACE" -# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates -# [[mtls_certificates]] -# binding = "MY_CERTIFICATE" -# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - -# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues -# [[queues.producers]] -# binding = "MY_QUEUE" -# queue = "my-queue" - -# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues -# [[queues.consumers]] -# queue = "my-queue" - -# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets -# [[r2_buckets]] -# binding = "MY_BUCKET" -# bucket_name = "my-bucket" - -# Bind another Worker service. Use this binding to call another Worker without network overhead. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings -# [[services]] -# binding = "MY_SERVICE" -# service = "my-service" - -# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes -# [[vectorize]] -# binding = "MY_INDEX" -# index_name = "my-index" diff --git a/web/workers/osmosis-client/.gitignore b/web/workers/osmosis-client/.gitignore deleted file mode 100644 index 90cfa7c2d..000000000 --- a/web/workers/osmosis-client/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules -.DS_Store -.env -dist -out diff --git a/web/workers/osmosis-client/README.md b/web/workers/osmosis-client/README.md deleted file mode 100644 index c54afa25e..000000000 --- a/web/workers/osmosis-client/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# `osmosis-client` - -This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. - -It uses `osmosis-es` to provide a simple interface to interact with the Sonr network. - -## Usage - -### Deploying to Cloudflare - diff --git a/web/workers/osmosis-client/package.json b/web/workers/osmosis-client/package.json deleted file mode 100644 index 4dabb65ab..000000000 --- a/web/workers/osmosis-client/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "sonr-client", - "version": "0.0.0", - "private": true, - "scripts": { - "deploy": "wrangler deploy", - "dev": "wrangler dev", - "start": "wrangler dev" - }, - "devDependencies": { - "wrangler": "^3.60.3" - }, - "dependencies": { - "sonr-es": "^0.5.3" - } -} diff --git a/web/workers/osmosis-client/src/index.js b/web/workers/osmosis-client/src/index.js deleted file mode 100644 index 940c612d0..000000000 --- a/web/workers/osmosis-client/src/index.js +++ /dev/null @@ -1,45 +0,0 @@ -export * from "./stub.js"; - -/** - * Welcome to Cloudflare Workers! This is your first Durable Objects application. - * - * - Run `npm run dev` in your terminal to start a development server - * - Open a browser tab at http://localhost:8787/ to see your Durable Object in action - * - Run `npm run deploy` to publish your application - * - * Learn more at https://developers.cloudflare.com/durable-objects - */ - -/** - * Env provides a mechanism to reference bindings declared in wrangler.toml within JavaScript - * - * @typedef {Object} Env - * @property {DurableObjectNamespace} OSMOSIS_DURABLE_CLIENT - The Durable Object namespace binding - */ - - -export default { - /** - * This is the standard fetch handler for a Cloudflare Worker - * - * @param {Request} request - The request submitted to the Worker from the client - * @param {Env} env - The interface to reference bindings declared in wrangler.toml - * @param {ExecutionContext} ctx - The execution context of the Worker - * @returns {Promise} The response to be sent back to the client - */ - async fetch(request, env, ctx) { - // We will create a `DurableObjectId` using the pathname from the Worker request - // This id refers to a unique instance of our 'MyDurableObject' class above - let id = env.OSMOSIS_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); - - // This stub creates a communication channel with the Durable Object instance - // The Durable Object constructor will be invoked upon the first call for a given id - let stub = env.OSMOSIS_DURABLE_CLIENT.get(id); - - // We call the `sayHello()` RPC method on the stub to invoke the method on the remote - // Durable Object instance - let greeting = await stub.sayHello("world"); - - return new Response(greeting); - }, -}; diff --git a/web/workers/osmosis-client/src/stub.js b/web/workers/osmosis-client/src/stub.js deleted file mode 100644 index f2afbbace..000000000 --- a/web/workers/osmosis-client/src/stub.js +++ /dev/null @@ -1,26 +0,0 @@ -import { DurableObject } from "cloudflare:workers"; - -/** A Durable Object's behavior is defined in an exported Javascript class */ -export class OsmosisDurableClient extends DurableObject { - /** - * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to - * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) - * - * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state - * @param {Env} env - The interface to reference bindings declared in wrangler.toml - */ - constructor(ctx, env) { - super(ctx, env); - } - - /** - * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable - * Object instance receives a request from a Worker via the same method invocation on the stub - * - * @param {string} name - The name provided to a Durable Object instance from a Worker - * @returns {Promise} The greeting to be sent back to the Worker - */ - async sayHello(name) { - return `Hello, ${name}!`; - } -} diff --git a/web/workers/osmosis-client/wrangler.toml b/web/workers/osmosis-client/wrangler.toml deleted file mode 100644 index e9a92ea58..000000000 --- a/web/workers/osmosis-client/wrangler.toml +++ /dev/null @@ -1,113 +0,0 @@ -#:schema node_modules/wrangler/config-schema.json -name = "osmosis-client" -main = "src/index.js" -compatibility_date = "2024-11-12" - -# Workers Logs -# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ -# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs -[observability] -enabled = true - -# Automatically place your workloads in an optimal location to minimize latency. -# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure -# rather than the end user may result in better performance. -# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement -# [placement] -# mode = "smart" - -# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) -# Docs: -# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables -# Note: Use secrets to store sensitive data. -# - https://developers.cloudflare.com/workers/configuration/secrets/ -# [vars] -# MY_VARIABLE = "production_value" - -# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai -# [ai] -# binding = "AI" - -# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets -# [[analytics_engine_datasets]] -# binding = "MY_DATASET" - -# Bind a headless browser instance running on Cloudflare's global network. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering -# [browser] -# binding = "MY_BROWSER" - -# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases -# [[d1_databases]] -# binding = "MY_DB" -# database_name = "my-database" -# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - -# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms -# [[dispatch_namespaces]] -# binding = "MY_DISPATCHER" -# namespace = "my-namespace" - -# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. -# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects -[[durable_objects.bindings]] -name = "OSMOSIS_DURABLE_CLIENT" -class_name = "OsmosisDurableClient" - -# Durable Object migrations. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations -[[migrations]] -tag = "v1" -new_classes = ["OsmosisDurableClient"] - -# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive -# [[hyperdrive]] -# binding = "MY_HYPERDRIVE" -# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces -# [[kv_namespaces]] -# binding = "MY_KV_NAMESPACE" -# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates -# [[mtls_certificates]] -# binding = "MY_CERTIFICATE" -# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - -# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues -# [[queues.producers]] -# binding = "MY_QUEUE" -# queue = "my-queue" - -# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues -# [[queues.consumers]] -# queue = "my-queue" - -# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets -# [[r2_buckets]] -# binding = "MY_BUCKET" -# bucket_name = "my-bucket" - -# Bind another Worker service. Use this binding to call another Worker without network overhead. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings -# [[services]] -# binding = "MY_SERVICE" -# service = "my-service" - -# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes -# [[vectorize]] -# binding = "MY_INDEX" -# index_name = "my-index" diff --git a/web/workers/sonr-client/.gitignore b/web/workers/sonr-client/.gitignore deleted file mode 100644 index 90cfa7c2d..000000000 --- a/web/workers/sonr-client/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules -.DS_Store -.env -dist -out diff --git a/web/workers/sonr-client/README.md b/web/workers/sonr-client/README.md deleted file mode 100644 index 40b5fb2c4..000000000 --- a/web/workers/sonr-client/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# `sonr-client` - -This is a Cloudflare Workers Durable Object that can be deployed to Cloudflare's edge network. - -It uses `sonr-es` to provide a simple interface to interact with the Sonr network. - -## Usage - -### Deploying to Cloudflare - diff --git a/web/workers/sonr-client/bun.lockb b/web/workers/sonr-client/bun.lockb deleted file mode 100755 index eab8f6254d966e5eefcf09ad26d818e7ffc1ad4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106594 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�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 mBFCB}*X{UiF;a{7} The response to be sent back to the client - */ - async fetch(request, env, ctx) { - // We will create a `DurableObjectId` using the pathname from the Worker request - // This id refers to a unique instance of our 'MyDurableObject' class above - let id = env.SONR_DURABLE_CLIENT.idFromName(new URL(request.url).pathname); - - // This stub creates a communication channel with the Durable Object instance - // The Durable Object constructor will be invoked upon the first call for a given id - let stub = env.SONR_DURABLE_CLIENT.get(id); - - // We call the `sayHello()` RPC method on the stub to invoke the method on the remote - // Durable Object instance - let greeting = await stub.sayHello("world"); - - return new Response(greeting); - }, -}; diff --git a/web/workers/sonr-client/src/stub.js b/web/workers/sonr-client/src/stub.js deleted file mode 100644 index c0ec6bb77..000000000 --- a/web/workers/sonr-client/src/stub.js +++ /dev/null @@ -1,26 +0,0 @@ -import { DurableObject } from "cloudflare:workers"; - -/** A Durable Object's behavior is defined in an exported Javascript class */ -export class SonrDurableClient extends DurableObject { - /** - * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to - * `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted) - * - * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state - * @param {Env} env - The interface to reference bindings declared in wrangler.toml - */ - constructor(ctx, env) { - super(ctx, env); - } - - /** - * The Durable Object exposes an RPC method sayHello which will be invoked when when a Durable - * Object instance receives a request from a Worker via the same method invocation on the stub - * - * @param {string} name - The name provided to a Durable Object instance from a Worker - * @returns {Promise} The greeting to be sent back to the Worker - */ - async sayHello(name) { - return `Hello, ${name}!`; - } -} diff --git a/web/workers/sonr-client/wrangler.toml b/web/workers/sonr-client/wrangler.toml deleted file mode 100644 index 1ccb2aa5f..000000000 --- a/web/workers/sonr-client/wrangler.toml +++ /dev/null @@ -1,113 +0,0 @@ -#:schema node_modules/wrangler/config-schema.json -name = "sonr-client" -main = "src/index.js" -compatibility_date = "2024-11-12" - -# Workers Logs -# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ -# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs -[observability] -enabled = true - -# Automatically place your workloads in an optimal location to minimize latency. -# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure -# rather than the end user may result in better performance. -# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement -# [placement] -# mode = "smart" - -# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) -# Docs: -# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables -# Note: Use secrets to store sensitive data. -# - https://developers.cloudflare.com/workers/configuration/secrets/ -# [vars] -# MY_VARIABLE = "production_value" - -# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai -# [ai] -# binding = "AI" - -# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets -# [[analytics_engine_datasets]] -# binding = "MY_DATASET" - -# Bind a headless browser instance running on Cloudflare's global network. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering -# [browser] -# binding = "MY_BROWSER" - -# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases -# [[d1_databases]] -# binding = "MY_DB" -# database_name = "my-database" -# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - -# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms -# [[dispatch_namespaces]] -# binding = "MY_DISPATCHER" -# namespace = "my-namespace" - -# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. -# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects -[[durable_objects.bindings]] -name = "SONR_DURABLE_CLIENT" -class_name = "SonrDurableClient" - -# Durable Object migrations. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations -[[migrations]] -tag = "v2" -renamed_classes = [{ from = "MyDurableObject", to = "SonrDurableClient" }] - -# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive -# [[hyperdrive]] -# binding = "MY_HYPERDRIVE" -# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces -# [[kv_namespaces]] -# binding = "MY_KV_NAMESPACE" -# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - -# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates -# [[mtls_certificates]] -# binding = "MY_CERTIFICATE" -# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - -# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues -# [[queues.producers]] -# binding = "MY_QUEUE" -# queue = "my-queue" - -# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues -# [[queues.consumers]] -# queue = "my-queue" - -# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets -# [[r2_buckets]] -# binding = "MY_BUCKET" -# bucket_name = "my-bucket" - -# Bind another Worker service. Use this binding to call another Worker without network overhead. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings -# [[services]] -# binding = "MY_SERVICE" -# service = "my-service" - -# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. -# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes -# [[vectorize]] -# binding = "MY_INDEX" -# index_name = "my-index" diff --git a/x/vault/README.md b/x/dwn/README.md similarity index 85% rename from x/vault/README.md rename to x/dwn/README.md index 31f48bb91..ecca8c15a 100644 --- a/x/vault/README.md +++ b/x/dwn/README.md @@ -1,18 +1,18 @@ -# `x/vault` +# `x/dwn` -The Vault module is responsible for the management of IPFS deployed Decentralized Web Nodes (DWNs) and their associated data. +The DWN module is responsible for the management of IPFS deployed Decentralized Web Nodes (DWNs) and their associated data. ## Concepts -The Vault module introduces several key concepts: +The DWN module introduces several key concepts: 1. Decentralized Web Node (DWN): A distributed network for storing and sharing data. -2. Schema: A structure defining the format of various data types in the vault. +2. Schema: A structure defining the format of various data types in the dwn. 3. IPFS Integration: The module can interact with IPFS for decentralized data storage. ## State -The Vault module maintains the following state: +The DWN module maintains the following state: ### DWN State @@ -62,15 +62,15 @@ message Schema { ## State Transitions -State transitions in the Vault module are primarily triggered by: +State transitions in the DWN module are primarily triggered by: 1. Updating module parameters -2. Allocating new vaults +2. Allocating new dwns 3. Syncing DID documents ## Messages -The Vault module defines the following message: +The DWN module defines the following message: 1. `MsgUpdateParams`: Used to update the module parameters. @@ -91,19 +91,19 @@ No specific end-block operations are defined for this module. ## Hooks -The Vault module does not define any hooks. +The DWN module does not define any hooks. ## Events -The Vault module does not explicitly define any events. However, standard Cosmos SDK events may be emitted during state transitions. +The DWN module does not explicitly define any events. However, standard Cosmos SDK events may be emitted during state transitions. ## Client -The Vault module provides the following gRPC query endpoints: +The DWN module provides the following gRPC query endpoints: 1. `Params`: Queries all parameters of the module. 2. `Schema`: Queries the DID document schema. -3. `Allocate`: Initializes a Target Vault available for claims. +3. `Allocate`: Initializes a Target DWN available for claims. 4. `Sync`: Queries the DID document by its ID and returns required information. ## Params @@ -112,7 +112,7 @@ The module parameters include: - `ipfs_active` (bool): Indicates if IPFS integration is active. - `local_registration_enabled` (bool): Indicates if local registration is enabled. -- `schema` (Schema): Defines the structure for various data types in the vault. +- `schema` (Schema): Defines the structure for various data types in the dwn. ## Future Improvements @@ -129,7 +129,7 @@ Acceptance tests should cover: 1. Parameter updates 2. DWN state management 3. Schema queries -4. Vault allocation process +4. DWN allocation process 5. DID document syncing ## Appendix diff --git a/x/vault/autocli.go b/x/dwn/autocli.go similarity index 94% rename from x/vault/autocli.go rename to x/dwn/autocli.go index 721de0298..0c7cd0b33 100644 --- a/x/vault/autocli.go +++ b/x/dwn/autocli.go @@ -2,7 +2,7 @@ package module import ( autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" - modulev1 "github.com/onsonr/sonr/api/vault/v1" + modulev1 "github.com/onsonr/sonr/api/dwn/v1" ) // AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. diff --git a/x/vault/client/cli/query.go b/x/dwn/client/cli/query.go similarity index 96% rename from x/vault/client/cli/query.go rename to x/dwn/client/cli/query.go index fb2220253..8ecd129fc 100644 --- a/x/vault/client/cli/query.go +++ b/x/dwn/client/cli/query.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/onsonr/sonr/x/vault/types" + "github.com/onsonr/sonr/x/dwn/types" ) // !NOTE: Must enable in module.go (disabled in favor of autocli.go) diff --git a/x/vault/client/cli/tx.go b/x/dwn/client/cli/tx.go similarity index 95% rename from x/vault/client/cli/tx.go rename to x/dwn/client/cli/tx.go index 6f052facd..3e7706d59 100644 --- a/x/vault/client/cli/tx.go +++ b/x/dwn/client/cli/tx.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/onsonr/sonr/x/vault/types" + "github.com/onsonr/sonr/x/dwn/types" ) // !NOTE: Must enable in module.go (disabled in favor of autocli.go) @@ -54,7 +54,7 @@ func MsgUpdateParams() *cobra.Command { msg := &types.MsgUpdateParams{ Authority: senderAddress.String(), Params: types.Params{ - IpfsActive: someValue, + SomeValue: someValue, }, } diff --git a/x/vault/depinject.go b/x/dwn/depinject.go similarity index 78% rename from x/vault/depinject.go rename to x/dwn/depinject.go index 163a4c607..ffbc5bbf5 100644 --- a/x/vault/depinject.go +++ b/x/dwn/depinject.go @@ -3,21 +3,21 @@ package module import ( "os" + "github.com/cosmos/cosmos-sdk/codec" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" "cosmossdk.io/core/store" "cosmossdk.io/depinject" "cosmossdk.io/log" - "github.com/cosmos/cosmos-sdk/codec" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - modulev1 "github.com/onsonr/sonr/api/vault/module/v1" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - "github.com/onsonr/sonr/x/vault/keeper" + modulev1 "github.com/onsonr/sonr/api/dwn/module/v1" + "github.com/onsonr/sonr/x/dwn/keeper" ) var _ appmodule.AppModule = AppModule{} @@ -42,8 +42,6 @@ type ModuleInputs struct { StoreService store.KVStoreService AddressCodec address.Codec - AccountKeeper authkeeper.AccountKeeper - DidKeeper didkeeper.Keeper StakingKeeper stakingkeeper.Keeper SlashingKeeper slashingkeeper.Keeper } @@ -58,8 +56,8 @@ type ModuleOutputs struct { func ProvideModule(in ModuleInputs) ModuleOutputs { govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() - k := keeper.NewKeeper(in.Cdc, in.StoreService, log.NewLogger(os.Stderr), govAddr, in.AccountKeeper, in.DidKeeper) - m := NewAppModule(in.Cdc, k, in.DidKeeper) + k := keeper.NewKeeper(in.Cdc, in.StoreService, log.NewLogger(os.Stderr), govAddr) + m := NewAppModule(in.Cdc, k) return ModuleOutputs{Module: m, Keeper: k, Out: depinject.Out{}} } diff --git a/x/vault/keeper/genesis_test.go b/x/dwn/keeper/genesis_test.go similarity index 63% rename from x/vault/keeper/genesis_test.go rename to x/dwn/keeper/genesis_test.go index 97ee1dea6..8a18e86ba 100644 --- a/x/vault/keeper/genesis_test.go +++ b/x/dwn/keeper/genesis_test.go @@ -3,7 +3,7 @@ package keeper_test import ( "testing" - "github.com/onsonr/sonr/x/vault/types" + "github.com/onsonr/sonr/x/dwn/types" "github.com/stretchr/testify/require" ) @@ -12,8 +12,6 @@ func TestGenesis(t *testing.T) { genesisState := &types.GenesisState{ Params: types.DefaultParams(), - - // this line is used by starport scaffolding # genesis/test/state } f.k.InitGenesis(f.ctx, genesisState) @@ -21,5 +19,4 @@ func TestGenesis(t *testing.T) { got := f.k.ExportGenesis(f.ctx) require.NotNil(t, got) - // this line is used by starport scaffolding # genesis/test/assert } diff --git a/x/service/keeper/keeper.go b/x/dwn/keeper/keeper.go similarity index 67% rename from x/service/keeper/keeper.go rename to x/dwn/keeper/keeper.go index 4af26fc5a..363ca49bf 100644 --- a/x/service/keeper/keeper.go +++ b/x/dwn/keeper/keeper.go @@ -1,20 +1,20 @@ package keeper import ( + "context" + + "github.com/cosmos/cosmos-sdk/codec" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "cosmossdk.io/collections" storetypes "cosmossdk.io/core/store" "cosmossdk.io/log" "cosmossdk.io/orm/model/ormdb" - nftkeeper "cosmossdk.io/x/nft/keeper" - "github.com/cosmos/cosmos-sdk/codec" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper" - apiv1 "github.com/onsonr/sonr/api/service/v1" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - "github.com/onsonr/sonr/x/service/types" - vaultkeeper "github.com/onsonr/sonr/x/vault/keeper" + apiv1 "github.com/onsonr/sonr/api/dwn/v1" + "github.com/onsonr/sonr/x/dwn/types" ) type Keeper struct { @@ -28,11 +28,6 @@ type Keeper struct { OrmDB apiv1.StateStore authority string - - DidKeeper didkeeper.Keeper - GroupKeeper groupkeeper.Keeper - NFTKeeper nftkeeper.Keeper - VaultKeeper vaultkeeper.Keeper } // NewKeeper creates a new Keeper instance @@ -41,10 +36,6 @@ func NewKeeper( storeService storetypes.KVStoreService, logger log.Logger, authority string, - didKeeper didkeeper.Keeper, - groupKeeper groupkeeper.Keeper, - nftKeeper nftkeeper.Keeper, - vaultKeeper vaultkeeper.Keeper, ) Keeper { logger = logger.With(log.ModuleKey, "x/"+types.ModuleName) @@ -72,10 +63,6 @@ func NewKeeper( OrmDB: store, authority: authority, - - DidKeeper: didKeeper, - GroupKeeper: groupKeeper, - NFTKeeper: nftKeeper, } schema, err := sb.Build() @@ -87,3 +74,29 @@ func NewKeeper( return k } + +func (k Keeper) Logger() log.Logger { + return k.logger +} + +// InitGenesis initializes the module's state from a genesis state. +func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { + + if err := data.Params.Validate(); err != nil { + return err + } + + return k.Params.Set(ctx, data.Params) +} + +// ExportGenesis exports the module's state to a genesis state. +func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { + params, err := k.Params.Get(ctx) + if err != nil { + panic(err) + } + + return &types.GenesisState{ + Params: params, + } +} diff --git a/x/vault/keeper/keeper_test.go b/x/dwn/keeper/keeper_test.go similarity index 68% rename from x/vault/keeper/keeper_test.go rename to x/dwn/keeper/keeper_test.go index 313bd65be..154bc8b53 100644 --- a/x/vault/keeper/keeper_test.go +++ b/x/dwn/keeper/keeper_test.go @@ -3,11 +3,14 @@ package keeper_test import ( "testing" - "cosmossdk.io/core/store" + "github.com/stretchr/testify/suite" + "cosmossdk.io/log" storetypes "cosmossdk.io/store/types" + + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/runtime" - "github.com/cosmos/cosmos-sdk/testutil" + "github.com/cosmos/cosmos-sdk/testutil/integration" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -15,18 +18,16 @@ import ( authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - module "github.com/onsonr/sonr/x/vault" - "github.com/onsonr/sonr/x/vault/keeper" - "github.com/onsonr/sonr/x/vault/types" + module "github.com/onsonr/sonr/x/dwn" + "github.com/onsonr/sonr/x/dwn/keeper" + "github.com/onsonr/sonr/x/dwn/types" ) var maccPerms = map[string][]string{ @@ -50,7 +51,6 @@ type testFixture struct { bankkeeper bankkeeper.BaseKeeper stakingKeeper *stakingkeeper.Keeper mintkeeper mintkeeper.Keeper - didk didkeeper.Keeper addrs []sdk.AccAddress govModAddr string @@ -59,7 +59,6 @@ type testFixture struct { func SetupTest(t *testing.T) *testFixture { t.Helper() f := new(testFixture) - require := require.New(t) // Base setup logger := log.NewTestLogger(t) @@ -68,20 +67,17 @@ func SetupTest(t *testing.T) *testFixture { f.govModAddr = authtypes.NewModuleAddress(govtypes.ModuleName).String() f.addrs = simtestutil.CreateIncrementalAccounts(3) - key := storetypes.NewKVStoreKey(types.ModuleName) - storeService := runtime.NewKVStoreService(key) - testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) - - f.ctx = testCtx.Ctx + keys := storetypes.NewKVStoreKeys(authtypes.ModuleName, banktypes.ModuleName, stakingtypes.ModuleName, minttypes.ModuleName, types.ModuleName) + f.ctx = sdk.NewContext(integration.CreateMultiStore(keys, logger), cmtproto.Header{}, false, logger) // Register SDK modules. - registerBaseSDKModules(f, encCfg, storeService, logger, require) + registerBaseSDKModules(logger, f, encCfg, keys) // Setup Keeper. - f.k = keeper.NewKeeper(encCfg.Codec, storeService, logger, f.govModAddr, f.accountkeeper, f.didk) + f.k = keeper.NewKeeper(encCfg.Codec, runtime.NewKVStoreService(keys[types.ModuleName]), logger, f.govModAddr) f.msgServer = keeper.NewMsgServerImpl(f.k) f.queryServer = keeper.NewQuerier(f.k) - f.appModule = module.NewAppModule(encCfg.Codec, f.k, f.didk) + f.appModule = module.NewAppModule(encCfg.Codec, f.k) return f } @@ -89,22 +85,23 @@ func SetupTest(t *testing.T) *testFixture { func registerModuleInterfaces(encCfg moduletestutil.TestEncodingConfig) { authtypes.RegisterInterfaces(encCfg.InterfaceRegistry) stakingtypes.RegisterInterfaces(encCfg.InterfaceRegistry) + banktypes.RegisterInterfaces(encCfg.InterfaceRegistry) + minttypes.RegisterInterfaces(encCfg.InterfaceRegistry) types.RegisterInterfaces(encCfg.InterfaceRegistry) } func registerBaseSDKModules( + logger log.Logger, f *testFixture, encCfg moduletestutil.TestEncodingConfig, - storeService store.KVStoreService, - logger log.Logger, - require *require.Assertions, + keys map[string]*storetypes.KVStoreKey, ) { registerModuleInterfaces(encCfg) // Auth Keeper. f.accountkeeper = authkeeper.NewAccountKeeper( - encCfg.Codec, storeService, + encCfg.Codec, runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, authcodec.NewBech32Codec(sdk.Bech32MainPrefix), sdk.Bech32MainPrefix, @@ -113,7 +110,7 @@ func registerBaseSDKModules( // Bank Keeper. f.bankkeeper = bankkeeper.NewBaseKeeper( - encCfg.Codec, storeService, + encCfg.Codec, runtime.NewKVStoreService(keys[banktypes.StoreKey]), f.accountkeeper, nil, f.govModAddr, logger, @@ -121,21 +118,16 @@ func registerBaseSDKModules( // Staking Keeper. f.stakingKeeper = stakingkeeper.NewKeeper( - encCfg.Codec, storeService, + encCfg.Codec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), f.accountkeeper, f.bankkeeper, f.govModAddr, authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), ) - require.NoError(f.stakingKeeper.SetParams(f.ctx, stakingtypes.DefaultParams())) - f.accountkeeper.SetModuleAccount(f.ctx, f.stakingKeeper.GetNotBondedPool(f.ctx)) - f.accountkeeper.SetModuleAccount(f.ctx, f.stakingKeeper.GetBondedPool(f.ctx)) // Mint Keeper. f.mintkeeper = mintkeeper.NewKeeper( - encCfg.Codec, storeService, + encCfg.Codec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), f.stakingKeeper, f.accountkeeper, f.bankkeeper, authtypes.FeeCollectorName, f.govModAddr, ) - f.accountkeeper.SetModuleAccount(f.ctx, f.accountkeeper.GetModuleAccount(f.ctx, minttypes.ModuleName)) - f.mintkeeper.InitGenesis(f.ctx, f.accountkeeper, minttypes.DefaultGenesisState()) } diff --git a/x/vault/keeper/rpc.go b/x/dwn/keeper/msg_server.go similarity index 68% rename from x/vault/keeper/rpc.go rename to x/dwn/keeper/msg_server.go index 725c6830a..c8503c83d 100644 --- a/x/vault/keeper/rpc.go +++ b/x/dwn/keeper/msg_server.go @@ -6,7 +6,7 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "cosmossdk.io/errors" - "github.com/onsonr/sonr/x/vault/types" + "github.com/onsonr/sonr/x/dwn/types" ) type msgServer struct { @@ -27,3 +27,10 @@ func (ms msgServer) UpdateParams(ctx context.Context, msg *types.MsgUpdateParams return nil, ms.k.Params.Set(ctx, msg.Params) } + +// Initialize implements types.MsgServer. +func (ms msgServer) Initialize(ctx context.Context, msg *types.MsgInitialize) (*types.MsgInitializeResponse, error) { + // ctx := sdk.UnwrapSDKContext(goCtx) + panic("Initialize is unimplemented") + return &types.MsgInitializeResponse{}, nil +} diff --git a/x/vault/keeper/rpc_test.go b/x/dwn/keeper/msg_server_test.go similarity index 96% rename from x/vault/keeper/rpc_test.go rename to x/dwn/keeper/msg_server_test.go index 05afe506f..58580e911 100644 --- a/x/vault/keeper/rpc_test.go +++ b/x/dwn/keeper/msg_server_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/onsonr/sonr/x/vault/types" + "github.com/onsonr/sonr/x/dwn/types" ) func TestParams(t *testing.T) { diff --git a/x/dwn/keeper/orm_test.go b/x/dwn/keeper/orm_test.go new file mode 100644 index 000000000..de439d2bf --- /dev/null +++ b/x/dwn/keeper/orm_test.go @@ -0,0 +1,31 @@ +package keeper_test + +import ( + "testing" + + apiv1 "github.com/onsonr/sonr/api/dwn/v1" + "github.com/stretchr/testify/require" +) + +func TestORM(t *testing.T) { + f := SetupTest(t) + + dt := f.k.OrmDB.ExampleDataTable() + acc := []byte("test_acc") + amt := uint64(7) + + err := dt.Insert(f.ctx, &apiv1.ExampleData{ + Account: acc, + Amount: amt, + }) + require.NoError(t, err) + + d, err := dt.Has(f.ctx, []byte("test_acc")) + require.NoError(t, err) + require.True(t, d) + + res, err := dt.Get(f.ctx, []byte("test_acc")) + require.NoError(t, err) + require.NotNil(t, res) + require.EqualValues(t, amt, res.Amount) +} diff --git a/x/dwn/keeper/query_server.go b/x/dwn/keeper/query_server.go new file mode 100644 index 000000000..70726e1a9 --- /dev/null +++ b/x/dwn/keeper/query_server.go @@ -0,0 +1,51 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/onsonr/sonr/x/dwn/types" +) + +var _ types.QueryServer = Querier{} + +type Querier struct { + Keeper +} + +func NewQuerier(keeper Keeper) Querier { + return Querier{Keeper: keeper} +} + +func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + + p, err := k.Keeper.Params.Get(ctx) + if err != nil { + return nil, err + } + + return &types.QueryParamsResponse{Params: &p}, nil +} + +// Schema implements types.QueryServer. +func (k Querier) Schema(goCtx context.Context, req *types.QuerySchemaRequest) (*types.QuerySchemaResponse, error) { + // ctx := sdk.UnwrapSDKContext(goCtx) + panic("Schema is unimplemented") + return &types.QuerySchemaResponse{}, nil +} + +// Allocate implements types.QueryServer. +func (k Querier) Allocate(goCtx context.Context, req *types.QueryAllocateRequest) (*types.QueryAllocateResponse, error) { + // ctx := sdk.UnwrapSDKContext(goCtx) + panic("Allocate is unimplemented") + return &types.QueryAllocateResponse{}, nil +} + +// Sync implements types.QueryServer. +func (k Querier) Sync(goCtx context.Context, req *types.QuerySyncRequest) (*types.QuerySyncResponse, error) { + // ctx := sdk.UnwrapSDKContext(goCtx) + panic("Sync is unimplemented") + return &types.QuerySyncResponse{}, nil +} diff --git a/x/service/module.go b/x/dwn/module.go similarity index 91% rename from x/service/module.go rename to x/dwn/module.go index 5442d22d3..c6015efa0 100644 --- a/x/service/module.go +++ b/x/dwn/module.go @@ -4,27 +4,27 @@ import ( "context" "encoding/json" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + + abci "github.com/cometbft/cometbft/abci/types" + "cosmossdk.io/client/v2/autocli" errorsmod "cosmossdk.io/errors" - abci "github.com/cometbft/cometbft/abci/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - "github.com/onsonr/sonr/x/service/keeper" - "github.com/onsonr/sonr/x/service/types" + "github.com/onsonr/sonr/x/dwn/keeper" + "github.com/onsonr/sonr/x/dwn/types" ) const ( - // ConsensusVersion defines the current x/service module consensus version. + // ConsensusVersion defines the current x/dwn module consensus version. ConsensusVersion = 1 - -// this line is used by starport scaffolding # simapp/module/const ) var ( @@ -44,19 +44,16 @@ type AppModule struct { AppModuleBasic keeper keeper.Keeper - didk didkeeper.Keeper } // NewAppModule constructor func NewAppModule( cdc codec.Codec, keeper keeper.Keeper, - didkeeper didkeeper.Keeper, ) *AppModule { return &AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, - didk: didkeeper, } } diff --git a/x/vault/types/codec.go b/x/dwn/types/codec.go similarity index 89% rename from x/vault/types/codec.go rename to x/dwn/types/codec.go index 550adfc39..6d57a9e34 100644 --- a/x/vault/types/codec.go +++ b/x/dwn/types/codec.go @@ -6,7 +6,6 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" - // this line is used by starport scaffolding # 1 ) var ( @@ -26,7 +25,6 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { } func RegisterInterfaces(registry types.InterfaceRegistry) { - // this line is used by starport scaffolding # 3 registry.RegisterImplementations( (*sdk.Msg)(nil), diff --git a/x/vault/types/genesis.go b/x/dwn/types/genesis.go similarity index 93% rename from x/vault/types/genesis.go rename to x/dwn/types/genesis.go index 1cbf2defd..e1e8ab313 100644 --- a/x/vault/types/genesis.go +++ b/x/dwn/types/genesis.go @@ -1,7 +1,5 @@ package types -// this line is used by starport scaffolding # genesis/types/import - // DefaultIndex is the default global index const DefaultIndex uint64 = 1 diff --git a/x/vault/types/genesis.pb.go b/x/dwn/types/genesis.pb.go similarity index 89% rename from x/vault/types/genesis.pb.go rename to x/dwn/types/genesis.pb.go index e3defe5be..430981ca0 100644 --- a/x/vault/types/genesis.pb.go +++ b/x/dwn/types/genesis.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: vault/v1/genesis.proto +// source: dwn/v1/genesis.proto package types @@ -34,7 +34,7 @@ func (m *GenesisState) Reset() { *m = GenesisState{} } func (m *GenesisState) String() string { return proto.CompactTextString(m) } func (*GenesisState) ProtoMessage() {} func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_4c971b352fb6cc17, []int{0} + return fileDescriptor_8e7492a25d5871dc, []int{0} } func (m *GenesisState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -80,7 +80,7 @@ type Params struct { func (m *Params) Reset() { *m = Params{} } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_4c971b352fb6cc17, []int{1} + return fileDescriptor_8e7492a25d5871dc, []int{1} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -147,7 +147,7 @@ func (m *Schema) Reset() { *m = Schema{} } func (m *Schema) String() string { return proto.CompactTextString(m) } func (*Schema) ProtoMessage() {} func (*Schema) Descriptor() ([]byte, []int) { - return fileDescriptor_4c971b352fb6cc17, []int{2} + return fileDescriptor_8e7492a25d5871dc, []int{2} } func (m *Schema) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -247,43 +247,42 @@ func (m *Schema) GetProfile() string { } func init() { - proto.RegisterType((*GenesisState)(nil), "vault.v1.GenesisState") - proto.RegisterType((*Params)(nil), "vault.v1.Params") - proto.RegisterType((*Schema)(nil), "vault.v1.Schema") + proto.RegisterType((*GenesisState)(nil), "dwn.v1.GenesisState") + proto.RegisterType((*Params)(nil), "dwn.v1.Params") + proto.RegisterType((*Schema)(nil), "dwn.v1.Schema") } -func init() { proto.RegisterFile("vault/v1/genesis.proto", fileDescriptor_4c971b352fb6cc17) } +func init() { proto.RegisterFile("dwn/v1/genesis.proto", fileDescriptor_8e7492a25d5871dc) } -var fileDescriptor_4c971b352fb6cc17 = []byte{ - // 434 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0xc7, 0x6d, 0xda, 0xb8, 0xc9, 0xb5, 0x43, 0x39, 0x55, 0xe8, 0xc8, 0xe0, 0xa0, 0x8a, 0xa1, - 0x62, 0xb0, 0x55, 0xd8, 0x10, 0xaa, 0x44, 0x25, 0xc4, 0x8a, 0xdc, 0x8d, 0x25, 0x7a, 0x71, 0x5e, - 0x9d, 0x6b, 0x9c, 0x3b, 0xeb, 0xee, 0xe2, 0xd2, 0xaf, 0xc0, 0xc4, 0xc8, 0xd8, 0x0f, 0xc0, 0xc0, - 0xc7, 0xe8, 0xd8, 0x91, 0x09, 0xa1, 0x64, 0x80, 0x8f, 0xc0, 0x88, 0xee, 0x9d, 0x83, 0xa2, 0x2e, - 0xa7, 0xf7, 0xff, 0xfd, 0xff, 0x7e, 0xfa, 0xeb, 0xc9, 0xec, 0x49, 0x0b, 0xcb, 0xda, 0xe5, 0xed, - 0x69, 0x5e, 0xa1, 0x42, 0x2b, 0x6d, 0xd6, 0x18, 0xed, 0x34, 0xef, 0x13, 0xcf, 0xda, 0xd3, 0xe1, - 0x63, 0x58, 0x48, 0xa5, 0x73, 0x7a, 0x83, 0x39, 0x3c, 0xaa, 0x74, 0xa5, 0x69, 0xcc, 0xfd, 0x14, - 0xe8, 0xf1, 0x19, 0x3b, 0x78, 0x1f, 0x76, 0x5c, 0x38, 0x70, 0xc8, 0x33, 0x96, 0x34, 0x60, 0x60, - 0x61, 0x45, 0xfc, 0x2c, 0x3e, 0xd9, 0x7f, 0x79, 0x98, 0x6d, 0x76, 0x66, 0x1f, 0x88, 0x9f, 0xef, - 0xde, 0xfd, 0x1c, 0x45, 0x45, 0x97, 0x3a, 0xfe, 0x16, 0xb3, 0x24, 0x18, 0x7c, 0xc4, 0xf6, 0x65, - 0x73, 0x69, 0xc7, 0x50, 0x3a, 0xd9, 0x22, 0x7d, 0xdf, 0x2f, 0x98, 0x47, 0x6f, 0x89, 0xf0, 0x37, - 0x6c, 0x58, 0xeb, 0x12, 0xea, 0xb1, 0xc1, 0x4a, 0x5a, 0x67, 0xc0, 0x49, 0xad, 0xc6, 0xa8, 0x60, - 0x52, 0xe3, 0x54, 0x3c, 0xa2, 0xbc, 0xa0, 0x44, 0xb1, 0x15, 0x78, 0x17, 0x7c, 0x7e, 0xc2, 0x12, - 0x5b, 0xce, 0x70, 0x01, 0x62, 0xf7, 0x61, 0xb3, 0x0b, 0xe2, 0x45, 0xe7, 0xbf, 0x7e, 0xfa, 0xf5, - 0x76, 0x14, 0xfd, 0xb9, 0x1d, 0xc5, 0x9f, 0x7f, 0x7f, 0x7f, 0x71, 0x10, 0x6e, 0xd5, 0xd5, 0xfd, - 0x1b, 0xb3, 0x24, 0xa4, 0xb9, 0x60, 0x7b, 0x2d, 0x1a, 0x2b, 0xb5, 0xa2, 0xaa, 0xbd, 0x62, 0x23, - 0xbd, 0x03, 0x65, 0xa9, 0x97, 0xca, 0x51, 0xa9, 0x41, 0xb1, 0x91, 0xfc, 0x88, 0xf5, 0xc0, 0x5a, - 0x74, 0x62, 0x87, 0x78, 0x10, 0x9e, 0x96, 0x33, 0x90, 0x8a, 0x8a, 0x0d, 0x8a, 0x20, 0x78, 0xca, - 0x58, 0x69, 0x70, 0x8a, 0xca, 0x49, 0xa8, 0x45, 0x8f, 0xac, 0x2d, 0xc2, 0x0f, 0xd9, 0xce, 0x54, - 0x4e, 0x45, 0x42, 0x86, 0x1f, 0x3d, 0xb9, 0xba, 0x9e, 0x8b, 0xbd, 0x40, 0xae, 0xae, 0xe7, 0x7e, - 0x73, 0x65, 0x40, 0x39, 0xd1, 0x0f, 0x9b, 0x49, 0xf0, 0x21, 0xeb, 0xcf, 0xf1, 0xc6, 0xce, 0xc0, - 0xa0, 0x18, 0x90, 0xf1, 0x5f, 0xfb, 0xee, 0x8d, 0xd1, 0x97, 0xb2, 0x46, 0xc1, 0x42, 0xf7, 0x4e, - 0x9e, 0x9f, 0xdd, 0xad, 0xd2, 0xf8, 0x7e, 0x95, 0xc6, 0xbf, 0x56, 0x69, 0xfc, 0x65, 0x9d, 0x46, - 0xf7, 0xeb, 0x34, 0xfa, 0xb1, 0x4e, 0xa3, 0x8f, 0xcf, 0x2b, 0xe9, 0x66, 0xcb, 0x49, 0x56, 0xea, - 0x45, 0xae, 0x95, 0xd5, 0xca, 0xe4, 0xf4, 0x7c, 0xca, 0xc3, 0xed, 0xdc, 0x4d, 0x83, 0x76, 0x92, - 0xd0, 0x0f, 0xf3, 0xea, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x54, 0x04, 0x35, 0x7d, 0x02, - 0x00, 0x00, +var fileDescriptor_8e7492a25d5871dc = []byte{ + // 431 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x92, 0x31, 0x6f, 0x13, 0x31, + 0x1c, 0xc5, 0xef, 0x68, 0x73, 0x4d, 0xdc, 0x0a, 0x81, 0x95, 0xc1, 0x64, 0xb8, 0xa0, 0x0c, 0x08, + 0x21, 0x74, 0xa7, 0xc2, 0x86, 0xb2, 0x50, 0x09, 0xb1, 0xa2, 0xeb, 0xc6, 0x12, 0x39, 0xbe, 0x7f, + 0x2f, 0x6e, 0x2e, 0xf6, 0xc9, 0x76, 0x2e, 0xf4, 0x2b, 0x30, 0x31, 0x32, 0x76, 0x66, 0xe2, 0x63, + 0x74, 0xec, 0xc8, 0x84, 0x50, 0x32, 0xc0, 0x47, 0x60, 0x44, 0xfe, 0xfb, 0x8a, 0xd2, 0xc5, 0xf2, + 0xfb, 0xbd, 0xe7, 0xa7, 0x37, 0x98, 0x0c, 0xcb, 0x8d, 0xca, 0xdb, 0xd3, 0xbc, 0x02, 0x05, 0x56, + 0xda, 0xac, 0x31, 0xda, 0x69, 0x9a, 0x94, 0x1b, 0x95, 0xb5, 0xa7, 0xa3, 0x61, 0xa5, 0x2b, 0x8d, + 0x28, 0xf7, 0xb7, 0xe0, 0x8e, 0x1e, 0xf3, 0x95, 0x54, 0x3a, 0xc7, 0x33, 0xa0, 0xc9, 0x94, 0x9c, + 0xbc, 0x0f, 0x0d, 0xe7, 0x8e, 0x3b, 0xa0, 0x2f, 0x49, 0xd2, 0x70, 0xc3, 0x57, 0x96, 0xc5, 0x4f, + 0xe3, 0xe7, 0xc7, 0xaf, 0x1e, 0x66, 0xa1, 0x31, 0xfb, 0x80, 0xf4, 0xec, 0xf0, 0xe6, 0xe7, 0x38, + 0x2a, 0xba, 0xcc, 0xe4, 0x5b, 0x4c, 0x92, 0x60, 0xd0, 0x31, 0x39, 0x96, 0xcd, 0x85, 0x9d, 0x71, + 0xe1, 0x64, 0x0b, 0xf8, 0xba, 0x5f, 0x10, 0x8f, 0xde, 0x22, 0xa1, 0x53, 0x32, 0xaa, 0xb5, 0xe0, + 0xf5, 0xcc, 0x40, 0x25, 0xad, 0x33, 0xdc, 0x49, 0xad, 0x66, 0xa0, 0xf8, 0xbc, 0x86, 0x92, 0x3d, + 0xc0, 0x3c, 0xc3, 0x44, 0xb1, 0x17, 0x78, 0x17, 0x7c, 0xfa, 0x8c, 0x24, 0x56, 0x2c, 0x60, 0xc5, + 0xd9, 0xe1, 0xfd, 0x5d, 0xe7, 0x48, 0x8b, 0xce, 0x7d, 0xf3, 0xe4, 0xeb, 0xf5, 0x38, 0xfa, 0x73, + 0x3d, 0x8e, 0x3f, 0xff, 0xfe, 0xfe, 0xe2, 0xa4, 0xe5, 0xeb, 0xda, 0xe5, 0xdd, 0xd8, 0xbf, 0x31, + 0x49, 0x42, 0x9a, 0x32, 0x72, 0xd4, 0x82, 0xb1, 0x52, 0x2b, 0x1c, 0xda, 0x2b, 0xee, 0xa4, 0x77, + 0xb8, 0x10, 0x7a, 0xad, 0x1c, 0x4e, 0x1a, 0x14, 0x77, 0x92, 0x0e, 0x49, 0x8f, 0x5b, 0x0b, 0x8e, + 0x1d, 0x20, 0x0f, 0xc2, 0x53, 0xb1, 0xe0, 0x52, 0xe1, 0xac, 0x41, 0x11, 0x04, 0x4d, 0x09, 0x11, + 0x06, 0x4a, 0x50, 0x4e, 0xf2, 0x9a, 0xf5, 0xd0, 0xda, 0x23, 0xf4, 0x11, 0x39, 0x28, 0x65, 0xc9, + 0x12, 0x34, 0xfc, 0xd5, 0x93, 0xcb, 0xcd, 0x92, 0x1d, 0x05, 0x72, 0xb9, 0x59, 0xfa, 0xe6, 0xca, + 0x70, 0xe5, 0x58, 0x3f, 0x34, 0xa3, 0xa0, 0x23, 0xd2, 0x5f, 0xc2, 0x95, 0x5d, 0x70, 0x03, 0x6c, + 0x80, 0xc6, 0x7f, 0xed, 0xb7, 0x37, 0x46, 0x5f, 0xc8, 0x1a, 0x18, 0x09, 0xdb, 0x3b, 0x79, 0x36, + 0xbd, 0xd9, 0xa6, 0xf1, 0xed, 0x36, 0x8d, 0x7f, 0x6d, 0xd3, 0xf8, 0xcb, 0x2e, 0x8d, 0x6e, 0x77, + 0x69, 0xf4, 0x63, 0x97, 0x46, 0x1f, 0x27, 0x95, 0x74, 0x8b, 0xf5, 0x3c, 0x13, 0x7a, 0x95, 0x6b, + 0x65, 0xb5, 0x32, 0x39, 0x1e, 0x9f, 0x72, 0xff, 0xbf, 0xdc, 0x55, 0x03, 0x76, 0x9e, 0xe0, 0x57, + 0x79, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xdd, 0xa9, 0xd7, 0xe1, 0x73, 0x02, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { diff --git a/x/vault/types/genesis_test.go b/x/dwn/types/genesis_test.go similarity index 69% rename from x/vault/types/genesis_test.go rename to x/dwn/types/genesis_test.go index e1f7f7ff8..8c5a25dd7 100644 --- a/x/vault/types/genesis_test.go +++ b/x/dwn/types/genesis_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/onsonr/sonr/x/vault/types" + "github.com/onsonr/sonr/x/dwn/types" "github.com/stretchr/testify/require" ) @@ -21,13 +21,9 @@ func TestGenesisState_Validate(t *testing.T) { }, { desc: "valid genesis state", - genState: &types.GenesisState{ - - // this line is used by starport scaffolding # types/genesis/validField - }, - valid: true, + genState: &types.GenesisState{}, + valid: true, }, - // this line is used by starport scaffolding # types/genesis/testcase } for _, tc := range tests { t.Run(tc.desc, func(t *testing.T) { diff --git a/x/vault/types/keys.go b/x/dwn/types/keys.go similarity index 85% rename from x/vault/types/keys.go rename to x/dwn/types/keys.go index 075c9510f..5f6375c42 100644 --- a/x/vault/types/keys.go +++ b/x/dwn/types/keys.go @@ -12,7 +12,7 @@ var ( ) const ( - ModuleName = "vault" + ModuleName = "dwn" StoreKey = ModuleName @@ -21,7 +21,7 @@ const ( var ORMModuleSchema = ormv1alpha1.ModuleSchemaDescriptor{ SchemaFile: []*ormv1alpha1.ModuleSchemaDescriptor_FileEntry{ - {Id: 1, ProtoFileName: "vault/v1/state.proto"}, + {Id: 1, ProtoFileName: "dwn/v1/state.proto"}, }, Prefix: []byte{0}, } diff --git a/x/vault/types/msgs.go b/x/dwn/types/msgs.go similarity index 100% rename from x/vault/types/msgs.go rename to x/dwn/types/msgs.go diff --git a/x/vault/types/params.go b/x/dwn/types/params.go similarity index 100% rename from x/vault/types/params.go rename to x/dwn/types/params.go diff --git a/x/vault/types/query.pb.go b/x/dwn/types/query.pb.go similarity index 90% rename from x/vault/types/query.pb.go rename to x/dwn/types/query.pb.go index b45384952..d2faf34a4 100644 --- a/x/vault/types/query.pb.go +++ b/x/dwn/types/query.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: vault/v1/query.proto +// source: dwn/v1/query.proto package types @@ -36,7 +36,7 @@ func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryParamsRequest) ProtoMessage() {} func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_e6d49a2800ab3e4b, []int{0} + return fileDescriptor_9a31dfed63924cb3, []int{0} } func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,7 +75,7 @@ func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryParamsResponse) ProtoMessage() {} func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_e6d49a2800ab3e4b, []int{1} + return fileDescriptor_9a31dfed63924cb3, []int{1} } func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -119,7 +119,7 @@ func (m *QuerySchemaRequest) Reset() { *m = QuerySchemaRequest{} } func (m *QuerySchemaRequest) String() string { return proto.CompactTextString(m) } func (*QuerySchemaRequest) ProtoMessage() {} func (*QuerySchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_e6d49a2800ab3e4b, []int{2} + return fileDescriptor_9a31dfed63924cb3, []int{2} } func (m *QuerySchemaRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -158,7 +158,7 @@ func (m *QuerySchemaResponse) Reset() { *m = QuerySchemaResponse{} } func (m *QuerySchemaResponse) String() string { return proto.CompactTextString(m) } func (*QuerySchemaResponse) ProtoMessage() {} func (*QuerySchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_e6d49a2800ab3e4b, []int{3} + return fileDescriptor_9a31dfed63924cb3, []int{3} } func (m *QuerySchemaResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -202,7 +202,7 @@ func (m *QueryAllocateRequest) Reset() { *m = QueryAllocateRequest{} } func (m *QueryAllocateRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllocateRequest) ProtoMessage() {} func (*QueryAllocateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_e6d49a2800ab3e4b, []int{4} + return fileDescriptor_9a31dfed63924cb3, []int{4} } func (m *QueryAllocateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -244,7 +244,7 @@ func (m *QueryAllocateResponse) Reset() { *m = QueryAllocateResponse{} } func (m *QueryAllocateResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllocateResponse) ProtoMessage() {} func (*QueryAllocateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_e6d49a2800ab3e4b, []int{5} + return fileDescriptor_9a31dfed63924cb3, []int{5} } func (m *QueryAllocateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -317,7 +317,7 @@ func (m *QuerySyncRequest) Reset() { *m = QuerySyncRequest{} } func (m *QuerySyncRequest) String() string { return proto.CompactTextString(m) } func (*QuerySyncRequest) ProtoMessage() {} func (*QuerySyncRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_e6d49a2800ab3e4b, []int{6} + return fileDescriptor_9a31dfed63924cb3, []int{6} } func (m *QuerySyncRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -368,7 +368,7 @@ func (m *QuerySyncResponse) Reset() { *m = QuerySyncResponse{} } func (m *QuerySyncResponse) String() string { return proto.CompactTextString(m) } func (*QuerySyncResponse) ProtoMessage() {} func (*QuerySyncResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_e6d49a2800ab3e4b, []int{7} + return fileDescriptor_9a31dfed63924cb3, []int{7} } func (m *QuerySyncResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -426,53 +426,53 @@ func (m *QuerySyncResponse) GetChainID() string { } func init() { - proto.RegisterType((*QueryParamsRequest)(nil), "vault.v1.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "vault.v1.QueryParamsResponse") - proto.RegisterType((*QuerySchemaRequest)(nil), "vault.v1.QuerySchemaRequest") - proto.RegisterType((*QuerySchemaResponse)(nil), "vault.v1.QuerySchemaResponse") - proto.RegisterType((*QueryAllocateRequest)(nil), "vault.v1.QueryAllocateRequest") - proto.RegisterType((*QueryAllocateResponse)(nil), "vault.v1.QueryAllocateResponse") - proto.RegisterType((*QuerySyncRequest)(nil), "vault.v1.QuerySyncRequest") - proto.RegisterType((*QuerySyncResponse)(nil), "vault.v1.QuerySyncResponse") + proto.RegisterType((*QueryParamsRequest)(nil), "dwn.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "dwn.v1.QueryParamsResponse") + proto.RegisterType((*QuerySchemaRequest)(nil), "dwn.v1.QuerySchemaRequest") + proto.RegisterType((*QuerySchemaResponse)(nil), "dwn.v1.QuerySchemaResponse") + proto.RegisterType((*QueryAllocateRequest)(nil), "dwn.v1.QueryAllocateRequest") + proto.RegisterType((*QueryAllocateResponse)(nil), "dwn.v1.QueryAllocateResponse") + proto.RegisterType((*QuerySyncRequest)(nil), "dwn.v1.QuerySyncRequest") + proto.RegisterType((*QuerySyncResponse)(nil), "dwn.v1.QuerySyncResponse") } -func init() { proto.RegisterFile("vault/v1/query.proto", fileDescriptor_e6d49a2800ab3e4b) } +func init() { proto.RegisterFile("dwn/v1/query.proto", fileDescriptor_9a31dfed63924cb3) } -var fileDescriptor_e6d49a2800ab3e4b = []byte{ - // 515 bytes of a gzipped FileDescriptorProto +var fileDescriptor_9a31dfed63924cb3 = []byte{ + // 520 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0x3f, 0x6f, 0xd3, 0x40, - 0x18, 0xc6, 0xeb, 0xa4, 0x0d, 0xc9, 0x15, 0x21, 0x73, 0x84, 0xc8, 0x32, 0xad, 0x09, 0x56, 0x87, - 0x4c, 0xb6, 0x5a, 0x76, 0x10, 0x15, 0x0b, 0x1b, 0x18, 0x21, 0x24, 0x96, 0xe8, 0x72, 0x3e, 0x39, - 0x27, 0x9c, 0x3b, 0xd7, 0x67, 0x47, 0xf5, 0xca, 0xda, 0x05, 0x89, 0x4f, 0xc0, 0xb7, 0x61, 0xac, - 0xc4, 0xc2, 0x88, 0x12, 0x3e, 0x08, 0xba, 0x3f, 0x8e, 0x1b, 0xa7, 0x85, 0x25, 0xf2, 0x3d, 0xcf, - 0x9b, 0xdf, 0xf3, 0xbe, 0xbe, 0xd7, 0x60, 0xb8, 0x44, 0x65, 0x5a, 0x84, 0xcb, 0xd3, 0xf0, 0xa2, - 0x24, 0x79, 0x15, 0x64, 0x39, 0x2f, 0x38, 0xec, 0x2b, 0x35, 0x58, 0x9e, 0xba, 0x47, 0x09, 0xe7, - 0x49, 0x4a, 0x42, 0x94, 0xd1, 0x10, 0x31, 0xc6, 0x0b, 0x54, 0x50, 0xce, 0x84, 0xae, 0x73, 0x47, - 0x9b, 0x7f, 0x27, 0x84, 0x11, 0x41, 0x8d, 0xee, 0x0f, 0x01, 0x7c, 0x27, 0x71, 0x6f, 0x51, 0x8e, - 0x16, 0x22, 0x22, 0x17, 0x25, 0x11, 0x85, 0xff, 0x12, 0x3c, 0xda, 0x52, 0x45, 0xc6, 0x99, 0x20, - 0x70, 0x02, 0x7a, 0x99, 0x52, 0x1c, 0x6b, 0x6c, 0x4d, 0x0e, 0xcf, 0xec, 0xa0, 0x4e, 0x0f, 0x4c, - 0xa5, 0xf1, 0x37, 0xd8, 0xf7, 0x78, 0x4e, 0x16, 0xa8, 0x8d, 0xad, 0xd5, 0x06, 0x2b, 0x94, 0xb2, - 0x8b, 0x35, 0x95, 0xc6, 0xf7, 0x47, 0x60, 0xa8, 0x00, 0xaf, 0xd2, 0x94, 0x63, 0x54, 0x90, 0x1a, - 0xfc, 0xdd, 0x02, 0x8f, 0x5b, 0x86, 0x61, 0x3b, 0xe0, 0x9e, 0x28, 0x31, 0x26, 0x42, 0xf7, 0xdc, - 0x8f, 0xea, 0x23, 0xb4, 0x41, 0x17, 0xd3, 0xd8, 0xe9, 0x8c, 0xad, 0xc9, 0x20, 0x92, 0x8f, 0xd0, - 0x05, 0xfd, 0x05, 0xc2, 0x28, 0xe7, 0x9c, 0x39, 0x5d, 0x25, 0x6f, 0xce, 0xf0, 0x18, 0x80, 0xac, - 0x9c, 0xa5, 0x14, 0x4f, 0xcb, 0x9c, 0x3a, 0xfb, 0xca, 0x1d, 0x68, 0xe5, 0x43, 0x4e, 0xe1, 0x33, - 0x70, 0x9f, 0x5c, 0x66, 0x34, 0xaf, 0xa6, 0xb3, 0x94, 0xe3, 0xcf, 0xce, 0xc1, 0xd8, 0x9a, 0x74, - 0xa3, 0x43, 0xad, 0x9d, 0x4b, 0xc9, 0x3f, 0x01, 0xb6, 0x1e, 0xbe, 0x62, 0xd8, 0xf4, 0x2d, 0x7b, - 0x88, 0x69, 0xac, 0x3a, 0x1b, 0x44, 0xf2, 0xd1, 0xbf, 0xb2, 0xc0, 0xc3, 0x1b, 0x65, 0xff, 0x9d, - 0xa2, 0x79, 0x77, 0x9d, 0x7f, 0xbf, 0x3b, 0xc9, 0x40, 0x71, 0x9c, 0x4b, 0x86, 0x1e, 0xae, 0x3e, - 0x4a, 0x07, 0xcf, 0x11, 0x65, 0x6f, 0x5e, 0x9b, 0xc1, 0xea, 0xe3, 0xd9, 0x55, 0x17, 0x1c, 0xa8, - 0x6e, 0xe0, 0x14, 0xf4, 0xf4, 0x15, 0xc3, 0xa3, 0x26, 0x61, 0x77, 0x73, 0xdc, 0xe3, 0x3b, 0x5c, - 0x3d, 0x88, 0xef, 0x7c, 0xf9, 0xf9, 0xe7, 0x5b, 0x07, 0x42, 0x3b, 0xdc, 0xec, 0xa3, 0xde, 0x18, - 0x19, 0xa0, 0x1b, 0xde, 0x09, 0xd8, 0xda, 0xa1, 0x9d, 0x80, 0xed, 0x5d, 0xba, 0x2d, 0xc0, 0xcc, - 0x9f, 0x80, 0x7e, 0xbd, 0x1d, 0xd0, 0x6b, 0x41, 0x5a, 0xfb, 0xe4, 0x3e, 0xbd, 0xd3, 0x37, 0x31, - 0xae, 0x8a, 0x19, 0x42, 0xd8, 0xc4, 0xa0, 0x1a, 0xfe, 0x11, 0xec, 0xcb, 0xcb, 0x83, 0x6e, 0xbb, - 0xd3, 0xe6, 0xe2, 0xdd, 0x27, 0xb7, 0x7a, 0x06, 0x3e, 0x52, 0x70, 0x1b, 0x3e, 0xb8, 0x31, 0x43, - 0xc5, 0xf0, 0xf9, 0x8b, 0x1f, 0x2b, 0xcf, 0xba, 0x5e, 0x79, 0xd6, 0xef, 0x95, 0x67, 0x7d, 0x5d, - 0x7b, 0x7b, 0xd7, 0x6b, 0x6f, 0xef, 0xd7, 0xda, 0xdb, 0xfb, 0x74, 0x92, 0xd0, 0x62, 0x5e, 0xce, - 0x02, 0xcc, 0x17, 0x21, 0x67, 0x82, 0xb3, 0x3c, 0x54, 0x3f, 0x97, 0x86, 0x50, 0x54, 0x19, 0x11, - 0xb3, 0x9e, 0xfa, 0xe4, 0x9f, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x89, 0x02, 0x8d, 0x5a, 0x4a, - 0x04, 0x00, 0x00, + 0x18, 0xc6, 0xe3, 0xa4, 0x0d, 0xc9, 0x15, 0x55, 0xe1, 0x08, 0x95, 0x31, 0xad, 0x15, 0x2c, 0x84, + 0x32, 0xd9, 0x6a, 0x59, 0x61, 0xa0, 0x62, 0x61, 0x03, 0x57, 0x2c, 0x30, 0x54, 0x97, 0xf3, 0x29, + 0x39, 0xe1, 0xdc, 0xb9, 0x77, 0x76, 0x5a, 0xaf, 0x6c, 0x6c, 0x48, 0x7c, 0x02, 0xbe, 0x0d, 0x63, + 0x25, 0x16, 0x46, 0x94, 0xf0, 0x2d, 0x58, 0xd0, 0xfd, 0x71, 0x13, 0x9b, 0x00, 0x8b, 0xe5, 0x7b, + 0x9e, 0xf3, 0xef, 0x7d, 0x5e, 0xdf, 0x7b, 0x00, 0x26, 0x97, 0x2c, 0x5a, 0x1c, 0x47, 0x17, 0x05, + 0x11, 0x65, 0x98, 0x09, 0x9e, 0x73, 0xd8, 0x4d, 0x2e, 0x59, 0xb8, 0x38, 0xf6, 0x0e, 0xa7, 0x9c, + 0x4f, 0x53, 0x12, 0xa1, 0x8c, 0x46, 0x88, 0x31, 0x9e, 0xa3, 0x9c, 0x72, 0x26, 0xcd, 0x2e, 0x6f, + 0x68, 0xbf, 0x9c, 0x12, 0x46, 0x24, 0xb5, 0x6a, 0x30, 0x04, 0xf0, 0xb5, 0x42, 0xbd, 0x42, 0x02, + 0xcd, 0x65, 0x4c, 0x2e, 0x0a, 0x22, 0xf3, 0xe0, 0x19, 0xb8, 0x5b, 0x53, 0x65, 0xc6, 0x99, 0x24, + 0xf0, 0x31, 0xe8, 0x66, 0x5a, 0x71, 0x9d, 0x91, 0x33, 0xde, 0x3b, 0xd9, 0x0f, 0x4d, 0xe5, 0xd0, + 0xee, 0xb3, 0xee, 0x0d, 0xf4, 0x0c, 0xcf, 0xc8, 0x1c, 0x35, 0xa1, 0x95, 0xba, 0x86, 0x4a, 0xad, + 0x34, 0xa1, 0x76, 0x9f, 0x75, 0x83, 0x03, 0x30, 0xd4, 0x9f, 0x3f, 0x4f, 0x53, 0x8e, 0x51, 0x4e, + 0x2a, 0xec, 0x17, 0x07, 0xdc, 0x6b, 0x18, 0x96, 0xec, 0x82, 0x5b, 0xb2, 0xc0, 0x98, 0x48, 0x93, + 0xb7, 0x17, 0x57, 0x4b, 0x38, 0x00, 0x1d, 0x4c, 0x13, 0xb7, 0x3d, 0x72, 0xc6, 0xfd, 0x58, 0xbd, + 0x42, 0x0f, 0xf4, 0xe6, 0x08, 0x23, 0xc1, 0x39, 0x73, 0x3b, 0x5a, 0xbe, 0x59, 0xc3, 0x23, 0x00, + 0xb2, 0x62, 0x92, 0x52, 0x7c, 0x5e, 0x08, 0xea, 0xee, 0x68, 0xb7, 0x6f, 0x94, 0x37, 0x82, 0xc2, + 0x87, 0xe0, 0x36, 0xb9, 0xca, 0xa8, 0x28, 0xcf, 0x27, 0x29, 0xc7, 0xef, 0xdd, 0xdd, 0x91, 0x33, + 0xee, 0xc4, 0x7b, 0x46, 0x3b, 0x55, 0x52, 0xf0, 0x08, 0x0c, 0x4c, 0xeb, 0x25, 0xc3, 0x36, 0xb7, + 0xca, 0x90, 0xd0, 0x44, 0x27, 0xeb, 0xc7, 0xea, 0x35, 0xf8, 0xe8, 0x80, 0x3b, 0x1b, 0xdb, 0xfe, + 0xdb, 0xc5, 0xfa, 0xcf, 0xb5, 0xff, 0xf5, 0xe7, 0x14, 0x01, 0x25, 0x89, 0x50, 0x04, 0xd3, 0x5a, + 0xb5, 0x54, 0x0e, 0x9e, 0x21, 0xca, 0x5e, 0xbe, 0xb0, 0x6d, 0x55, 0xcb, 0x93, 0x5f, 0x6d, 0xb0, + 0xab, 0xb3, 0xc0, 0x77, 0xa0, 0x6b, 0x8e, 0x17, 0x7a, 0x15, 0xff, 0xcf, 0x89, 0xf1, 0x1e, 0x6c, + 0xf5, 0x4c, 0x0b, 0x81, 0xfb, 0xe1, 0xdb, 0xcf, 0xcf, 0x6d, 0x08, 0x07, 0xd1, 0x02, 0x15, 0x69, + 0xae, 0xa6, 0xd0, 0x4c, 0x8a, 0x82, 0x9b, 0xb0, 0x0d, 0x78, 0x6d, 0x72, 0x1a, 0xf0, 0xfa, 0xfc, + 0x6c, 0x83, 0xdb, 0xbe, 0x31, 0xe8, 0x55, 0x33, 0x01, 0x0f, 0x6b, 0x88, 0xc6, 0x0c, 0x79, 0x47, + 0x7f, 0x71, 0x6d, 0x09, 0x4f, 0x97, 0x18, 0x42, 0xb8, 0x2e, 0x81, 0x2a, 0xf0, 0x19, 0xd8, 0x51, + 0xc7, 0x05, 0xdd, 0x7a, 0xc6, 0xf5, 0x41, 0x7b, 0xf7, 0xb7, 0x38, 0x16, 0x7c, 0xa0, 0xc1, 0x03, + 0xb8, 0xbf, 0x91, 0xbd, 0x64, 0xf8, 0xf4, 0xe9, 0xd7, 0xa5, 0xef, 0x5c, 0x2f, 0x7d, 0xe7, 0xc7, + 0xd2, 0x77, 0x3e, 0xad, 0xfc, 0xd6, 0xf5, 0xca, 0x6f, 0x7d, 0x5f, 0xf9, 0xad, 0xb7, 0xc1, 0x94, + 0xe6, 0xb3, 0x62, 0x12, 0x62, 0x3e, 0x8f, 0x38, 0x93, 0x9c, 0x89, 0x48, 0x3f, 0xae, 0x22, 0x75, + 0xbd, 0xf3, 0x32, 0x23, 0x72, 0xd2, 0xd5, 0x57, 0xfb, 0xc9, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x73, 0xa2, 0xa3, 0xc2, 0x2c, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -510,7 +510,7 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/vault.v1.Query/Params", in, out, opts...) + err := c.cc.Invoke(ctx, "/dwn.v1.Query/Params", in, out, opts...) if err != nil { return nil, err } @@ -519,7 +519,7 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . func (c *queryClient) Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error) { out := new(QuerySchemaResponse) - err := c.cc.Invoke(ctx, "/vault.v1.Query/Schema", in, out, opts...) + err := c.cc.Invoke(ctx, "/dwn.v1.Query/Schema", in, out, opts...) if err != nil { return nil, err } @@ -528,7 +528,7 @@ func (c *queryClient) Schema(ctx context.Context, in *QuerySchemaRequest, opts . func (c *queryClient) Allocate(ctx context.Context, in *QueryAllocateRequest, opts ...grpc.CallOption) (*QueryAllocateResponse, error) { out := new(QueryAllocateResponse) - err := c.cc.Invoke(ctx, "/vault.v1.Query/Allocate", in, out, opts...) + err := c.cc.Invoke(ctx, "/dwn.v1.Query/Allocate", in, out, opts...) if err != nil { return nil, err } @@ -537,7 +537,7 @@ func (c *queryClient) Allocate(ctx context.Context, in *QueryAllocateRequest, op func (c *queryClient) Sync(ctx context.Context, in *QuerySyncRequest, opts ...grpc.CallOption) (*QuerySyncResponse, error) { out := new(QuerySyncResponse) - err := c.cc.Invoke(ctx, "/vault.v1.Query/Sync", in, out, opts...) + err := c.cc.Invoke(ctx, "/dwn.v1.Query/Sync", in, out, opts...) if err != nil { return nil, err } @@ -590,7 +590,7 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/vault.v1.Query/Params", + FullMethod: "/dwn.v1.Query/Params", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) @@ -608,7 +608,7 @@ func _Query_Schema_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/vault.v1.Query/Schema", + FullMethod: "/dwn.v1.Query/Schema", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).Schema(ctx, req.(*QuerySchemaRequest)) @@ -626,7 +626,7 @@ func _Query_Allocate_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/vault.v1.Query/Allocate", + FullMethod: "/dwn.v1.Query/Allocate", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).Allocate(ctx, req.(*QueryAllocateRequest)) @@ -644,7 +644,7 @@ func _Query_Sync_Handler(srv interface{}, ctx context.Context, dec func(interfac } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/vault.v1.Query/Sync", + FullMethod: "/dwn.v1.Query/Sync", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).Sync(ctx, req.(*QuerySyncRequest)) @@ -654,7 +654,7 @@ func _Query_Sync_Handler(srv interface{}, ctx context.Context, dec func(interfac var Query_serviceDesc = _Query_serviceDesc var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "vault.v1.Query", + ServiceName: "dwn.v1.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ { @@ -675,7 +675,7 @@ var _Query_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "vault/v1/query.proto", + Metadata: "dwn/v1/query.proto", } func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { diff --git a/x/vault/types/query.pb.gw.go b/x/dwn/types/query.pb.gw.go similarity index 99% rename from x/vault/types/query.pb.gw.go rename to x/dwn/types/query.pb.gw.go index 3843a9fa9..1e05aa046 100644 --- a/x/vault/types/query.pb.gw.go +++ b/x/dwn/types/query.pb.gw.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: vault/v1/query.proto +// source: dwn/v1/query.proto /* Package types is a reverse proxy. diff --git a/x/vault/types/spawn.go b/x/dwn/types/spawn.go similarity index 95% rename from x/vault/types/spawn.go rename to x/dwn/types/spawn.go index 02822ea11..6fb6464dd 100644 --- a/x/vault/types/spawn.go +++ b/x/dwn/types/spawn.go @@ -4,7 +4,7 @@ import ( "github.com/ipfs/boxo/files" "github.com/onsonr/sonr/pkg/core/dwn" - "github.com/onsonr/sonr/x/vault/types/static" + "github.com/onsonr/sonr/x/dwn/types/static" ) const ( diff --git a/x/dwn/types/state.pb.go b/x/dwn/types/state.pb.go new file mode 100644 index 000000000..f3029c324 --- /dev/null +++ b/x/dwn/types/state.pb.go @@ -0,0 +1,355 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dwn/v1/state.proto + +package types + +import ( + _ "cosmossdk.io/orm" + fmt "fmt" + proto "github.com/cosmos/gogoproto/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.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type ExampleData struct { + Account []byte `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` +} + +func (m *ExampleData) Reset() { *m = ExampleData{} } +func (m *ExampleData) String() string { return proto.CompactTextString(m) } +func (*ExampleData) ProtoMessage() {} +func (*ExampleData) Descriptor() ([]byte, []int) { + return fileDescriptor_040a9b061177db90, []int{0} +} +func (m *ExampleData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ExampleData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ExampleData.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 *ExampleData) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExampleData.Merge(m, src) +} +func (m *ExampleData) XXX_Size() int { + return m.Size() +} +func (m *ExampleData) XXX_DiscardUnknown() { + xxx_messageInfo_ExampleData.DiscardUnknown(m) +} + +var xxx_messageInfo_ExampleData proto.InternalMessageInfo + +func (m *ExampleData) GetAccount() []byte { + if m != nil { + return m.Account + } + return nil +} + +func (m *ExampleData) GetAmount() uint64 { + if m != nil { + return m.Amount + } + return 0 +} + +func init() { + proto.RegisterType((*ExampleData)(nil), "dwn.v1.ExampleData") +} + +func init() { proto.RegisterFile("dwn/v1/state.proto", fileDescriptor_040a9b061177db90) } + +var fileDescriptor_040a9b061177db90 = []byte{ + // 205 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4a, 0x29, 0xcf, 0xd3, + 0x2f, 0x33, 0xd4, 0x2f, 0x2e, 0x49, 0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, + 0x4b, 0x29, 0xcf, 0xd3, 0x2b, 0x33, 0x94, 0x12, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0xcf, + 0x2f, 0xca, 0x05, 0x29, 0xc9, 0x2f, 0xca, 0x85, 0x28, 0x50, 0x4a, 0xe0, 0xe2, 0x76, 0xad, 0x48, + 0xcc, 0x2d, 0xc8, 0x49, 0x75, 0x49, 0x2c, 0x49, 0x14, 0x92, 0xe0, 0x62, 0x4f, 0x4c, 0x4e, 0xce, + 0x2f, 0xcd, 0x2b, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x09, 0x82, 0x71, 0x85, 0xc4, 0xb8, 0xd8, + 0x12, 0x73, 0xc1, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x2c, 0x41, 0x50, 0x9e, 0x95, 0xfc, 0xa7, 0x79, + 0x97, 0xfb, 0x98, 0x25, 0xb9, 0x38, 0xe1, 0x3a, 0x85, 0xb8, 0x60, 0x4a, 0x05, 0x18, 0x25, 0x18, + 0x9d, 0x6c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, + 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x29, 0x3d, 0xb3, + 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x3f, 0x3f, 0xaf, 0x38, 0x3f, 0xaf, 0x48, 0x1f, + 0x4c, 0x54, 0xe8, 0x83, 0x7c, 0x52, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x76, 0xa6, 0x31, + 0x20, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x48, 0x77, 0x36, 0xdd, 0x00, 0x00, 0x00, +} + +func (m *ExampleData) 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 *ExampleData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ExampleData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Amount != 0 { + i = encodeVarintState(dAtA, i, uint64(m.Amount)) + i-- + dAtA[i] = 0x10 + } + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintState(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintState(dAtA []byte, offset int, v uint64) int { + offset -= sovState(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ExampleData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Account) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + if m.Amount != 0 { + n += 1 + sovState(uint64(m.Amount)) + } + return n +} + +func sovState(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozState(x uint64) (n int) { + return sovState(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ExampleData) 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 ErrIntOverflowState + } + 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: ExampleData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExampleData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = append(m.Account[:0], dAtA[iNdEx:postIndex]...) + if m.Account == nil { + m.Account = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + m.Amount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Amount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipState(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipState(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, ErrIntOverflowState + } + 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, ErrIntOverflowState + } + 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, ErrIntOverflowState + } + 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, ErrInvalidLengthState + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupState + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthState + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthState = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowState = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupState = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/vault/types/static/index.html b/x/dwn/types/static/index.html similarity index 100% rename from x/vault/types/static/index.html rename to x/dwn/types/static/index.html diff --git a/x/vault/types/static/static.go b/x/dwn/types/static/static.go similarity index 100% rename from x/vault/types/static/static.go rename to x/dwn/types/static/static.go diff --git a/x/vault/types/static/sw.js b/x/dwn/types/static/sw.js similarity index 100% rename from x/vault/types/static/sw.js rename to x/dwn/types/static/sw.js diff --git a/x/vault/types/tx.pb.go b/x/dwn/types/tx.pb.go similarity index 52% rename from x/vault/types/tx.pb.go rename to x/dwn/types/tx.pb.go index 3f273d481..128b51a87 100644 --- a/x/vault/types/tx.pb.go +++ b/x/dwn/types/tx.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: vault/v1/tx.proto +// source: dwn/v1/tx.proto package types @@ -11,7 +11,6 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" - _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -47,7 +46,7 @@ func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParams) ProtoMessage() {} func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_311d0123a4881c5c, []int{0} + return fileDescriptor_32d2464465560de7, []int{0} } func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -101,7 +100,7 @@ func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParamsResponse) ProtoMessage() {} func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_311d0123a4881c5c, []int{1} + return fileDescriptor_32d2464465560de7, []int{1} } func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -130,37 +129,140 @@ func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo -func init() { - proto.RegisterType((*MsgUpdateParams)(nil), "vault.v1.MsgUpdateParams") - proto.RegisterType((*MsgUpdateParamsResponse)(nil), "vault.v1.MsgUpdateParamsResponse") +// MsgInitialize spawns a New Vault with Unclaimed State. This is a one-time +// operation that must be performed interacting with the Vault. +// +// Since: cosmos-sdk 0.47 +type MsgInitialize struct { + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` } -func init() { proto.RegisterFile("vault/v1/tx.proto", fileDescriptor_311d0123a4881c5c) } +func (m *MsgInitialize) Reset() { *m = MsgInitialize{} } +func (m *MsgInitialize) String() string { return proto.CompactTextString(m) } +func (*MsgInitialize) ProtoMessage() {} +func (*MsgInitialize) Descriptor() ([]byte, []int) { + return fileDescriptor_32d2464465560de7, []int{2} +} +func (m *MsgInitialize) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgInitialize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgInitialize.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 *MsgInitialize) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgInitialize.Merge(m, src) +} +func (m *MsgInitialize) XXX_Size() int { + return m.Size() +} +func (m *MsgInitialize) XXX_DiscardUnknown() { + xxx_messageInfo_MsgInitialize.DiscardUnknown(m) +} -var fileDescriptor_311d0123a4881c5c = []byte{ - // 338 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x50, 0x4d, 0x4b, 0x02, 0x41, - 0x18, 0xde, 0xe9, 0x43, 0x72, 0x8a, 0x3e, 0x16, 0x49, 0x5d, 0x62, 0x33, 0xe9, 0x20, 0x42, 0x3b, - 0x68, 0xd0, 0xa1, 0x43, 0x90, 0xe7, 0x84, 0x30, 0xba, 0x78, 0x89, 0x51, 0x87, 0x71, 0xc1, 0x9d, - 0x77, 0xd9, 0x77, 0x14, 0xbd, 0x45, 0xb7, 0x6e, 0xfd, 0x14, 0x0f, 0xfd, 0x08, 0x8f, 0xd2, 0xa9, - 0x53, 0x84, 0x1e, 0xfc, 0x1b, 0xe1, 0xee, 0xda, 0x92, 0xd0, 0x65, 0x98, 0xf7, 0xf9, 0x9a, 0x67, - 0x5e, 0x7a, 0x34, 0xe0, 0xfd, 0x9e, 0x66, 0x83, 0x0a, 0xd3, 0x43, 0xc7, 0x0f, 0x40, 0x83, 0xb9, - 0x13, 0x42, 0xce, 0xa0, 0x62, 0x65, 0xdb, 0x80, 0x1e, 0x20, 0xf3, 0x50, 0x2e, 0x15, 0x1e, 0xca, - 0x48, 0x62, 0xe5, 0x23, 0xe2, 0x29, 0x9c, 0x58, 0x34, 0xc4, 0x54, 0x46, 0x82, 0x84, 0x08, 0x5f, - 0xde, 0x62, 0xf4, 0x44, 0x02, 0xc8, 0x9e, 0x60, 0xdc, 0x77, 0x19, 0x57, 0x0a, 0x34, 0xd7, 0x2e, - 0xa8, 0x95, 0xe7, 0xf8, 0xb7, 0x84, 0x14, 0x4a, 0xa0, 0x1b, 0xe3, 0xc5, 0x57, 0x42, 0x0f, 0xea, - 0x28, 0x1f, 0xfd, 0x0e, 0xd7, 0xe2, 0x9e, 0x07, 0xdc, 0x43, 0xf3, 0x8a, 0xa6, 0x79, 0x5f, 0x77, - 0x21, 0x70, 0xf5, 0x28, 0x47, 0x0a, 0xa4, 0x94, 0xae, 0xe5, 0x3e, 0xde, 0x2f, 0x32, 0x71, 0x89, - 0xdb, 0x4e, 0x27, 0x10, 0x88, 0x0f, 0x3a, 0x70, 0x95, 0x6c, 0x24, 0x52, 0xd3, 0xa1, 0x29, 0x3f, - 0x4c, 0xc8, 0x6d, 0x14, 0x48, 0x69, 0xb7, 0x7a, 0xe8, 0xac, 0xbe, 0xe9, 0x44, 0xc9, 0xb5, 0xad, - 0xc9, 0xd7, 0xa9, 0xd1, 0x88, 0x55, 0xd7, 0xfb, 0x2f, 0x8b, 0x71, 0x39, 0xf1, 0x17, 0xf3, 0x34, - 0xbb, 0x56, 0xa5, 0x21, 0xd0, 0x07, 0x85, 0xa2, 0xda, 0xa4, 0x9b, 0x75, 0x94, 0xe6, 0x1d, 0xdd, - 0xfb, 0xd3, 0x34, 0x9f, 0xbc, 0xb0, 0xe6, 0xb4, 0xce, 0xfe, 0xa5, 0x56, 0xa1, 0xd6, 0xf6, 0xf3, - 0x62, 0x5c, 0x26, 0xb5, 0x9b, 0xc9, 0xcc, 0x26, 0xd3, 0x99, 0x4d, 0xbe, 0x67, 0x36, 0x79, 0x9b, - 0xdb, 0xc6, 0x74, 0x6e, 0x1b, 0x9f, 0x73, 0xdb, 0x68, 0x9e, 0x4b, 0x57, 0x77, 0xfb, 0x2d, 0xa7, - 0x0d, 0x1e, 0x03, 0x85, 0xa0, 0x02, 0x16, 0x1e, 0x43, 0x16, 0x6d, 0x53, 0x8f, 0x7c, 0x81, 0xad, - 0x54, 0xb8, 0xc9, 0xcb, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9a, 0xa7, 0x73, 0x6d, 0xe8, 0x01, - 0x00, 0x00, +var xxx_messageInfo_MsgInitialize proto.InternalMessageInfo + +func (m *MsgInitialize) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgInitialize) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +// MsgInitializeResponse defines the response structure for executing a +// MsgInitialize message. +// +// Since: cosmos-sdk 0.47 +type MsgInitializeResponse struct { +} + +func (m *MsgInitializeResponse) Reset() { *m = MsgInitializeResponse{} } +func (m *MsgInitializeResponse) String() string { return proto.CompactTextString(m) } +func (*MsgInitializeResponse) ProtoMessage() {} +func (*MsgInitializeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_32d2464465560de7, []int{3} +} +func (m *MsgInitializeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgInitializeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgInitializeResponse.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 *MsgInitializeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgInitializeResponse.Merge(m, src) +} +func (m *MsgInitializeResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgInitializeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgInitializeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgInitializeResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgUpdateParams)(nil), "dwn.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "dwn.v1.MsgUpdateParamsResponse") + proto.RegisterType((*MsgInitialize)(nil), "dwn.v1.MsgInitialize") + proto.RegisterType((*MsgInitializeResponse)(nil), "dwn.v1.MsgInitializeResponse") +} + +func init() { proto.RegisterFile("dwn/v1/tx.proto", fileDescriptor_32d2464465560de7) } + +var fileDescriptor_32d2464465560de7 = []byte{ + // 361 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4f, 0x29, 0xcf, 0xd3, + 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4b, 0x29, 0xcf, + 0xd3, 0x2b, 0x33, 0x94, 0x12, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0xcf, 0x2d, 0x4e, 0x07, + 0xc9, 0xe7, 0x16, 0xa7, 0x43, 0x14, 0x48, 0x89, 0x40, 0x75, 0xa4, 0xa7, 0xe6, 0xa5, 0x16, 0x67, + 0x16, 0xc3, 0x44, 0xd3, 0xf3, 0xd3, 0xf3, 0xc1, 0x4c, 0x7d, 0x10, 0x0b, 0x2a, 0x2a, 0x09, 0x31, + 0x24, 0x1e, 0x22, 0x01, 0xe1, 0x40, 0xa4, 0x94, 0xda, 0x19, 0xb9, 0xf8, 0x7d, 0x8b, 0xd3, 0x43, + 0x0b, 0x52, 0x12, 0x4b, 0x52, 0x03, 0x12, 0x8b, 0x12, 0x73, 0x8b, 0x85, 0xcc, 0xb8, 0x38, 0x13, + 0x4b, 0x4b, 0x32, 0xf2, 0x8b, 0x32, 0x4b, 0x2a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x9d, 0x24, + 0x2e, 0x6d, 0xd1, 0x15, 0x81, 0x6a, 0x74, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x0e, 0x2e, 0x29, + 0xca, 0xcc, 0x4b, 0x0f, 0x42, 0x28, 0x15, 0xd2, 0xe1, 0x62, 0x2b, 0x00, 0x9b, 0x20, 0xc1, 0xa4, + 0xc0, 0xa8, 0xc1, 0x6d, 0xc4, 0xa7, 0x07, 0xf1, 0x84, 0x1e, 0xc4, 0x5c, 0x27, 0x96, 0x13, 0xf7, + 0xe4, 0x19, 0x82, 0xa0, 0x6a, 0xac, 0xf8, 0x9a, 0x9e, 0x6f, 0xd0, 0x42, 0xe8, 0x56, 0x92, 0xe4, + 0x12, 0x47, 0x73, 0x48, 0x50, 0x6a, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x52, 0x2b, 0x23, 0x17, + 0xaf, 0x6f, 0x71, 0xba, 0x67, 0x5e, 0x66, 0x49, 0x66, 0x62, 0x4e, 0x66, 0x55, 0xea, 0x00, 0x39, + 0x51, 0x9c, 0x4b, 0x14, 0xc5, 0x19, 0x30, 0x07, 0x1a, 0xcd, 0x62, 0xe4, 0x62, 0xf6, 0x2d, 0x4e, + 0x17, 0xf2, 0xe0, 0xe2, 0x41, 0x09, 0x49, 0x71, 0x98, 0xf1, 0x68, 0x3e, 0x93, 0x92, 0xc7, 0x21, + 0x01, 0x33, 0x51, 0xc8, 0x89, 0x8b, 0x0b, 0xc9, 0xbb, 0xa2, 0x48, 0xca, 0x11, 0xc2, 0x52, 0xb2, + 0x58, 0x85, 0x61, 0x66, 0x48, 0xb1, 0x36, 0x3c, 0xdf, 0xa0, 0xc5, 0xe8, 0x64, 0x73, 0xe2, 0x91, + 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, + 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x4a, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, + 0xc9, 0xf9, 0xb9, 0xfa, 0xf9, 0x79, 0xc5, 0xf9, 0x79, 0x45, 0xfa, 0x60, 0xa2, 0x42, 0x1f, 0x94, + 0xb8, 0x4a, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0xe9, 0xc4, 0x18, 0x10, 0x00, 0x00, 0xff, + 0xff, 0xbb, 0x62, 0x4e, 0x8b, 0xa2, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -179,6 +281,8 @@ type MsgClient interface { // // Since: cosmos-sdk 0.47 UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + // Initialize spawns a new Vault + Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error) } type msgClient struct { @@ -191,7 +295,16 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { out := new(MsgUpdateParamsResponse) - err := c.cc.Invoke(ctx, "/vault.v1.Msg/UpdateParams", in, out, opts...) + err := c.cc.Invoke(ctx, "/dwn.v1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error) { + out := new(MsgInitializeResponse) + err := c.cc.Invoke(ctx, "/dwn.v1.Msg/Initialize", in, out, opts...) if err != nil { return nil, err } @@ -204,6 +317,8 @@ type MsgServer interface { // // Since: cosmos-sdk 0.47 UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + // Initialize spawns a new Vault + Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -213,6 +328,9 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") } +func (*UnimplementedMsgServer) Initialize(ctx context.Context, req *MsgInitialize) (*MsgInitializeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Initialize not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -228,7 +346,7 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/vault.v1.Msg/UpdateParams", + FullMethod: "/dwn.v1.Msg/UpdateParams", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) @@ -236,18 +354,40 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_Initialize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgInitialize) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Initialize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dwn.v1.Msg/Initialize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Initialize(ctx, req.(*MsgInitialize)) + } + return interceptor(ctx, in, info, handler) +} + var Msg_serviceDesc = _Msg_serviceDesc var _Msg_serviceDesc = grpc.ServiceDesc{ - ServiceName: "vault.v1.Msg", + ServiceName: "dwn.v1.Msg", HandlerType: (*MsgServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "UpdateParams", Handler: _Msg_UpdateParams_Handler, }, + { + MethodName: "Initialize", + Handler: _Msg_Initialize_Handler, + }, }, Streams: []grpc.StreamDesc{}, - Metadata: "vault/v1/tx.proto", + Metadata: "dwn/v1/tx.proto", } func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { @@ -313,6 +453,69 @@ func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *MsgInitialize) 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 *MsgInitialize) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgInitialize) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgInitializeResponse) 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 *MsgInitializeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgInitializeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -348,6 +551,30 @@ func (m *MsgUpdateParamsResponse) Size() (n int) { return n } +func (m *MsgInitialize) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgInitializeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -519,6 +746,171 @@ func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgInitialize) 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 ErrIntOverflowTx + } + 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: MsgInitialize: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgInitialize: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgInitializeResponse) 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 ErrIntOverflowTx + } + 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: MsgInitializeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgInitializeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/service/keeper/genesis.go b/x/service/keeper/genesis.go deleted file mode 100644 index 9004983fd..000000000 --- a/x/service/keeper/genesis.go +++ /dev/null @@ -1,37 +0,0 @@ -package keeper - -import ( - "context" - - "cosmossdk.io/log" - - "github.com/onsonr/sonr/x/service/types" -) - -func (k Keeper) Logger() log.Logger { - return k.logger -} - -// InitGenesis initializes the module's state from a genesis state. -func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { - // this line is used by starport scaffolding # genesis/module/init - if err := data.Params.Validate(); err != nil { - return err - } - - return k.Params.Set(ctx, data.Params) -} - -// ExportGenesis exports the module's state to a genesis state. -func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { - params, err := k.Params.Get(ctx) - if err != nil { - panic(err) - } - - // this line is used by starport scaffolding # genesis/module/export - - return &types.GenesisState{ - Params: params, - } -} diff --git a/x/service/keeper/orm_test.go b/x/service/keeper/orm_test.go deleted file mode 100644 index 49c95c10a..000000000 --- a/x/service/keeper/orm_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package keeper_test - -import ( - "testing" -) - -func TestORM(t *testing.T) { - f := SetupTest(t) - if f == nil { - return - } - - // dt := f.k.OrmDB.ExampleDataTable() - // acc := []byte("test_acc") - // amt := uint64(7) - // - // err := dt.Insert(f.ctx, &apiv1.ExampleData{ - // Account: acc, - // Amount: amt, - // }) - // require.NoError(t, err) - // - // d, err := dt.Has(f.ctx, []byte("test_acc")) - // require.NoError(t, err) - // require.True(t, d) - // - // res, err := dt.Get(f.ctx, []byte("test_acc")) - // require.NoError(t, err) - // require.NotNil(t, res) - // require.EqualValues(t, amt, res.Amount) -} diff --git a/x/service/types/errors.go b/x/service/types/errors.go deleted file mode 100644 index b169c4acc..000000000 --- a/x/service/types/errors.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import sdkerrors "cosmossdk.io/errors" - -var ( - ErrInvalidGenesisState = sdkerrors.Register(ModuleName, 100, "invalid genesis state") - ErrInvalidServiceOrigin = sdkerrors.Register(ModuleName, 200, "invalid service origin") - ErrUnrecognizedService = sdkerrors.Register(ModuleName, 201, "unrecognized service") - ErrInvalidServiceGroup = sdkerrors.Register(ModuleName, 202, "invalid group") -) diff --git a/x/service/README.md b/x/svc/README.md similarity index 57% rename from x/service/README.md rename to x/svc/README.md index 85c7cbb04..079760c07 100644 --- a/x/service/README.md +++ b/x/svc/README.md @@ -1,12 +1,12 @@ -# `x/service` +# `x/svc` -The Service module is responsible for managing the registration and authorization of services within the Sonr ecosystem. It provides a secure and verifiable mechanism for registering and authorizing services using Decentralized Identifiers (DIDs). +The svc module is responsible for managing the registration and authorization of services within the Sonr ecosystem. It provides a secure and verifiable mechanism for registering and authorizing services using Decentralized Identifiers (DIDs). ## Concepts -- **Service**: A decentralized service on the Sonr Blockchain with properties such as ID, authority, origin, name, description, category, tags, and expiry height. +- **Service**: A decentralized svc on the Sonr Blockchain with properties such as ID, authority, origin, name, description, category, tags, and expiry height. - **Profile**: Represents a DID alias with properties like ID, subject, origin, and controller. -- **Metadata**: Contains information about a service, including name, description, category, icon, and tags. +- **Metadata**: Contains information about a svc, including name, description, category, icon, and tags. ### Dependencies @@ -42,14 +42,14 @@ Updates the module parameters. Can only be executed by the governance account. ### MsgRegisterService -Registers a new service on the blockchain. Requires a valid TXT record in DNS for the origin. +Registers a new svc on the blockchain. Requires a valid TXT record in DNS for the origin. ## Params The module has the following parameters: -- `categories`: List of allowed service categories -- `types`: List of allowed service types +- `categories`: List of allowed svc categories +- `types`: List of allowed svc types ## Query @@ -63,7 +63,7 @@ Retrieves all parameters of the module. ### gRPC -The module provides a gRPC Query service with the following RPC: +The module provides a gRPC Query svc with the following RPC: - `Params`: Get all parameters of the module @@ -77,10 +77,10 @@ The module provides a gRPC Query service with the following RPC: ## Future Improvements -- Implement service discovery mechanisms -- Add support for service reputation and rating systems -- Enhance service metadata with more detailed information -- Implement service update and deactivation functionality +- Implement svc discovery mechanisms +- Add support for svc reputation and rating systems +- Enhance svc metadata with more detailed information +- Implement svc update and deactivation functionality ## Tests @@ -88,4 +88,4 @@ The module provides a gRPC Query service with the following RPC: ## Appendix -This module is part of the Sonr blockchain project and interacts with other modules such as DID and NFT modules to provide a comprehensive decentralized service ecosystem. +This module is part of the Sonr blockchain project and interacts with other modules such as DID and NFT modules to provide a comprehensive decentralized svc ecosystem. diff --git a/x/service/autocli.go b/x/svc/autocli.go similarity index 94% rename from x/service/autocli.go rename to x/svc/autocli.go index dc7993c19..c6ef5491e 100644 --- a/x/service/autocli.go +++ b/x/svc/autocli.go @@ -2,7 +2,7 @@ package module import ( autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" - modulev1 "github.com/onsonr/sonr/api/service/v1" + modulev1 "github.com/onsonr/sonr/api/svc/v1" ) // AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. diff --git a/x/service/client/cli/query.go b/x/svc/client/cli/query.go similarity index 96% rename from x/service/client/cli/query.go rename to x/svc/client/cli/query.go index 5ad2fc882..5aa13f08b 100644 --- a/x/service/client/cli/query.go +++ b/x/svc/client/cli/query.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/onsonr/sonr/x/service/types" + "github.com/onsonr/sonr/x/svc/types" ) // !NOTE: Must enable in module.go (disabled in favor of autocli.go) diff --git a/x/service/client/cli/tx.go b/x/svc/client/cli/tx.go similarity index 87% rename from x/service/client/cli/tx.go rename to x/svc/client/cli/tx.go index 3c9b4b605..14fbb4670 100644 --- a/x/service/client/cli/tx.go +++ b/x/svc/client/cli/tx.go @@ -1,13 +1,15 @@ package cli import ( + "strconv" + "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/onsonr/sonr/x/service/types" + "github.com/onsonr/sonr/x/svc/types" ) // !NOTE: Must enable in module.go (disabled in favor of autocli.go) @@ -44,15 +46,15 @@ func MsgUpdateParams() *cobra.Command { senderAddress := cliCtx.GetFromAddress() - // someValue, err := strconv.ParseBool(args[0]) - // if err != nil { - // return err - // } - // + someValue, err := strconv.ParseBool(args[0]) + if err != nil { + return err + } + msg := &types.MsgUpdateParams{ Authority: senderAddress.String(), - Params: types.Params{ - // SomeValue: someValue, + Params: types.Params{ + SomeValue: someValue, }, } diff --git a/x/service/depinject.go b/x/svc/depinject.go similarity index 70% rename from x/service/depinject.go rename to x/svc/depinject.go index d535caf81..b9dc2fa9a 100644 --- a/x/service/depinject.go +++ b/x/svc/depinject.go @@ -3,23 +3,21 @@ package module import ( "os" + "github.com/cosmos/cosmos-sdk/codec" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" "cosmossdk.io/core/store" "cosmossdk.io/depinject" "cosmossdk.io/log" - nftkeeper "cosmossdk.io/x/nft/keeper" - "github.com/cosmos/cosmos-sdk/codec" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper" - slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - modulev1 "github.com/onsonr/sonr/api/service/module/v1" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - "github.com/onsonr/sonr/x/service/keeper" - vaultkeeper "github.com/onsonr/sonr/x/vault/keeper" + modulev1 "github.com/onsonr/sonr/api/svc/module/v1" + "github.com/onsonr/sonr/x/svc/keeper" ) var _ appmodule.AppModule = AppModule{} @@ -44,12 +42,8 @@ type ModuleInputs struct { StoreService store.KVStoreService AddressCodec address.Codec - DidKeeper didkeeper.Keeper - GroupKeeper groupkeeper.Keeper - NFTKeeper nftkeeper.Keeper StakingKeeper stakingkeeper.Keeper SlashingKeeper slashingkeeper.Keeper - VaultKeeper vaultkeeper.Keeper } type ModuleOutputs struct { @@ -62,8 +56,8 @@ type ModuleOutputs struct { func ProvideModule(in ModuleInputs) ModuleOutputs { govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() - k := keeper.NewKeeper(in.Cdc, in.StoreService, log.NewLogger(os.Stderr), govAddr, in.DidKeeper, in.GroupKeeper, in.NFTKeeper, in.VaultKeeper) - m := NewAppModule(in.Cdc, k, in.DidKeeper) + k := keeper.NewKeeper(in.Cdc, in.StoreService, log.NewLogger(os.Stderr), govAddr) + m := NewAppModule(in.Cdc, k) return ModuleOutputs{Module: m, Keeper: k, Out: depinject.Out{}} } diff --git a/x/service/keeper/genesis_test.go b/x/svc/keeper/genesis_test.go similarity index 63% rename from x/service/keeper/genesis_test.go rename to x/svc/keeper/genesis_test.go index 8ab904796..9f5396c9c 100644 --- a/x/service/keeper/genesis_test.go +++ b/x/svc/keeper/genesis_test.go @@ -3,7 +3,7 @@ package keeper_test import ( "testing" - "github.com/onsonr/sonr/x/service/types" + "github.com/onsonr/sonr/x/svc/types" "github.com/stretchr/testify/require" ) @@ -12,8 +12,6 @@ func TestGenesis(t *testing.T) { genesisState := &types.GenesisState{ Params: types.DefaultParams(), - - // this line is used by starport scaffolding # genesis/test/state } f.k.InitGenesis(f.ctx, genesisState) @@ -21,5 +19,4 @@ func TestGenesis(t *testing.T) { got := f.k.ExportGenesis(f.ctx) require.NotNil(t, got) - // this line is used by starport scaffolding # genesis/test/assert } diff --git a/x/svc/keeper/keeper.go b/x/svc/keeper/keeper.go new file mode 100644 index 000000000..e0a9d0a57 --- /dev/null +++ b/x/svc/keeper/keeper.go @@ -0,0 +1,102 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/codec" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "cosmossdk.io/collections" + storetypes "cosmossdk.io/core/store" + "cosmossdk.io/log" + "cosmossdk.io/orm/model/ormdb" + + apiv1 "github.com/onsonr/sonr/api/svc/v1" + "github.com/onsonr/sonr/x/svc/types" +) + +type Keeper struct { + cdc codec.BinaryCodec + + logger log.Logger + + // state management + Schema collections.Schema + Params collections.Item[types.Params] + OrmDB apiv1.StateStore + + authority string +} + +// NewKeeper creates a new Keeper instance +func NewKeeper( + cdc codec.BinaryCodec, + storeService storetypes.KVStoreService, + logger log.Logger, + authority string, +) Keeper { + logger = logger.With(log.ModuleKey, "x/"+types.ModuleName) + + sb := collections.NewSchemaBuilder(storeService) + + if authority == "" { + authority = authtypes.NewModuleAddress(govtypes.ModuleName).String() + } + + db, err := ormdb.NewModuleDB(&types.ORMModuleSchema, ormdb.ModuleDBOptions{KVStoreService: storeService}) + if err != nil { + panic(err) + } + + store, err := apiv1.NewStateStore(db) + if err != nil { + panic(err) + } + + k := Keeper{ + cdc: cdc, + logger: logger, + + Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), + OrmDB: store, + + authority: authority, + } + + schema, err := sb.Build() + if err != nil { + panic(err) + } + + k.Schema = schema + + return k +} + +func (k Keeper) Logger() log.Logger { + return k.logger +} + +// InitGenesis initializes the module's state from a genesis state. +func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { + + if err := data.Params.Validate(); err != nil { + return err + } + + return k.Params.Set(ctx, data.Params) +} + +// ExportGenesis exports the module's state to a genesis state. +func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { + params, err := k.Params.Get(ctx) + if err != nil { + panic(err) + } + + return &types.GenesisState{ + Params: params, + } +} diff --git a/x/service/keeper/keeper_test.go b/x/svc/keeper/keeper_test.go similarity index 64% rename from x/service/keeper/keeper_test.go rename to x/svc/keeper/keeper_test.go index a3212777f..1f1563755 100644 --- a/x/service/keeper/keeper_test.go +++ b/x/svc/keeper/keeper_test.go @@ -3,12 +3,14 @@ package keeper_test import ( "testing" - "cosmossdk.io/core/store" + "github.com/stretchr/testify/suite" + "cosmossdk.io/log" storetypes "cosmossdk.io/store/types" - nftkeeper "cosmossdk.io/x/nft/keeper" + + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/runtime" - "github.com/cosmos/cosmos-sdk/testutil" + "github.com/cosmos/cosmos-sdk/testutil/integration" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" @@ -16,20 +18,16 @@ import ( authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - module "github.com/onsonr/sonr/x/service" - "github.com/onsonr/sonr/x/service/keeper" - "github.com/onsonr/sonr/x/service/types" - vaultkeeper "github.com/onsonr/sonr/x/vault/keeper" + module "github.com/onsonr/sonr/x/svc" + "github.com/onsonr/sonr/x/svc/keeper" + "github.com/onsonr/sonr/x/svc/types" ) var maccPerms = map[string][]string{ @@ -51,12 +49,8 @@ type testFixture struct { accountkeeper authkeeper.AccountKeeper bankkeeper bankkeeper.BaseKeeper - didkeeper didkeeper.Keeper - groupkeeper groupkeeper.Keeper stakingKeeper *stakingkeeper.Keeper mintkeeper mintkeeper.Keeper - nftkeeper nftkeeper.Keeper - vaultkeeper vaultkeeper.Keeper addrs []sdk.AccAddress govModAddr string @@ -65,7 +59,6 @@ type testFixture struct { func SetupTest(t *testing.T) *testFixture { t.Helper() f := new(testFixture) - require := require.New(t) // Base setup logger := log.NewTestLogger(t) @@ -74,20 +67,17 @@ func SetupTest(t *testing.T) *testFixture { f.govModAddr = authtypes.NewModuleAddress(govtypes.ModuleName).String() f.addrs = simtestutil.CreateIncrementalAccounts(3) - key := storetypes.NewKVStoreKey(types.ModuleName) - storeService := runtime.NewKVStoreService(key) - testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test")) - - f.ctx = testCtx.Ctx + keys := storetypes.NewKVStoreKeys(authtypes.ModuleName, banktypes.ModuleName, stakingtypes.ModuleName, minttypes.ModuleName, types.ModuleName) + f.ctx = sdk.NewContext(integration.CreateMultiStore(keys, logger), cmtproto.Header{}, false, logger) // Register SDK modules. - registerBaseSDKModules(f, encCfg, storeService, logger, require) + registerBaseSDKModules(logger, f, encCfg, keys) // Setup Keeper. - f.k = keeper.NewKeeper(encCfg.Codec, storeService, logger, f.govModAddr, f.didkeeper, f.groupkeeper, f.nftkeeper, f.vaultkeeper) + f.k = keeper.NewKeeper(encCfg.Codec, runtime.NewKVStoreService(keys[types.ModuleName]), logger, f.govModAddr) f.msgServer = keeper.NewMsgServerImpl(f.k) f.queryServer = keeper.NewQuerier(f.k) - f.appModule = module.NewAppModule(encCfg.Codec, f.k, f.didkeeper) + f.appModule = module.NewAppModule(encCfg.Codec, f.k) return f } @@ -95,22 +85,23 @@ func SetupTest(t *testing.T) *testFixture { func registerModuleInterfaces(encCfg moduletestutil.TestEncodingConfig) { authtypes.RegisterInterfaces(encCfg.InterfaceRegistry) stakingtypes.RegisterInterfaces(encCfg.InterfaceRegistry) + banktypes.RegisterInterfaces(encCfg.InterfaceRegistry) + minttypes.RegisterInterfaces(encCfg.InterfaceRegistry) types.RegisterInterfaces(encCfg.InterfaceRegistry) } func registerBaseSDKModules( + logger log.Logger, f *testFixture, encCfg moduletestutil.TestEncodingConfig, - storeService store.KVStoreService, - logger log.Logger, - require *require.Assertions, + keys map[string]*storetypes.KVStoreKey, ) { registerModuleInterfaces(encCfg) // Auth Keeper. f.accountkeeper = authkeeper.NewAccountKeeper( - encCfg.Codec, storeService, + encCfg.Codec, runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, authcodec.NewBech32Codec(sdk.Bech32MainPrefix), sdk.Bech32MainPrefix, @@ -119,7 +110,7 @@ func registerBaseSDKModules( // Bank Keeper. f.bankkeeper = bankkeeper.NewBaseKeeper( - encCfg.Codec, storeService, + encCfg.Codec, runtime.NewKVStoreService(keys[banktypes.StoreKey]), f.accountkeeper, nil, f.govModAddr, logger, @@ -127,21 +118,16 @@ func registerBaseSDKModules( // Staking Keeper. f.stakingKeeper = stakingkeeper.NewKeeper( - encCfg.Codec, storeService, + encCfg.Codec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), f.accountkeeper, f.bankkeeper, f.govModAddr, authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), ) - require.NoError(f.stakingKeeper.SetParams(f.ctx, stakingtypes.DefaultParams())) - f.accountkeeper.SetModuleAccount(f.ctx, f.stakingKeeper.GetNotBondedPool(f.ctx)) - f.accountkeeper.SetModuleAccount(f.ctx, f.stakingKeeper.GetBondedPool(f.ctx)) // Mint Keeper. f.mintkeeper = mintkeeper.NewKeeper( - encCfg.Codec, storeService, + encCfg.Codec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), f.stakingKeeper, f.accountkeeper, f.bankkeeper, authtypes.FeeCollectorName, f.govModAddr, ) - f.accountkeeper.SetModuleAccount(f.ctx, f.accountkeeper.GetModuleAccount(f.ctx, minttypes.ModuleName)) - f.mintkeeper.InitGenesis(f.ctx, f.accountkeeper, minttypes.DefaultGenesisState()) } diff --git a/x/service/keeper/rpc.go b/x/svc/keeper/msg_server.go similarity index 96% rename from x/service/keeper/rpc.go rename to x/svc/keeper/msg_server.go index e6e14791c..a4e939a59 100644 --- a/x/service/keeper/rpc.go +++ b/x/svc/keeper/msg_server.go @@ -6,7 +6,7 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "cosmossdk.io/errors" - "github.com/onsonr/sonr/x/service/types" + "github.com/onsonr/sonr/x/svc/types" ) type msgServer struct { diff --git a/x/service/keeper/rpc_test.go b/x/svc/keeper/msg_server_test.go similarity index 95% rename from x/service/keeper/rpc_test.go rename to x/svc/keeper/msg_server_test.go index 20637a46e..85dddea7b 100644 --- a/x/service/keeper/rpc_test.go +++ b/x/svc/keeper/msg_server_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/onsonr/sonr/x/service/types" + "github.com/onsonr/sonr/x/svc/types" ) func TestParams(t *testing.T) { diff --git a/x/service/keeper/querier.go b/x/svc/keeper/query_server.go similarity index 92% rename from x/service/keeper/querier.go rename to x/svc/keeper/query_server.go index df7393d53..c4ec7861d 100644 --- a/x/service/keeper/querier.go +++ b/x/svc/keeper/query_server.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/onsonr/sonr/x/service/types" + "github.com/onsonr/sonr/x/svc/types" ) var _ types.QueryServer = Querier{} diff --git a/x/vault/module.go b/x/svc/module.go similarity index 89% rename from x/vault/module.go rename to x/svc/module.go index 9034bdcf0..bd9a85ef0 100644 --- a/x/vault/module.go +++ b/x/svc/module.go @@ -4,27 +4,27 @@ import ( "context" "encoding/json" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + + abci "github.com/cometbft/cometbft/abci/types" + "cosmossdk.io/client/v2/autocli" errorsmod "cosmossdk.io/errors" - abci "github.com/cometbft/cometbft/abci/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - "github.com/onsonr/sonr/x/vault/keeper" - "github.com/onsonr/sonr/x/vault/types" + "github.com/onsonr/sonr/x/svc/keeper" + "github.com/onsonr/sonr/x/svc/types" ) const ( - // ConsensusVersion defines the current x/vault module consensus version. + // ConsensusVersion defines the current x/svc module consensus version. ConsensusVersion = 1 - -// this line is used by starport scaffolding # simapp/module/const ) var ( @@ -44,19 +44,16 @@ type AppModule struct { AppModuleBasic keeper keeper.Keeper - didk didkeeper.Keeper } // NewAppModule constructor func NewAppModule( cdc codec.Codec, keeper keeper.Keeper, - didkeeper didkeeper.Keeper, ) *AppModule { return &AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, - didk: didkeeper, } } @@ -93,6 +90,17 @@ func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux } } +// Disable in favor of autocli.go. If you wish to use these, it will override AutoCLI methods. +/* +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.NewTxCmd() +} + +func (a AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} +*/ + func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { types.RegisterLegacyAminoCodec(cdc) } diff --git a/x/service/types/codec.go b/x/svc/types/codec.go similarity index 89% rename from x/service/types/codec.go rename to x/svc/types/codec.go index 550adfc39..6d57a9e34 100644 --- a/x/service/types/codec.go +++ b/x/svc/types/codec.go @@ -6,7 +6,6 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" - // this line is used by starport scaffolding # 1 ) var ( @@ -26,7 +25,6 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { } func RegisterInterfaces(registry types.InterfaceRegistry) { - // this line is used by starport scaffolding # 3 registry.RegisterImplementations( (*sdk.Msg)(nil), diff --git a/x/service/types/genesis.go b/x/svc/types/genesis.go similarity index 65% rename from x/service/types/genesis.go rename to x/svc/types/genesis.go index 4f9eac491..97cad7616 100644 --- a/x/service/types/genesis.go +++ b/x/svc/types/genesis.go @@ -1,14 +1,12 @@ package types -// this line is used by starport scaffolding # genesis/types/import - // DefaultIndex is the default global index const DefaultIndex uint64 = 1 // DefaultGenesis returns the default genesis state func DefaultGenesis() *GenesisState { return &GenesisState{ - // this line is used by starport scaffolding # genesis/types/default + Params: DefaultParams(), } } @@ -16,6 +14,6 @@ func DefaultGenesis() *GenesisState { // Validate performs basic genesis state validation returning an error upon any // failure. func (gs GenesisState) Validate() error { - // this line is used by starport scaffolding # genesis/types/validate + return gs.Params.Validate() } diff --git a/x/service/types/genesis.pb.go b/x/svc/types/genesis.pb.go similarity index 90% rename from x/service/types/genesis.pb.go rename to x/svc/types/genesis.pb.go index 03b072f8e..b15a23d81 100644 --- a/x/service/types/genesis.pb.go +++ b/x/svc/types/genesis.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: service/v1/genesis.proto +// source: svc/v1/genesis.proto package types @@ -34,7 +34,7 @@ func (m *GenesisState) Reset() { *m = GenesisState{} } func (m *GenesisState) String() string { return proto.CompactTextString(m) } func (*GenesisState) ProtoMessage() {} func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_0ce55e499988823a, []int{0} + return fileDescriptor_86658d95daaa12a9, []int{0} } func (m *GenesisState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -79,7 +79,7 @@ type Params struct { func (m *Params) Reset() { *m = Params{} } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_0ce55e499988823a, []int{1} + return fileDescriptor_86658d95daaa12a9, []int{1} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -130,7 +130,7 @@ func (m *ServiceCategories) Reset() { *m = ServiceCategories{} } func (m *ServiceCategories) String() string { return proto.CompactTextString(m) } func (*ServiceCategories) ProtoMessage() {} func (*ServiceCategories) Descriptor() ([]byte, []int) { - return fileDescriptor_0ce55e499988823a, []int{2} + return fileDescriptor_86658d95daaa12a9, []int{2} } func (m *ServiceCategories) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -174,7 +174,7 @@ func (m *ServiceTypes) Reset() { *m = ServiceTypes{} } func (m *ServiceTypes) String() string { return proto.CompactTextString(m) } func (*ServiceTypes) ProtoMessage() {} func (*ServiceTypes) Descriptor() ([]byte, []int) { - return fileDescriptor_0ce55e499988823a, []int{3} + return fileDescriptor_86658d95daaa12a9, []int{3} } func (m *ServiceTypes) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -226,7 +226,7 @@ func (m *Service) Reset() { *m = Service{} } func (m *Service) String() string { return proto.CompactTextString(m) } func (*Service) ProtoMessage() {} func (*Service) Descriptor() ([]byte, []int) { - return fileDescriptor_0ce55e499988823a, []int{4} + return fileDescriptor_86658d95daaa12a9, []int{4} } func (m *Service) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -312,45 +312,45 @@ func (m *Service) GetExpiryHeight() int64 { } func init() { - proto.RegisterType((*GenesisState)(nil), "service.v1.GenesisState") - proto.RegisterType((*Params)(nil), "service.v1.Params") - proto.RegisterType((*ServiceCategories)(nil), "service.v1.ServiceCategories") - proto.RegisterType((*ServiceTypes)(nil), "service.v1.ServiceTypes") - proto.RegisterType((*Service)(nil), "service.v1.Service") + proto.RegisterType((*GenesisState)(nil), "svc.v1.GenesisState") + proto.RegisterType((*Params)(nil), "svc.v1.Params") + proto.RegisterType((*ServiceCategories)(nil), "svc.v1.ServiceCategories") + proto.RegisterType((*ServiceTypes)(nil), "svc.v1.ServiceTypes") + proto.RegisterType((*Service)(nil), "svc.v1.Service") } -func init() { proto.RegisterFile("service/v1/genesis.proto", fileDescriptor_0ce55e499988823a) } +func init() { proto.RegisterFile("svc/v1/genesis.proto", fileDescriptor_86658d95daaa12a9) } -var fileDescriptor_0ce55e499988823a = []byte{ - // 442 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xbf, 0x6e, 0x13, 0x41, - 0x10, 0xc6, 0x6f, 0x6d, 0xe7, 0x12, 0x4f, 0x9c, 0x48, 0x19, 0x45, 0xd1, 0xca, 0x81, 0xb3, 0x65, - 0x24, 0x64, 0x51, 0xdc, 0x11, 0xe8, 0x22, 0x90, 0xa2, 0x50, 0x40, 0x19, 0x5d, 0xa8, 0x68, 0xd0, - 0xc5, 0x5e, 0xad, 0xb7, 0xf0, 0xed, 0x69, 0x77, 0x63, 0xc5, 0xaf, 0x40, 0x45, 0x41, 0x41, 0x99, - 0x47, 0xe0, 0x31, 0x52, 0xa6, 0x44, 0x14, 0x08, 0xd9, 0x05, 0x3c, 0x06, 0xf2, 0xec, 0x9d, 0x7d, - 0xfc, 0x69, 0x56, 0xb3, 0xdf, 0xb7, 0xf3, 0xbb, 0x6f, 0x46, 0x07, 0xdc, 0x0a, 0x33, 0x53, 0x23, - 0x91, 0xcc, 0x4e, 0x12, 0x29, 0x72, 0x61, 0x95, 0x8d, 0x0b, 0xa3, 0x9d, 0x46, 0x28, 0x9d, 0x78, - 0x76, 0xd2, 0x3d, 0xc8, 0xa6, 0x2a, 0xd7, 0x09, 0x9d, 0xde, 0xee, 0x1e, 0x4a, 0x2d, 0x35, 0x95, - 0xc9, 0xaa, 0xf2, 0xea, 0xe0, 0x0c, 0x3a, 0xaf, 0x3d, 0xe5, 0xd2, 0x65, 0x4e, 0xe0, 0x53, 0x08, - 0x8b, 0xcc, 0x64, 0x53, 0xcb, 0x59, 0x9f, 0x0d, 0x77, 0x9f, 0x61, 0xbc, 0xa1, 0xc6, 0x17, 0xe4, - 0x9c, 0xb7, 0xee, 0xbe, 0xf7, 0x82, 0xb4, 0x7c, 0x37, 0xf8, 0xc4, 0x20, 0xf4, 0x06, 0xbe, 0x04, - 0x18, 0x65, 0x4e, 0x48, 0x6d, 0x94, 0xa8, 0x00, 0x0f, 0xeb, 0x80, 0x4b, 0x5f, 0xbe, 0x5a, 0x3f, - 0x4a, 0x6b, 0x0d, 0x18, 0xc3, 0x96, 0x9b, 0x17, 0xc2, 0xf2, 0x06, 0x75, 0xf2, 0xff, 0x74, 0xbe, - 0x5d, 0xf9, 0xa9, 0x7f, 0x76, 0x7a, 0xfc, 0xf9, 0xb6, 0x17, 0xfc, 0xba, 0xed, 0xb1, 0x0f, 0x3f, - 0xbf, 0x3c, 0xd9, 0xaf, 0xf6, 0x52, 0xc6, 0xba, 0x80, 0x83, 0x7f, 0xbe, 0x86, 0xd1, 0x5f, 0x01, - 0x9b, 0xc3, 0x76, 0x3d, 0xc1, 0xe9, 0x71, 0x45, 0xc3, 0x8a, 0xb6, 0x31, 0x07, 0x2f, 0xa0, 0x53, - 0x4f, 0x81, 0x87, 0x55, 0x5c, 0xcf, 0x29, 0x43, 0x1d, 0x55, 0x88, 0xbd, 0x0a, 0x41, 0xfa, 0xe0, - 0x1b, 0x83, 0xed, 0xb2, 0x1d, 0xf7, 0xa1, 0xa1, 0xc6, 0xb4, 0x9f, 0x76, 0xda, 0x50, 0x63, 0x7c, - 0x00, 0xed, 0xec, 0xda, 0x4d, 0xb4, 0x51, 0x6e, 0x4e, 0xc3, 0xb7, 0xd3, 0x8d, 0x80, 0x47, 0x10, - 0x6a, 0xa3, 0xa4, 0xca, 0x79, 0x93, 0xac, 0xf2, 0x86, 0x08, 0xad, 0x3c, 0x9b, 0x0a, 0xde, 0x22, - 0x95, 0x6a, 0xec, 0xc3, 0xee, 0x58, 0xd8, 0x91, 0x51, 0x85, 0x53, 0x3a, 0xe7, 0x5b, 0x64, 0xd5, - 0x25, 0xec, 0xc2, 0x4e, 0x39, 0xd3, 0x9c, 0x87, 0x64, 0xaf, 0xef, 0x2b, 0xa2, 0xcb, 0xa4, 0xe5, - 0xdb, 0x34, 0x10, 0xd5, 0xf8, 0x08, 0xf6, 0xc4, 0x4d, 0xa1, 0xcc, 0xfc, 0xfd, 0x44, 0x28, 0x39, - 0x71, 0x7c, 0xa7, 0xcf, 0x86, 0xcd, 0xb4, 0xe3, 0xc5, 0x37, 0xa4, 0x9d, 0x9f, 0xdd, 0x2d, 0x22, - 0x76, 0xbf, 0x88, 0xd8, 0x8f, 0x45, 0xc4, 0x3e, 0x2e, 0xa3, 0xe0, 0x7e, 0x19, 0x05, 0x5f, 0x97, - 0x51, 0xf0, 0xee, 0xb1, 0x54, 0x6e, 0x72, 0x7d, 0x15, 0x8f, 0xf4, 0x34, 0xd1, 0xb9, 0xd5, 0xb9, - 0x49, 0xe8, 0xb8, 0x49, 0xfe, 0x58, 0xcf, 0x55, 0x48, 0xbf, 0xe3, 0xf3, 0xdf, 0x01, 0x00, 0x00, - 0xff, 0xff, 0xe6, 0x6d, 0xb2, 0xb0, 0xdf, 0x02, 0x00, 0x00, +var fileDescriptor_86658d95daaa12a9 = []byte{ + // 441 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x52, 0xb1, 0x6e, 0xdb, 0x30, + 0x10, 0x15, 0x6d, 0x47, 0x89, 0x2f, 0x89, 0x81, 0x10, 0x46, 0xa0, 0x3a, 0x85, 0x6c, 0xb8, 0x8b, + 0x11, 0x14, 0x22, 0xd2, 0x4e, 0x0d, 0x32, 0xa5, 0x43, 0x3b, 0x06, 0x4a, 0xa7, 0x2e, 0x05, 0x23, + 0x13, 0x34, 0x07, 0x8b, 0x02, 0xc9, 0x08, 0xf1, 0x2f, 0x14, 0x1d, 0x3a, 0x76, 0xcc, 0x27, 0xf4, + 0x33, 0x32, 0x66, 0x2c, 0x3a, 0x14, 0x85, 0x3d, 0xb4, 0x9f, 0x51, 0xe8, 0x28, 0x25, 0x42, 0xba, + 0x10, 0xc7, 0xf7, 0xee, 0x3d, 0xbe, 0x3b, 0x10, 0x86, 0xb6, 0xcc, 0x58, 0x79, 0xc2, 0xa4, 0xc8, + 0x85, 0x55, 0x36, 0x29, 0x8c, 0x76, 0x9a, 0x86, 0xb6, 0xcc, 0x92, 0xf2, 0x64, 0x34, 0x94, 0x5a, + 0x6a, 0x84, 0x58, 0x55, 0x79, 0x76, 0x74, 0xc0, 0x97, 0x2a, 0xd7, 0x0c, 0x4f, 0x0f, 0x4d, 0xcf, + 0x60, 0xef, 0x9d, 0x77, 0xb8, 0x74, 0xdc, 0x09, 0xfa, 0x12, 0xc2, 0x82, 0x1b, 0xbe, 0xb4, 0x11, + 0x99, 0x90, 0xd9, 0xee, 0xab, 0x41, 0xe2, 0x1d, 0x93, 0x0b, 0x44, 0xcf, 0x7b, 0x77, 0xbf, 0xc6, + 0x41, 0x5a, 0xf7, 0x4c, 0xbf, 0x10, 0x08, 0x3d, 0x41, 0xdf, 0x00, 0x64, 0xdc, 0x09, 0xa9, 0x8d, + 0x12, 0x8d, 0xf8, 0x59, 0x23, 0xbe, 0x14, 0xa6, 0x54, 0x99, 0x78, 0xfb, 0xd0, 0x90, 0xb6, 0x9a, + 0xe9, 0x31, 0x6c, 0xb9, 0x55, 0x21, 0x6c, 0xd4, 0x41, 0xd5, 0xf0, 0x89, 0xea, 0x43, 0xc5, 0xa5, + 0xbe, 0xe5, 0xf4, 0xe8, 0xdb, 0xed, 0x38, 0xf8, 0x7b, 0x3b, 0x26, 0x9f, 0xff, 0x7c, 0x3f, 0x1e, + 0x58, 0xdf, 0xc1, 0xea, 0x38, 0x17, 0x70, 0xf0, 0xdf, 0x4b, 0x34, 0x7e, 0x12, 0xac, 0x3b, 0xeb, + 0xb7, 0x5f, 0x3f, 0x3d, 0x6a, 0xdc, 0x68, 0xe3, 0xf6, 0x48, 0x56, 0xeb, 0x69, 0xa7, 0xa0, 0xc3, + 0x26, 0xaa, 0xf7, 0xa9, 0x43, 0x1d, 0x36, 0x16, 0xfb, 0x8d, 0x05, 0xe2, 0xd3, 0x9f, 0x04, 0xb6, + 0x6b, 0x39, 0x1d, 0x40, 0x47, 0xcd, 0x71, 0x2f, 0xfd, 0xb4, 0xa3, 0xe6, 0xf4, 0x39, 0xf4, 0xf9, + 0xb5, 0x5b, 0x68, 0xa3, 0xdc, 0x0a, 0x07, 0xef, 0xa7, 0x8f, 0x00, 0x3d, 0x84, 0x50, 0x1b, 0x25, + 0x55, 0x1e, 0x75, 0x91, 0xaa, 0x6f, 0x94, 0x42, 0x2f, 0xe7, 0x4b, 0x11, 0xf5, 0x10, 0xc5, 0x9a, + 0x4e, 0x60, 0x77, 0x2e, 0x6c, 0x66, 0x54, 0xe1, 0x94, 0xce, 0xa3, 0x2d, 0xa4, 0xda, 0x10, 0x1d, + 0xc1, 0x4e, 0x3d, 0xd3, 0x2a, 0x0a, 0x91, 0x7e, 0xb8, 0x57, 0x8e, 0x8e, 0x4b, 0x1b, 0x6d, 0xe3, + 0x40, 0x58, 0xd3, 0x17, 0xb0, 0x2f, 0x6e, 0x0a, 0x65, 0x56, 0x9f, 0x16, 0x42, 0xc9, 0x85, 0x8b, + 0x76, 0x26, 0x64, 0xd6, 0x4d, 0xf7, 0x3c, 0xf8, 0x1e, 0xb1, 0xf3, 0xb3, 0xbb, 0x75, 0x4c, 0xee, + 0xd7, 0x31, 0xf9, 0xbd, 0x8e, 0xc9, 0xd7, 0x4d, 0x1c, 0xdc, 0x6f, 0xe2, 0xe0, 0xc7, 0x26, 0x0e, + 0x3e, 0x4e, 0xa5, 0x72, 0x8b, 0xeb, 0xab, 0x24, 0xd3, 0x4b, 0xa6, 0x73, 0xab, 0x73, 0xc3, 0xf0, + 0xb8, 0x61, 0xd5, 0x9f, 0xc5, 0xd5, 0x5c, 0x85, 0xf8, 0xfd, 0x5e, 0xff, 0x0b, 0x00, 0x00, 0xff, + 0xff, 0x50, 0x14, 0xc4, 0xe2, 0xc7, 0x02, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { diff --git a/x/service/types/genesis_test.go b/x/svc/types/genesis_test.go similarity index 69% rename from x/service/types/genesis_test.go rename to x/svc/types/genesis_test.go index dacadd679..0b72f2e92 100644 --- a/x/service/types/genesis_test.go +++ b/x/svc/types/genesis_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/onsonr/sonr/x/service/types" + "github.com/onsonr/sonr/x/svc/types" "github.com/stretchr/testify/require" ) @@ -21,13 +21,9 @@ func TestGenesisState_Validate(t *testing.T) { }, { desc: "valid genesis state", - genState: &types.GenesisState{ - - // this line is used by starport scaffolding # types/genesis/validField - }, - valid: true, + genState: &types.GenesisState{}, + valid: true, }, - // this line is used by starport scaffolding # types/genesis/testcase } for _, tc := range tests { t.Run(tc.desc, func(t *testing.T) { diff --git a/x/service/types/keys.go b/x/svc/types/keys.go similarity index 84% rename from x/service/types/keys.go rename to x/svc/types/keys.go index 39fa5dfcf..a4e12f0d6 100644 --- a/x/service/types/keys.go +++ b/x/svc/types/keys.go @@ -12,7 +12,7 @@ var ( ) const ( - ModuleName = "service" + ModuleName = "svc" StoreKey = ModuleName @@ -21,7 +21,7 @@ const ( var ORMModuleSchema = ormv1alpha1.ModuleSchemaDescriptor{ SchemaFile: []*ormv1alpha1.ModuleSchemaDescriptor_FileEntry{ - {Id: 1, ProtoFileName: "service/v1/state.proto"}, + {Id: 1, ProtoFileName: "svc/v1/state.proto"}, }, Prefix: []byte{0}, } diff --git a/x/service/types/msgs.go b/x/svc/types/msgs.go similarity index 100% rename from x/service/types/msgs.go rename to x/svc/types/msgs.go diff --git a/x/service/types/params.go b/x/svc/types/params.go similarity index 100% rename from x/service/types/params.go rename to x/svc/types/params.go diff --git a/x/service/types/query.pb.go b/x/svc/types/query.pb.go similarity index 85% rename from x/service/types/query.pb.go rename to x/svc/types/query.pb.go index 6d84ca9a4..713aad622 100644 --- a/x/service/types/query.pb.go +++ b/x/svc/types/query.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: service/v1/query.proto +// source: svc/v1/query.proto package types @@ -36,7 +36,7 @@ func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryParamsRequest) ProtoMessage() {} func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_d0ed234bfe4ffc68, []int{0} + return fileDescriptor_81a1010cdbf4bc9c, []int{0} } func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,7 +75,7 @@ func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryParamsResponse) ProtoMessage() {} func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_d0ed234bfe4ffc68, []int{1} + return fileDescriptor_81a1010cdbf4bc9c, []int{1} } func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -112,30 +112,30 @@ func (m *QueryParamsResponse) GetParams() *Params { } func init() { - proto.RegisterType((*QueryParamsRequest)(nil), "service.v1.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "service.v1.QueryParamsResponse") + proto.RegisterType((*QueryParamsRequest)(nil), "svc.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "svc.v1.QueryParamsResponse") } -func init() { proto.RegisterFile("service/v1/query.proto", fileDescriptor_d0ed234bfe4ffc68) } +func init() { proto.RegisterFile("svc/v1/query.proto", fileDescriptor_81a1010cdbf4bc9c) } -var fileDescriptor_d0ed234bfe4ffc68 = []byte{ - // 251 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2b, 0x4e, 0x2d, 0x2a, - 0xcb, 0x4c, 0x4e, 0xd5, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, - 0x2f, 0xc9, 0x17, 0xe2, 0x82, 0x8a, 0xeb, 0x95, 0x19, 0x4a, 0xc9, 0xa4, 0xe7, 0xe7, 0xa7, 0xe7, - 0xa4, 0xea, 0x27, 0x16, 0x64, 0xea, 0x27, 0xe6, 0xe5, 0xe5, 0x97, 0x24, 0x96, 0x64, 0xe6, 0xe7, - 0x15, 0x43, 0x54, 0x4a, 0x49, 0x20, 0x99, 0x90, 0x9e, 0x9a, 0x97, 0x5a, 0x9c, 0x09, 0x95, 0x51, - 0x12, 0xe1, 0x12, 0x0a, 0x04, 0x19, 0x19, 0x90, 0x58, 0x94, 0x98, 0x5b, 0x1c, 0x94, 0x5a, 0x58, - 0x9a, 0x5a, 0x5c, 0xa2, 0xe4, 0xc8, 0x25, 0x8c, 0x22, 0x5a, 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x2a, - 0xa4, 0xc5, 0xc5, 0x56, 0x00, 0x16, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, 0x12, 0xd2, 0x43, - 0xb8, 0x40, 0x0f, 0xaa, 0x16, 0xaa, 0xc2, 0x28, 0x8f, 0x8b, 0x15, 0x6c, 0x84, 0x50, 0x2a, 0x17, - 0x1b, 0x44, 0x4a, 0x48, 0x0e, 0x59, 0x39, 0xa6, 0xad, 0x52, 0xf2, 0x38, 0xe5, 0x21, 0xf6, 0x2b, - 0x49, 0x35, 0x5d, 0x7e, 0x32, 0x99, 0x49, 0x44, 0x48, 0x48, 0x1f, 0xc9, 0x3f, 0x10, 0xfb, 0x9c, - 0x1c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, - 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x2d, 0x3d, 0xb3, 0x24, - 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x3f, 0x3f, 0xaf, 0x38, 0x3f, 0xaf, 0x48, 0x1f, 0x4c, - 0x54, 0xc0, 0x4d, 0x29, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x87, 0x88, 0x31, 0x20, 0x00, - 0x00, 0xff, 0xff, 0x3e, 0xda, 0x0a, 0xaf, 0x6f, 0x01, 0x00, 0x00, +var fileDescriptor_81a1010cdbf4bc9c = []byte{ + // 248 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x2e, 0x4b, 0xd6, + 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, + 0x2b, 0x2e, 0x4b, 0xd6, 0x2b, 0x33, 0x94, 0x92, 0x49, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x4f, + 0x2c, 0xc8, 0xd4, 0x4f, 0xcc, 0xcb, 0xcb, 0x2f, 0x49, 0x2c, 0xc9, 0xcc, 0xcf, 0x2b, 0x86, 0xa8, + 0x92, 0x12, 0x81, 0xea, 0x4c, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x84, 0x8a, 0x2a, 0x89, 0x70, 0x09, + 0x05, 0x82, 0x8c, 0x0a, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0x0e, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, + 0x51, 0xb2, 0xe5, 0x12, 0x46, 0x11, 0x2d, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0x15, 0x52, 0xe3, 0x62, + 0x2b, 0x00, 0x8b, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x1b, 0xf1, 0xe9, 0x41, 0x6c, 0xd6, 0x83, + 0xaa, 0x83, 0xca, 0x1a, 0x25, 0x71, 0xb1, 0x82, 0xb5, 0x0b, 0x45, 0x72, 0xb1, 0x41, 0xa4, 0x84, + 0xa4, 0x60, 0x4a, 0x31, 0x6d, 0x93, 0x92, 0xc6, 0x2a, 0x07, 0xb1, 0x53, 0x49, 0xac, 0xe9, 0xf2, + 0x93, 0xc9, 0x4c, 0x02, 0x42, 0x7c, 0xfa, 0x50, 0xf7, 0x43, 0xec, 0x70, 0xb2, 0x39, 0xf1, 0x48, + 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, + 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xa5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, + 0xe4, 0xfc, 0x5c, 0xfd, 0xfc, 0xbc, 0xe2, 0xfc, 0xbc, 0x22, 0x7d, 0x30, 0x51, 0x01, 0x36, 0xa1, + 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x7b, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x32, 0x0f, 0x6c, 0xb9, 0x4f, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -164,7 +164,7 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/service.v1.Query/Params", in, out, opts...) + err := c.cc.Invoke(ctx, "/svc.v1.Query/Params", in, out, opts...) if err != nil { return nil, err } @@ -199,7 +199,7 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/service.v1.Query/Params", + FullMethod: "/svc.v1.Query/Params", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) @@ -209,7 +209,7 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf var Query_serviceDesc = _Query_serviceDesc var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "service.v1.Query", + ServiceName: "svc.v1.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ { @@ -218,7 +218,7 @@ var _Query_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "service/v1/query.proto", + Metadata: "svc/v1/query.proto", } func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { diff --git a/x/service/types/query.pb.gw.go b/x/svc/types/query.pb.gw.go similarity index 97% rename from x/service/types/query.pb.gw.go rename to x/svc/types/query.pb.gw.go index e9ca37af4..2a298a885 100644 --- a/x/service/types/query.pb.gw.go +++ b/x/svc/types/query.pb.gw.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: service/v1/query.proto +// source: svc/v1/query.proto /* Package types is a reverse proxy. @@ -145,7 +145,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"service", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"svc", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/x/service/types/state.pb.go b/x/svc/types/state.pb.go similarity index 88% rename from x/service/types/state.pb.go rename to x/svc/types/state.pb.go index 339055f3a..a7e9ac963 100644 --- a/x/service/types/state.pb.go +++ b/x/svc/types/state.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: service/v1/state.proto +// source: svc/v1/state.proto package types @@ -37,7 +37,7 @@ func (m *Metadata) Reset() { *m = Metadata{} } func (m *Metadata) String() string { return proto.CompactTextString(m) } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_ab6e3654a2974847, []int{0} + return fileDescriptor_2859adb306f7c51f, []int{0} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -131,7 +131,7 @@ func (m *Profile) Reset() { *m = Profile{} } func (m *Profile) String() string { return proto.CompactTextString(m) } func (*Profile) ProtoMessage() {} func (*Profile) Descriptor() ([]byte, []int) { - return fileDescriptor_ab6e3654a2974847, []int{1} + return fileDescriptor_2859adb306f7c51f, []int{1} } func (m *Profile) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -189,36 +189,36 @@ func (m *Profile) GetController() string { } func init() { - proto.RegisterType((*Metadata)(nil), "service.v1.Metadata") - proto.RegisterType((*Profile)(nil), "service.v1.Profile") + proto.RegisterType((*Metadata)(nil), "svc.v1.Metadata") + proto.RegisterType((*Profile)(nil), "svc.v1.Profile") } -func init() { proto.RegisterFile("service/v1/state.proto", fileDescriptor_ab6e3654a2974847) } +func init() { proto.RegisterFile("svc/v1/state.proto", fileDescriptor_2859adb306f7c51f) } -var fileDescriptor_ab6e3654a2974847 = []byte{ - // 348 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xc1, 0x6a, 0xe3, 0x30, - 0x10, 0x86, 0x23, 0xdb, 0xeb, 0x24, 0xb3, 0x4b, 0x08, 0x62, 0xc9, 0x8a, 0x1c, 0x84, 0x09, 0xcb, - 0x92, 0xc3, 0x12, 0x13, 0xf6, 0x96, 0xd3, 0xd2, 0x7b, 0xa1, 0xe4, 0xd8, 0x9b, 0x23, 0xab, 0xae, - 0x4a, 0xec, 0x09, 0x92, 0x12, 0x9a, 0x97, 0x28, 0xed, 0x0b, 0xf4, 0x79, 0x7a, 0xe8, 0x21, 0xd0, - 0x4b, 0x8f, 0x25, 0x79, 0x83, 0x3e, 0x41, 0x91, 0xe2, 0x14, 0xf7, 0x22, 0x66, 0xfe, 0x19, 0x7e, - 0xfd, 0x1f, 0x03, 0x03, 0x23, 0xf5, 0x46, 0x09, 0x99, 0x6e, 0xa6, 0xa9, 0xb1, 0x99, 0x95, 0x93, - 0x95, 0x46, 0x8b, 0x14, 0x6a, 0x7d, 0xb2, 0x99, 0x0e, 0x7f, 0x09, 0x34, 0x25, 0x9a, 0x14, 0x75, - 0xe9, 0xd6, 0x50, 0x97, 0xc7, 0xa5, 0xd1, 0x33, 0x81, 0xce, 0xb9, 0xb4, 0x59, 0x9e, 0xd9, 0x8c, - 0xf6, 0x20, 0x50, 0x39, 0x23, 0x09, 0x19, 0x47, 0xf3, 0x40, 0xe5, 0x74, 0x00, 0x31, 0x6a, 0x55, - 0xa8, 0x8a, 0x05, 0x09, 0x19, 0x77, 0xe7, 0x75, 0x47, 0x29, 0x44, 0x55, 0x56, 0x4a, 0x16, 0x7a, - 0xd5, 0xd7, 0x34, 0x81, 0xef, 0xb9, 0x34, 0x42, 0xab, 0x95, 0x55, 0x58, 0xb1, 0xc8, 0x8f, 0x9a, - 0x12, 0x1d, 0x42, 0x47, 0x64, 0x56, 0x16, 0xa8, 0xb7, 0xec, 0x9b, 0x1f, 0x7f, 0xf6, 0xce, 0x51, - 0x09, 0xac, 0x58, 0x7c, 0x74, 0x74, 0xb5, 0xd3, 0x6c, 0x56, 0x18, 0xd6, 0x4e, 0x42, 0xa7, 0xb9, - 0x7a, 0xc6, 0xdf, 0x1f, 0x5f, 0xee, 0x42, 0x06, 0xb1, 0x4b, 0xda, 0x27, 0xf4, 0xc7, 0x29, 0x61, - 0x9f, 0x30, 0xc2, 0xc8, 0xe8, 0x81, 0x40, 0xfb, 0x42, 0xe3, 0x95, 0x5a, 0xca, 0x06, 0x4d, 0xd7, - 0xd3, 0x30, 0x68, 0x9b, 0xf5, 0xe2, 0x46, 0x0a, 0x5b, 0xe3, 0x9c, 0xda, 0x06, 0x67, 0xf8, 0x85, - 0x93, 0x03, 0x08, 0xac, 0xac, 0xc6, 0xe5, 0x52, 0xea, 0x1a, 0xa9, 0xa1, 0xcc, 0x7e, 0xfb, 0x34, - 0x1c, 0x22, 0xf7, 0x13, 0xfd, 0x09, 0xbd, 0xda, 0xf0, 0x6f, 0x23, 0x53, 0x70, 0xf6, 0xff, 0x69, - 0xcf, 0xc9, 0x6e, 0xcf, 0xc9, 0xdb, 0x9e, 0x93, 0xfb, 0x03, 0x6f, 0xed, 0x0e, 0xbc, 0xf5, 0x7a, - 0xe0, 0xad, 0xcb, 0x3f, 0x85, 0xb2, 0xd7, 0xeb, 0xc5, 0x44, 0x60, 0x99, 0x62, 0x65, 0xb0, 0xd2, - 0xa9, 0x7f, 0x6e, 0xd3, 0xd3, 0x49, 0xed, 0x76, 0x25, 0xcd, 0x22, 0xf6, 0xb7, 0xfa, 0xf7, 0x11, - 0x00, 0x00, 0xff, 0xff, 0x81, 0xa0, 0xdf, 0xce, 0xea, 0x01, 0x00, 0x00, +var fileDescriptor_2859adb306f7c51f = []byte{ + // 343 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xc1, 0x4a, 0x3b, 0x31, + 0x10, 0xc6, 0x9b, 0xdd, 0xfd, 0x6f, 0xdb, 0xfc, 0xa5, 0x94, 0x20, 0x1a, 0x7a, 0x08, 0x4b, 0xf1, + 0xd0, 0x83, 0x74, 0x29, 0xde, 0x8a, 0x27, 0xef, 0x82, 0xf4, 0xe8, 0x6d, 0x9b, 0x8d, 0x6b, 0xa4, + 0x9b, 0x29, 0x49, 0xba, 0xd8, 0x97, 0x10, 0x7d, 0x01, 0x9f, 0xc7, 0x83, 0x87, 0x82, 0x17, 0x8f, + 0xd2, 0xbe, 0x81, 0x4f, 0x20, 0x49, 0xb7, 0xb2, 0x5e, 0xc2, 0xcc, 0x37, 0xc3, 0x97, 0xef, 0xc7, + 0x60, 0x62, 0x2a, 0x9e, 0x56, 0x93, 0xd4, 0xd8, 0xcc, 0x8a, 0xf1, 0x52, 0x83, 0x05, 0x12, 0x9b, + 0x8a, 0x8f, 0xab, 0xc9, 0xe0, 0x94, 0x83, 0x29, 0xc1, 0xa4, 0xa0, 0x4b, 0xb7, 0x02, 0xba, 0xdc, + 0x2f, 0x0c, 0xdf, 0x11, 0xee, 0x5c, 0x0b, 0x9b, 0xe5, 0x99, 0xcd, 0x48, 0x0f, 0x07, 0x32, 0xa7, + 0x28, 0x41, 0xa3, 0x68, 0x16, 0xc8, 0x9c, 0x9c, 0xe0, 0x18, 0xb4, 0x2c, 0xa4, 0xa2, 0x41, 0x82, + 0x46, 0xdd, 0x59, 0xdd, 0x11, 0x82, 0x23, 0x95, 0x95, 0x82, 0x86, 0x5e, 0xf5, 0x35, 0x49, 0xf0, + 0xff, 0x5c, 0x18, 0xae, 0xe5, 0xd2, 0x4a, 0x50, 0x34, 0xf2, 0xa3, 0xa6, 0x44, 0x06, 0xb8, 0xc3, + 0x33, 0x2b, 0x0a, 0xd0, 0x6b, 0xfa, 0xcf, 0x8f, 0x7f, 0x7b, 0xe7, 0x28, 0x39, 0x28, 0x1a, 0xef, + 0x1d, 0x5d, 0xed, 0x34, 0x9b, 0x15, 0x86, 0xb6, 0x93, 0xd0, 0x69, 0xae, 0x9e, 0xb2, 0xef, 0xd7, + 0x8f, 0xa7, 0x90, 0xe2, 0xd8, 0x25, 0xed, 0x23, 0x72, 0x74, 0x48, 0xd8, 0x47, 0x14, 0x51, 0x34, + 0x7c, 0x41, 0xb8, 0x7d, 0xa3, 0xe1, 0x4e, 0x2e, 0x44, 0x83, 0xa6, 0xeb, 0x69, 0x28, 0x6e, 0x9b, + 0xd5, 0xfc, 0x41, 0x70, 0x5b, 0xe3, 0x1c, 0xda, 0x06, 0x67, 0xf8, 0x87, 0x93, 0x61, 0xcc, 0x41, + 0x59, 0x0d, 0x8b, 0x85, 0xd0, 0x35, 0x52, 0x43, 0x99, 0x9e, 0xf9, 0x34, 0x0c, 0x47, 0xee, 0x27, + 0x72, 0x8c, 0x7b, 0xb5, 0xe1, 0x79, 0x23, 0x53, 0x70, 0x75, 0xf9, 0xb6, 0x65, 0x68, 0xb3, 0x65, + 0xe8, 0x6b, 0xcb, 0xd0, 0xf3, 0x8e, 0xb5, 0x36, 0x3b, 0xd6, 0xfa, 0xdc, 0xb1, 0xd6, 0xed, 0xb0, + 0x90, 0xf6, 0x7e, 0x35, 0x1f, 0x73, 0x28, 0x53, 0x50, 0x06, 0x94, 0x4e, 0xfd, 0xf3, 0x98, 0xba, + 0x53, 0xda, 0xf5, 0x52, 0x98, 0x79, 0xec, 0xef, 0x74, 0xf1, 0x13, 0x00, 0x00, 0xff, 0xff, 0xd0, + 0x82, 0x18, 0x99, 0xde, 0x01, 0x00, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { diff --git a/x/service/types/tx.pb.go b/x/svc/types/tx.pb.go similarity index 87% rename from x/service/types/tx.pb.go rename to x/svc/types/tx.pb.go index 99c900605..2fb06a722 100644 --- a/x/service/types/tx.pb.go +++ b/x/svc/types/tx.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: service/v1/tx.proto +// source: svc/v1/tx.proto package types @@ -46,7 +46,7 @@ func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParams) ProtoMessage() {} func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_361c6b19b8fa4769, []int{0} + return fileDescriptor_084252b8c07dd202, []int{0} } func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -100,7 +100,7 @@ func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParamsResponse) ProtoMessage() {} func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_361c6b19b8fa4769, []int{1} + return fileDescriptor_084252b8c07dd202, []int{1} } func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -142,7 +142,7 @@ func (m *MsgRegisterService) Reset() { *m = MsgRegisterService{} } func (m *MsgRegisterService) String() string { return proto.CompactTextString(m) } func (*MsgRegisterService) ProtoMessage() {} func (*MsgRegisterService) Descriptor() ([]byte, []int) { - return fileDescriptor_361c6b19b8fa4769, []int{2} + return fileDescriptor_084252b8c07dd202, []int{2} } func (m *MsgRegisterService) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -195,7 +195,7 @@ func (m *MsgRegisterServiceResponse) Reset() { *m = MsgRegisterServiceRe func (m *MsgRegisterServiceResponse) String() string { return proto.CompactTextString(m) } func (*MsgRegisterServiceResponse) ProtoMessage() {} func (*MsgRegisterServiceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_361c6b19b8fa4769, []int{3} + return fileDescriptor_084252b8c07dd202, []int{3} } func (m *MsgRegisterServiceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -239,43 +239,43 @@ func (m *MsgRegisterServiceResponse) GetDid() string { } func init() { - proto.RegisterType((*MsgUpdateParams)(nil), "service.v1.MsgUpdateParams") - proto.RegisterType((*MsgUpdateParamsResponse)(nil), "service.v1.MsgUpdateParamsResponse") - proto.RegisterType((*MsgRegisterService)(nil), "service.v1.MsgRegisterService") - proto.RegisterType((*MsgRegisterServiceResponse)(nil), "service.v1.MsgRegisterServiceResponse") + proto.RegisterType((*MsgUpdateParams)(nil), "svc.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "svc.v1.MsgUpdateParamsResponse") + proto.RegisterType((*MsgRegisterService)(nil), "svc.v1.MsgRegisterService") + proto.RegisterType((*MsgRegisterServiceResponse)(nil), "svc.v1.MsgRegisterServiceResponse") } -func init() { proto.RegisterFile("service/v1/tx.proto", fileDescriptor_361c6b19b8fa4769) } +func init() { proto.RegisterFile("svc/v1/tx.proto", fileDescriptor_084252b8c07dd202) } -var fileDescriptor_361c6b19b8fa4769 = []byte{ - // 430 bytes of a gzipped FileDescriptorProto +var fileDescriptor_084252b8c07dd202 = []byte{ + // 428 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0x41, 0x8b, 0xd3, 0x40, - 0x14, 0xc7, 0x33, 0xae, 0xee, 0xda, 0xa7, 0x58, 0x99, 0x5d, 0xd8, 0x6c, 0x84, 0xb8, 0x44, 0x58, - 0x96, 0x85, 0x4d, 0xdc, 0x15, 0x44, 0xf6, 0xa4, 0x3d, 0x79, 0x29, 0x94, 0x14, 0x0f, 0x7a, 0x91, - 0x34, 0x19, 0xa6, 0x81, 0x26, 0x13, 0xe6, 0x4d, 0x4b, 0x7b, 0x13, 0xaf, 0x82, 0xf8, 0x51, 0x7a, - 0xf0, 0xe2, 0x37, 0xe8, 0xb1, 0x78, 0xf2, 0x24, 0xd2, 0x1e, 0xfa, 0x35, 0x24, 0xc9, 0xc4, 0xc6, - 0x08, 0xf5, 0x12, 0xe6, 0xbd, 0xff, 0x7f, 0xfe, 0xef, 0x97, 0x99, 0x81, 0x43, 0x64, 0x72, 0x12, - 0x87, 0xcc, 0x9b, 0x5c, 0x79, 0x6a, 0xea, 0x66, 0x52, 0x28, 0x41, 0x41, 0x37, 0xdd, 0xc9, 0x95, - 0x75, 0x1c, 0x0a, 0x4c, 0x04, 0x7a, 0x09, 0xf2, 0xdc, 0x93, 0x20, 0x2f, 0x4d, 0xd6, 0x49, 0x29, - 0xbc, 0x2f, 0x2a, 0xaf, 0x2c, 0xb4, 0x74, 0xc4, 0x05, 0x17, 0x65, 0x3f, 0x5f, 0xe9, 0xae, 0x59, - 0x1b, 0xc5, 0x59, 0xca, 0x30, 0xd6, 0x7e, 0xe7, 0x13, 0x81, 0x76, 0x17, 0xf9, 0x9b, 0x2c, 0x0a, - 0x14, 0xeb, 0x05, 0x32, 0x48, 0x90, 0x3e, 0x87, 0x56, 0x30, 0x56, 0x43, 0x21, 0x63, 0x35, 0x33, - 0xc9, 0x29, 0x39, 0x6f, 0x75, 0xcc, 0xef, 0x5f, 0x2f, 0x8f, 0xf4, 0xa0, 0x57, 0x51, 0x24, 0x19, - 0x62, 0x5f, 0xc9, 0x38, 0xe5, 0xfe, 0xd6, 0x4a, 0x9f, 0xc2, 0x7e, 0x56, 0x24, 0x98, 0xb7, 0x4e, - 0xc9, 0xf9, 0xbd, 0x6b, 0xea, 0x6e, 0x7f, 0xc6, 0x2d, 0xb3, 0x3b, 0xb7, 0x17, 0x3f, 0x1f, 0x1b, - 0xbe, 0xf6, 0xdd, 0x3c, 0xf8, 0xb8, 0x99, 0x5f, 0x6c, 0x13, 0x9c, 0x13, 0x38, 0x6e, 0xc0, 0xf8, - 0x0c, 0x33, 0x91, 0x22, 0x73, 0x3e, 0x13, 0xa0, 0x5d, 0xe4, 0x3e, 0xe3, 0x31, 0x2a, 0x26, 0xfb, - 0x65, 0x32, 0x7d, 0x01, 0x10, 0x8a, 0x54, 0x49, 0x31, 0x1a, 0x31, 0xf9, 0x5f, 0xd8, 0x9a, 0x97, - 0x5e, 0xc2, 0x81, 0xc6, 0xd3, 0xb8, 0x87, 0x75, 0x5c, 0x9d, 0xef, 0x57, 0x9e, 0x9b, 0x76, 0x8e, - 0x5a, 0xdb, 0xef, 0xbc, 0x06, 0xeb, 0x5f, 0x9e, 0x0a, 0x97, 0x9a, 0x70, 0x80, 0xe3, 0x30, 0x64, - 0x88, 0x05, 0xd4, 0x5d, 0xbf, 0x2a, 0xe9, 0x43, 0xd8, 0x8b, 0xe2, 0xa8, 0x98, 0xd9, 0xf2, 0xf3, - 0xe5, 0xf5, 0x37, 0x02, 0x7b, 0x5d, 0xe4, 0xb4, 0x07, 0xf7, 0xff, 0xba, 0x87, 0x47, 0x75, 0xa0, - 0xc6, 0xb9, 0x58, 0x4f, 0x76, 0x88, 0x7f, 0x28, 0xde, 0x42, 0xbb, 0x79, 0x60, 0x76, 0x63, 0x5f, - 0x43, 0xb7, 0xce, 0x76, 0xeb, 0x55, 0xb4, 0x75, 0xe7, 0xc3, 0x66, 0x7e, 0x41, 0x3a, 0x2f, 0x17, - 0x2b, 0x9b, 0x2c, 0x57, 0x36, 0xf9, 0xb5, 0xb2, 0xc9, 0x97, 0xb5, 0x6d, 0x2c, 0xd7, 0xb6, 0xf1, - 0x63, 0x6d, 0x1b, 0xef, 0xce, 0x78, 0xac, 0x86, 0xe3, 0x81, 0x1b, 0x8a, 0xc4, 0x13, 0x29, 0x8a, - 0x54, 0x7a, 0xc5, 0x67, 0xea, 0x55, 0x8f, 0x51, 0xcd, 0x32, 0x86, 0x83, 0xfd, 0xe2, 0x21, 0x3e, - 0xfb, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xc6, 0x80, 0x50, 0xdb, 0x0f, 0x03, 0x00, 0x00, + 0x14, 0xc7, 0x33, 0xae, 0x76, 0xed, 0x28, 0x1b, 0x19, 0x16, 0x9a, 0xcd, 0x21, 0xbb, 0xe4, 0xb4, + 0x2e, 0x9a, 0xb0, 0x15, 0x44, 0x8a, 0x17, 0x7b, 0xea, 0xa5, 0xa0, 0x29, 0x5e, 0xbc, 0x48, 0x3a, + 0x19, 0xa6, 0x81, 0x26, 0x13, 0xe6, 0x4d, 0x43, 0x7b, 0x13, 0x2f, 0x82, 0x27, 0xbf, 0x86, 0xb7, + 0x1e, 0xfc, 0x10, 0x3d, 0x16, 0x4f, 0x9e, 0x44, 0xda, 0x43, 0xbf, 0x86, 0x24, 0x93, 0xd8, 0x1a, + 0x29, 0x5e, 0xc2, 0x9b, 0xf9, 0xbf, 0xff, 0x7f, 0x7e, 0x79, 0x3c, 0x6c, 0x42, 0x4e, 0xfd, 0xfc, + 0xd6, 0x57, 0x73, 0x2f, 0x93, 0x42, 0x09, 0xd2, 0x82, 0x9c, 0x7a, 0xf9, 0xad, 0xdd, 0xa1, 0x02, + 0x12, 0x01, 0x7e, 0x02, 0xbc, 0xd0, 0x13, 0xe0, 0xba, 0xc1, 0x3e, 0xaf, 0x1c, 0x9c, 0xa5, 0x0c, + 0x62, 0xa8, 0x6f, 0xb9, 0xe0, 0xa2, 0x2c, 0xfd, 0xa2, 0xaa, 0x6e, 0x2f, 0x74, 0xc8, 0x7b, 0x2d, + 0xe8, 0x83, 0x96, 0xdc, 0x4f, 0x08, 0x9b, 0x43, 0xe0, 0x6f, 0xb3, 0x28, 0x54, 0xec, 0x75, 0x28, + 0xc3, 0x04, 0xc8, 0x73, 0xdc, 0x0e, 0x67, 0x6a, 0x22, 0x64, 0xac, 0x16, 0x16, 0xba, 0x42, 0xd7, + 0xed, 0xbe, 0xf5, 0xfd, 0xdb, 0xd3, 0xf3, 0xca, 0xf8, 0x2a, 0x8a, 0x24, 0x03, 0x18, 0x29, 0x19, + 0xa7, 0x3c, 0xd8, 0xb7, 0x92, 0x27, 0xb8, 0x95, 0x95, 0x09, 0xd6, 0x9d, 0x2b, 0x74, 0xfd, 0xa0, + 0x7b, 0xe6, 0xe9, 0x9f, 0xf0, 0x74, 0x6e, 0xff, 0xee, 0xea, 0xe7, 0xa5, 0x11, 0x54, 0x3d, 0xbd, + 0xb3, 0x8f, 0xbb, 0xe5, 0xcd, 0xde, 0xed, 0x5e, 0xe0, 0x4e, 0x03, 0x24, 0x60, 0x90, 0x89, 0x14, + 0x98, 0xfb, 0x19, 0x61, 0x32, 0x04, 0x1e, 0x30, 0x1e, 0x83, 0x62, 0x72, 0xc4, 0x64, 0x1e, 0x53, + 0x46, 0x5e, 0x60, 0x4c, 0x45, 0xaa, 0xa4, 0x98, 0x4e, 0x99, 0xfc, 0x2f, 0xe8, 0x41, 0x2f, 0x79, + 0x8c, 0x4f, 0x41, 0x87, 0x54, 0xa8, 0x66, 0x8d, 0x5a, 0x65, 0x07, 0xb5, 0xde, 0x33, 0x0b, 0xcc, + 0x03, 0xaf, 0x3b, 0xc0, 0xf6, 0xbf, 0x2c, 0x35, 0x2a, 0xb1, 0xf0, 0x29, 0xcc, 0x28, 0x65, 0x00, + 0x25, 0xd0, 0xfd, 0xa0, 0x3e, 0x92, 0x47, 0xf8, 0x24, 0x8a, 0xa3, 0xf2, 0xbd, 0x76, 0x50, 0x94, + 0xdd, 0xaf, 0x08, 0x9f, 0x0c, 0x81, 0x93, 0x01, 0x7e, 0xf8, 0xd7, 0xfc, 0x3b, 0x35, 0x4c, 0x63, + 0x1e, 0xf6, 0xe5, 0x11, 0xe1, 0xcf, 0xeb, 0x6f, 0xb0, 0xd9, 0x1c, 0x92, 0x7d, 0xe0, 0x69, 0x68, + 0xb6, 0x7b, 0x5c, 0xab, 0x23, 0xed, 0x7b, 0x1f, 0x76, 0xcb, 0x1b, 0xd4, 0x7f, 0xb9, 0xda, 0x38, + 0x68, 0xbd, 0x71, 0xd0, 0xaf, 0x8d, 0x83, 0xbe, 0x6c, 0x1d, 0x63, 0xbd, 0x75, 0x8c, 0x1f, 0x5b, + 0xc7, 0x78, 0xe7, 0xf2, 0x58, 0x4d, 0x66, 0x63, 0x8f, 0x8a, 0xc4, 0x17, 0x29, 0x88, 0x54, 0xfa, + 0xe5, 0x67, 0xee, 0x17, 0x1b, 0xaa, 0x16, 0x19, 0x83, 0x71, 0xab, 0x5c, 0xb6, 0x67, 0xbf, 0x03, + 0x00, 0x00, 0xff, 0xff, 0x98, 0xbc, 0xa7, 0xbe, 0xe7, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -309,7 +309,7 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { out := new(MsgUpdateParamsResponse) - err := c.cc.Invoke(ctx, "/service.v1.Msg/UpdateParams", in, out, opts...) + err := c.cc.Invoke(ctx, "/svc.v1.Msg/UpdateParams", in, out, opts...) if err != nil { return nil, err } @@ -318,7 +318,7 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts func (c *msgClient) RegisterService(ctx context.Context, in *MsgRegisterService, opts ...grpc.CallOption) (*MsgRegisterServiceResponse, error) { out := new(MsgRegisterServiceResponse) - err := c.cc.Invoke(ctx, "/service.v1.Msg/RegisterService", in, out, opts...) + err := c.cc.Invoke(ctx, "/svc.v1.Msg/RegisterService", in, out, opts...) if err != nil { return nil, err } @@ -361,7 +361,7 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/service.v1.Msg/UpdateParams", + FullMethod: "/svc.v1.Msg/UpdateParams", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) @@ -379,7 +379,7 @@ func _Msg_RegisterService_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/service.v1.Msg/RegisterService", + FullMethod: "/svc.v1.Msg/RegisterService", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MsgServer).RegisterService(ctx, req.(*MsgRegisterService)) @@ -389,7 +389,7 @@ func _Msg_RegisterService_Handler(srv interface{}, ctx context.Context, dec func var Msg_serviceDesc = _Msg_serviceDesc var _Msg_serviceDesc = grpc.ServiceDesc{ - ServiceName: "service.v1.Msg", + ServiceName: "svc.v1.Msg", HandlerType: (*MsgServer)(nil), Methods: []grpc.MethodDesc{ { @@ -402,7 +402,7 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "service/v1/tx.proto", + Metadata: "svc/v1/tx.proto", } func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { diff --git a/x/vault/keeper/genesis.go b/x/vault/keeper/genesis.go deleted file mode 100644 index 165d62baa..000000000 --- a/x/vault/keeper/genesis.go +++ /dev/null @@ -1,61 +0,0 @@ -package keeper - -import ( - "context" - - "cosmossdk.io/log" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ipfs/boxo/path" - - "github.com/onsonr/sonr/x/vault/types" -) - -func (k Keeper) Logger() log.Logger { - return k.logger -} - -// InitGenesis initializes the module's state from a genesis state. -func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { - // this line is used by starport scaffolding # genesis/module/init - if err := data.Params.Validate(); err != nil { - return err - } - - return k.Params.Set(ctx, data.Params) -} - -// ExportGenesis exports the module's state to a genesis state. -func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { - params, err := k.Params.Get(ctx) - if err != nil { - panic(err) - } - - // this line is used by starport scaffolding # genesis/module/export - - return &types.GenesisState{ - Params: params, - } -} - -// IPFSConnected returns true if the IPFS client is initialized -func (c Keeper) IPFSConnected() bool { - return c.hasIpfsConn -} - -// HasPathInIPFS checks if a file is in the local IPFS node -func (k Keeper) HasPathInIPFS(ctx sdk.Context, cid string) (bool, error) { - path, err := path.NewPath(cid) - if err != nil { - return false, err - } - v, err := k.ipfsClient.Unixfs().Get(ctx, path) - if err != nil { - return false, err - } - - if v == nil { - return false, nil - } - return true, nil -} diff --git a/x/vault/keeper/keeper.go b/x/vault/keeper/keeper.go deleted file mode 100644 index 846a0d892..000000000 --- a/x/vault/keeper/keeper.go +++ /dev/null @@ -1,126 +0,0 @@ -package keeper - -import ( - "time" - - "cosmossdk.io/collections" - storetypes "cosmossdk.io/core/store" - "cosmossdk.io/log" - "cosmossdk.io/orm/model/ormdb" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - "github.com/ipfs/kubo/client/rpc" - - apiv1 "github.com/onsonr/sonr/api/vault/v1" - "github.com/onsonr/sonr/pkg/core/dwn" - didkeeper "github.com/onsonr/sonr/x/did/keeper" - "github.com/onsonr/sonr/x/vault/types" -) - -type Keeper struct { - cdc codec.BinaryCodec - - logger log.Logger - - // state management - Schema collections.Schema - Params collections.Item[types.Params] - OrmDB apiv1.StateStore - - authority string - - ipfsClient *rpc.HttpApi - hasIpfsConn bool - - AccountKeeper authkeeper.AccountKeeper - DIDKeeper didkeeper.Keeper -} - -// NewKeeper creates a new Keeper instance -func NewKeeper( - cdc codec.BinaryCodec, - storeService storetypes.KVStoreService, - logger log.Logger, - authority string, - authKeeper authkeeper.AccountKeeper, - didKeeper didkeeper.Keeper, -) Keeper { - var hasIpfs bool - logger = logger.With(log.ModuleKey, "x/"+types.ModuleName) - - sb := collections.NewSchemaBuilder(storeService) - - if authority == "" { - authority = authtypes.NewModuleAddress(govtypes.ModuleName).String() - } - - db, err := ormdb.NewModuleDB(&types.ORMModuleSchema, ormdb.ModuleDBOptions{KVStoreService: storeService}) - if err != nil { - panic(err) - } - - store, err := apiv1.NewStateStore(db) - if err != nil { - panic(err) - } - - ipfsClient, err := rpc.NewLocalApi() - if err != nil { - hasIpfs = false - } - - if ipfsClient != nil { - hasIpfs = true - } - - k := Keeper{ - cdc: cdc, - logger: logger, - DIDKeeper: didKeeper, - AccountKeeper: authKeeper, - Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), - OrmDB: store, - - ipfsClient: ipfsClient, - hasIpfsConn: hasIpfs, - authority: authority, - } - - schema, err := sb.Build() - if err != nil { - panic(err) - } - - k.Schema = schema - - return k -} - -// currentSchema returns the current schema -func (k Keeper) currentSchema(ctx sdk.Context) (*dwn.Schema, error) { - p, err := k.Params.Get(ctx) - if err != nil { - return nil, err - } - schema := p.Schema - return &dwn.Schema{ - Version: int(schema.Version), - Account: schema.Account, - Asset: schema.Asset, - Chain: schema.Chain, - Credential: schema.Credential, - Jwk: schema.Jwk, - Grant: schema.Grant, - Keyshare: schema.Keyshare, - Profile: schema.Profile, - }, nil -} - -func calculateBlockExpiry(sdkctx sdk.Context, duration time.Duration) int64 { - blockTime := sdkctx.BlockTime() - avgBlockTime := float64(blockTime.Sub(blockTime).Seconds()) - return int64(duration.Seconds() / avgBlockTime) -} diff --git a/x/vault/keeper/orm_test.go b/x/vault/keeper/orm_test.go deleted file mode 100644 index a76b05bd0..000000000 --- a/x/vault/keeper/orm_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package keeper_test - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestORM(t *testing.T) { - f := SetupTest(t) - - dt := f.k.OrmDB.DWNTable() - require.NotNil(t, dt) -} diff --git a/x/vault/keeper/querier.go b/x/vault/keeper/querier.go deleted file mode 100644 index 8e4f2b7d1..000000000 --- a/x/vault/keeper/querier.go +++ /dev/null @@ -1,128 +0,0 @@ -package keeper - -import ( - "context" - "fmt" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/onsonr/sonr/pkg/crypto/mpc" - "github.com/onsonr/sonr/x/did/controller" - "github.com/onsonr/sonr/x/vault/types" -) - -var _ types.QueryServer = Querier{} - -type Querier struct{ Keeper } - -func NewQuerier(keeper Keeper) Querier { - return Querier{Keeper: keeper} -} - -// ╭───────────────────────────────────────────────────────────╮ -// │ Fixed Query Methods │ -// ╰───────────────────────────────────────────────────────────╯ - -// Params implements types.QueryServer. -func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { - ctx := sdk.UnwrapSDKContext(c) - - p, err := k.Keeper.Params.Get(ctx) - if err != nil { - return nil, err - } - - return &types.QueryParamsResponse{Params: &p}, nil -} - -// Schema implements types.QueryServer. -func (k Querier) Schema(goCtx context.Context, req *types.QuerySchemaRequest) (*types.QuerySchemaResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - p, err := k.Keeper.Params.Get(ctx) - if err != nil { - return nil, err - } - return &types.QuerySchemaResponse{ - Schema: p.Schema, - }, nil -} - -// ╭───────────────────────────────────────────────────────────╮ -// │ Pre-Authenticated Queries │ -// ╰───────────────────────────────────────────────────────────╯ - -// Allocate implements types.QueryServer. -func (k Querier) Allocate(goCtx context.Context, req *types.QueryAllocateRequest) (*types.QueryAllocateResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - // 1. Get current schema - sch, err := k.currentSchema(ctx) - if err != nil { - ctx.Logger().Error(fmt.Sprintf("Error getting current schema: %s", err.Error())) - return nil, types.ErrInvalidSchema.Wrap(err.Error()) - } - - // 2. Generate MPC Keyshares for new Account - shares, err := mpc.NewKeyshareSource() - if err != nil { - ctx.Logger().Error(fmt.Sprintf("Error generating keyshares: %s", err.Error())) - return nil, types.ErrInvalidSchema.Wrap(err.Error()) - } - - // 3. Create Controller from Keyshares - con, err := controller.New(shares) - if err != nil { - ctx.Logger().Error(fmt.Sprintf("Error creating controller: %s", err.Error())) - return nil, types.ErrControllerCreation.Wrap(err.Error()) - } - - // 4. Create a new vault PWA for service-worker - v, err := types.SpawnVault("", con.SonrAddress(), con.ChainID(), sch) - if err != nil { - ctx.Logger().Error(fmt.Sprintf("Error creating vault: %s", err.Error())) - return nil, types.ErrInvalidSchema.Wrap(err.Error()) - } - - // 5. Add to IPFS and Return CID for User Claims in Gateway - cid, err := k.ipfsClient.Unixfs().Add(context.Background(), v) - if err != nil { - ctx.Logger().Error(fmt.Sprintf("Error adding to IPFS: %s", err.Error())) - return nil, types.ErrVaultAssembly.Wrap(err.Error()) - } - - // 6. Return final response - return &types.QueryAllocateResponse{ - Success: true, - Cid: cid.String(), - ExpiryBlock: calculateBlockExpiry(ctx, time.Second*30), - }, nil -} - -// ╭───────────────────────────────────────────────────────────╮ -// │ Authenticated Endpoints │ -// ╰───────────────────────────────────────────────────────────╯ - -// Sync implements types.QueryServer. -func (k Querier) Sync(goCtx context.Context, req *types.QuerySyncRequest) (*types.QuerySyncResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - p, err := k.Keeper.Params.Get(ctx) - if err != nil { - return nil, err - } - c, _ := k.DIDKeeper.ResolveController(ctx, req.Did) - if c == nil { - return &types.QuerySyncResponse{ - Success: false, - Schema: p.Schema, - ChainID: ctx.ChainID(), - }, nil - } - return &types.QuerySyncResponse{ - Success: true, - Schema: p.Schema, - ChainID: ctx.ChainID(), - Address: c.SonrAddress(), - }, nil -} diff --git a/x/vault/types/errors.go b/x/vault/types/errors.go deleted file mode 100644 index 1c13a8993..000000000 --- a/x/vault/types/errors.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -import sdkerrors "cosmossdk.io/errors" - -var ( - ErrInvalidGenesisState = sdkerrors.Register(ModuleName, 100, "invalid genesis state") - ErrInvalidSchema = sdkerrors.Register(ModuleName, 200, "invalid schema") - ErrVaultAssembly = sdkerrors.Register(ModuleName, 201, "vault assembly") - ErrControllerCreation = sdkerrors.Register(ModuleName, 202, "failed to create controller") - ErrUnsupportedKeyEncoding = sdkerrors.Register(ModuleName, 300, "unsupported key encoding") - ErrUnsopportedChainCode = sdkerrors.Register(ModuleName, 301, "unsupported chain code") - ErrUnsupportedKeyCurve = sdkerrors.Register(ModuleName, 302, "unsupported key curve") -) diff --git a/x/vault/types/formatter.go b/x/vault/types/formatter.go deleted file mode 100644 index ab1254f4c..000000000 --- a/x/vault/types/formatter.go +++ /dev/null @@ -1 +0,0 @@ -package types diff --git a/x/vault/types/state.pb.go b/x/vault/types/state.pb.go deleted file mode 100644 index 0b38ab9b0..000000000 --- a/x/vault/types/state.pb.go +++ /dev/null @@ -1,457 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: vault/v1/state.proto - -package types - -import ( - _ "cosmossdk.io/orm" - fmt "fmt" - proto "github.com/cosmos/gogoproto/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.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type DWN struct { - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Alias string `protobuf:"bytes,2,opt,name=alias,proto3" json:"alias,omitempty"` - Cid string `protobuf:"bytes,3,opt,name=cid,proto3" json:"cid,omitempty"` - Resolver string `protobuf:"bytes,4,opt,name=resolver,proto3" json:"resolver,omitempty"` -} - -func (m *DWN) Reset() { *m = DWN{} } -func (m *DWN) String() string { return proto.CompactTextString(m) } -func (*DWN) ProtoMessage() {} -func (*DWN) Descriptor() ([]byte, []int) { - return fileDescriptor_2ad3e71ba384142e, []int{0} -} -func (m *DWN) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *DWN) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_DWN.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 *DWN) XXX_Merge(src proto.Message) { - xxx_messageInfo_DWN.Merge(m, src) -} -func (m *DWN) XXX_Size() int { - return m.Size() -} -func (m *DWN) XXX_DiscardUnknown() { - xxx_messageInfo_DWN.DiscardUnknown(m) -} - -var xxx_messageInfo_DWN proto.InternalMessageInfo - -func (m *DWN) GetId() uint64 { - if m != nil { - return m.Id - } - return 0 -} - -func (m *DWN) GetAlias() string { - if m != nil { - return m.Alias - } - return "" -} - -func (m *DWN) GetCid() string { - if m != nil { - return m.Cid - } - return "" -} - -func (m *DWN) GetResolver() string { - if m != nil { - return m.Resolver - } - return "" -} - -func init() { - proto.RegisterType((*DWN)(nil), "vault.v1.DWN") -} - -func init() { proto.RegisterFile("vault/v1/state.proto", fileDescriptor_2ad3e71ba384142e) } - -var fileDescriptor_2ad3e71ba384142e = []byte{ - // 240 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x29, 0x4b, 0x2c, 0xcd, - 0x29, 0xd1, 0x2f, 0x33, 0xd4, 0x2f, 0x2e, 0x49, 0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, - 0x17, 0xe2, 0x00, 0x8b, 0xea, 0x95, 0x19, 0x4a, 0x89, 0x27, 0xe7, 0x17, 0xe7, 0xe6, 0x17, 0xeb, - 0xe7, 0x17, 0xe5, 0x82, 0x14, 0xe5, 0x17, 0xe5, 0x42, 0x94, 0x28, 0x35, 0x33, 0x72, 0x31, 0xbb, - 0x84, 0xfb, 0x09, 0xf1, 0x71, 0x31, 0x65, 0xa6, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x04, 0x31, - 0x65, 0xa6, 0x08, 0x89, 0x70, 0xb1, 0x26, 0xe6, 0x64, 0x26, 0x16, 0x4b, 0x30, 0x29, 0x30, 0x6a, - 0x70, 0x06, 0x41, 0x38, 0x42, 0x02, 0x5c, 0xcc, 0xc9, 0x99, 0x29, 0x12, 0xcc, 0x60, 0x31, 0x10, - 0x53, 0x48, 0x8a, 0x8b, 0xa3, 0x28, 0xb5, 0x38, 0x3f, 0xa7, 0x2c, 0xb5, 0x48, 0x82, 0x05, 0x2c, - 0x0c, 0xe7, 0x5b, 0x69, 0x7c, 0x9a, 0x77, 0xb9, 0x8f, 0x59, 0x89, 0x8b, 0x0d, 0x64, 0xb6, 0x00, - 0xa3, 0x10, 0x37, 0xd4, 0x4c, 0x01, 0x46, 0x09, 0x46, 0x21, 0x4e, 0xb0, 0x51, 0x02, 0x4c, 0x12, - 0x8c, 0x12, 0x8c, 0x4e, 0x76, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, - 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, - 0x92, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, 0x9f, 0x57, 0x9c, 0x9f, - 0x57, 0xa4, 0x0f, 0x26, 0x2a, 0xf4, 0x21, 0x3e, 0x2e, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, - 0x7b, 0xc6, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x1a, 0xfe, 0x9e, 0x9c, 0x07, 0x01, 0x00, 0x00, -} - -func (m *DWN) 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 *DWN) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *DWN) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Resolver) > 0 { - i -= len(m.Resolver) - copy(dAtA[i:], m.Resolver) - i = encodeVarintState(dAtA, i, uint64(len(m.Resolver))) - i-- - dAtA[i] = 0x22 - } - if len(m.Cid) > 0 { - i -= len(m.Cid) - copy(dAtA[i:], m.Cid) - i = encodeVarintState(dAtA, i, uint64(len(m.Cid))) - i-- - dAtA[i] = 0x1a - } - if len(m.Alias) > 0 { - i -= len(m.Alias) - copy(dAtA[i:], m.Alias) - i = encodeVarintState(dAtA, i, uint64(len(m.Alias))) - i-- - dAtA[i] = 0x12 - } - if m.Id != 0 { - i = encodeVarintState(dAtA, i, uint64(m.Id)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func encodeVarintState(dAtA []byte, offset int, v uint64) int { - offset -= sovState(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *DWN) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Id != 0 { - n += 1 + sovState(uint64(m.Id)) - } - l = len(m.Alias) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.Cid) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.Resolver) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - return n -} - -func sovState(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozState(x uint64) (n int) { - return sovState(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *DWN) 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 ErrIntOverflowState - } - 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: DWN: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DWN: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - m.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Alias", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Alias = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Cid", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Cid = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resolver", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resolver = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipState(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthState - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipState(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, ErrIntOverflowState - } - 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, ErrIntOverflowState - } - 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, ErrIntOverflowState - } - 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, ErrInvalidLengthState - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupState - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthState - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthState = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowState = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupState = fmt.Errorf("proto: unexpected end of group") -) From 0e14099f0cff270b1b69d97173a4911032afe89d Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 15:47:21 -0500 Subject: [PATCH 09/30] refactor: remove unused dependencies and simplify module imports --- go.mod | 53 ------- go.sum | 325 ----------------------------------------- x/dwn/client/cli/tx.go | 11 +- x/svc/client/cli/tx.go | 11 +- 4 files changed, 2 insertions(+), 398 deletions(-) diff --git a/go.mod b/go.mod index de1ac9b13..9107f8fb9 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,6 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/gtank/merlin v0.1.1 github.com/ipfs/boxo v0.24.0 - github.com/ipfs/kubo v0.31.0 github.com/joho/godotenv v1.5.1 github.com/labstack/echo/v4 v4.10.2 github.com/libp2p/go-libp2p v0.36.5 @@ -113,7 +112,6 @@ require ( github.com/99designs/keyring v1.2.1 // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/DataDog/zstd v1.5.5 // indirect - github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aws/aws-sdk-go v1.44.224 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect @@ -121,7 +119,6 @@ require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect github.com/btcsuite/btcd v0.20.1-beta // indirect github.com/catppuccin/go v0.2.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -158,7 +155,6 @@ require ( github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/emicklei/dot v1.6.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -181,7 +177,6 @@ require ( github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-tpm v0.9.1 // indirect - github.com/google/gopacket v1.1.19 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect @@ -191,13 +186,11 @@ require ( github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-getter v1.7.5 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-metrics v0.5.3 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect @@ -212,26 +205,7 @@ require ( github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/ipfs/bbloom v0.0.4 // indirect - github.com/ipfs/go-bitfield v1.1.0 // indirect - github.com/ipfs/go-block-format v0.2.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect - github.com/ipfs/go-datastore v0.6.0 // indirect - github.com/ipfs/go-ds-measure v0.2.0 // indirect - github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-ipfs-cmds v0.13.0 // indirect - github.com/ipfs/go-ipfs-util v0.0.3 // indirect - github.com/ipfs/go-ipld-cbor v0.2.0 // indirect - github.com/ipfs/go-ipld-format v0.6.0 // indirect - github.com/ipfs/go-ipld-legacy v0.2.1 // indirect - github.com/ipfs/go-log v1.0.5 // indirect - github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipfs/go-metrics-interface v0.0.1 // indirect - github.com/ipfs/go-unixfsnode v1.9.1 // indirect - github.com/ipld/go-car/v2 v2.14.2 // indirect - github.com/ipld/go-codec-dagpb v1.6.0 // indirect - github.com/ipld/go-ipld-prime v0.21.0 // indirect - github.com/jbenet/goprocess v0.1.4 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect @@ -240,16 +214,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/labstack/gommon v0.4.0 // indirect github.com/lib/pq v1.10.7 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-core v0.7.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.26.1 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect - github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect - github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-openssl v0.1.0 // indirect github.com/linxGnu/grocksdb v1.8.14 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect @@ -260,7 +225,6 @@ require ( github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/miekg/dns v1.1.61 // indirect github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -275,21 +239,14 @@ require ( github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect - github.com/multiformats/go-multiaddr v0.13.0 // indirect - github.com/multiformats/go-multiaddr-dns v0.4.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.5.0 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/gomega v1.33.1 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect @@ -301,7 +258,6 @@ require ( github.com/rs/zerolog v1.32.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/samber/lo v1.46.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect @@ -316,10 +272,6 @@ require ( github.com/valyala/fasttemplate v1.2.2 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect - github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.1.2 // indirect - github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect @@ -331,10 +283,7 @@ require ( go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.8.0 // indirect @@ -342,9 +291,7 @@ require ( golang.org/x/term v0.24.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/api v0.169.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect diff --git a/go.sum b/go.sum index e97a4c572..d54e9b6ed 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc h1:utDghgcjE8u+EBjHOgYT+dJPcnDF05KqWMBcjuJy510= -bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.0.0-20170206221025-ce650573d812/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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= @@ -814,8 +812,6 @@ git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDf github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= @@ -856,8 +852,6 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXY github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= -github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -893,10 +887,6 @@ github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/Y 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/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= -github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= -github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= -github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= 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/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= @@ -946,8 +936,6 @@ github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWp github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= -github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -960,8 +948,6 @@ github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= 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/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= @@ -996,8 +982,6 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= -github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= 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= @@ -1091,13 +1075,10 @@ github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1 github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= @@ -1142,8 +1123,6 @@ github.com/creachadair/atomicfile v0.3.1/go.mod h1:mwfrkRxFKwpNAflYZzytbSwxvbK6f github.com/creachadair/tomledit v0.0.24 h1:5Xjr25R2esu1rKCbQEmjZYlrhFkDspoAbAKb6QKQDhQ= github.com/creachadair/tomledit v0.0.24/go.mod h1:9qHbShRWQzSCcn617cMzg4eab1vbLCOjOshAWSzWr8U= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= -github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= @@ -1157,8 +1136,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= -github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= @@ -1173,8 +1150,6 @@ github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRk github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= -github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -1214,8 +1189,6 @@ github.com/ecies/go/v2 v2.0.9/go.mod h1:HOVvjxPPx/HilLI8q7JRZ2ZTE4WzQU/RVvhUKPG3 github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= -github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/emicklei/dot v1.6.1 h1:ujpDlBkkwgWUY+qPId5IwapRW/xEoligRSYjioR6DFI= github.com/emicklei/dot v1.6.1/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -1246,8 +1219,6 @@ github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbL github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84abZexQmTgenWk0= github.com/ethereum/go-ethereum v1.14.6 h1:ZTxnErSopkDyxdvB8zW/KcK+/AVrdil/TzoWXVKaaC8= github.com/ethereum/go-ethereum v1.14.6/go.mod h1:hglUZo/5pVIYXNyYjWzsAUDpT/zI+WbWo/Nih7ot+G0= -github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= -github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -1262,14 +1233,10 @@ github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6Ytix github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= -github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= -github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= @@ -1280,8 +1247,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= -github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= @@ -1344,15 +1309,11 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-webauthn/webauthn v0.11.2 h1:Fgx0/wlmkClTKlnOsdOQ+K5HcHDsDcYIvtYmfhEOSUc= github.com/go-webauthn/webauthn v0.11.2/go.mod h1:aOtudaF94pM71g3jRwTYYwQTG1KyTILTcZqN1srkmD0= github.com/go-webauthn/x v0.1.14 h1:1wrB8jzXAofojJPAaRxnZhRgagvLGnLjhCAwg3kTpT0= github.com/go-webauthn/x v0.1.14/go.mod h1:UuVvFZ8/NbOnkDz3y1NaxtUN87pmtpC1PQ+/5BBQRdc= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -1362,8 +1323,6 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= @@ -1472,8 +1431,6 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -1499,8 +1456,6 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= @@ -1546,8 +1501,6 @@ github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7 github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= -github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= @@ -1567,8 +1520,6 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= @@ -1577,7 +1528,6 @@ github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtX github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= github.com/hashicorp/consul/sdk v0.14.1/go.mod h1:vFt03juSzocLRFo59NkeQHHmQa6+g7oU0pfzdI1mUhg= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -1598,7 +1548,6 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y= github.com/hashicorp/go-plugin v1.5.2/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= @@ -1648,7 +1597,6 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= @@ -1678,112 +1626,17 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y 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/ipfs-shipyard/nopfs v0.0.12 h1:mvwaoefDF5VI9jyvgWCmaoTJIJFAfrbyQV5fJz35hlk= -github.com/ipfs-shipyard/nopfs v0.0.12/go.mod h1:mQyd0BElYI2gB/kq/Oue97obP4B3os4eBmgfPZ+hnrE= -github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7UynTbtdlt+w08ggb1UGLGaGjp1mMaZhoTZSctpn5Ak= -github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= -github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= -github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= github.com/ipfs/boxo v0.24.0 h1:D9gTU3QdxyjPMlJ6QfqhHTG3TIJPplKzjXLO2J30h9U= github.com/ipfs/boxo v0.24.0/go.mod h1:iP7xUPpHq2QAmVAjwtQvsNBTxTwLpFuy6ZpiRFwmzDA= -github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= -github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= -github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= -github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= -github.com/ipfs/go-blockservice v0.5.2 h1:in9Bc+QcXwd1apOVM7Un9t8tixPKdaHQFdLSUM1Xgk8= -github.com/ipfs/go-blockservice v0.5.2/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= -github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= -github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= -github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= -github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= -github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= -github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= -github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ds-badger v0.3.0 h1:xREL3V0EH9S219kFFueOYJJTcjgNSZ2HY1iSvN7U1Ro= -github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= -github.com/ipfs/go-ds-flatfs v0.5.1 h1:ZCIO/kQOS/PSh3vcF1H6a8fkRGS7pOfwfPdx4n/KJH4= -github.com/ipfs/go-ds-flatfs v0.5.1/go.mod h1:RWTV7oZD/yZYBKdbVIFXTX2fdY2Tbvl94NsWqmoyAX4= -github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUNumo= -github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= -github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjApYyQ= -github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= -github.com/ipfs/go-ds-pebble v0.4.0 h1:88lgFAs2ck8jCQ8lMYRBtksEg18r9BlvTxIMnNJkZaQ= -github.com/ipfs/go-ds-pebble v0.4.0/go.mod h1:ZyYU+weIni+4NG/Yjva+cPkU3ghlsU1HA2R/VLHJ9sM= -github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= -github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ= -github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= -github.com/ipfs/go-ipfs-cmds v0.13.0 h1:+WVHZMrQNkPqwAQdrSFGbJgHpOc8H2G8eszNxnvoCQA= -github.com/ipfs/go-ipfs-cmds v0.13.0/go.mod h1:GYqjGSt6u9k9tyxIDT7M0ROWeB2raPGH94uuVnpWgY0= -github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= -github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw= -github.com/ipfs/go-ipfs-ds-help v1.1.1/go.mod h1:75vrVCkSdSFidJscs8n4W+77AtTpCIAdDGAwjitJMIo= -github.com/ipfs/go-ipfs-exchange-interface v0.2.1 h1:jMzo2VhLKSHbVe+mHNzYgs95n0+t0Q69GQ5WhRDZV/s= -github.com/ipfs/go-ipfs-exchange-interface v0.2.1/go.mod h1:MUsYn6rKbG6CTtsDp+lKJPmVt3ZrCViNyH3rfPGsZ2E= -github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= -github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= -github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= -github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= -github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= -github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= -github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= -github.com/ipfs/go-ipld-cbor v0.2.0 h1:VHIW3HVIjcMd8m4ZLZbrYpwjzqlVUfjLM7oK4T5/YF0= -github.com/ipfs/go-ipld-cbor v0.2.0/go.mod h1:Cp8T7w1NKcu4AQJLqK0tWpd1nkgTxEVB5C6kVpLW6/0= -github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= -github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= -github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= -github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= -github.com/ipfs/go-ipld-legacy v0.2.1 h1:mDFtrBpmU7b//LzLSypVrXsD8QxkEWxu5qVxN99/+tk= -github.com/ipfs/go-ipld-legacy v0.2.1/go.mod h1:782MOUghNzMO2DER0FlBR94mllfdCJCkTtDtPM51otM= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= -github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= -github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipfs/go-merkledag v0.11.0 h1:DgzwK5hprESOzS4O1t/wi6JDpyVQdvm9Bs59N/jqfBY= -github.com/ipfs/go-merkledag v0.11.0/go.mod h1:Q4f/1ezvBiJV0YCIXvt51W/9/kqJGH4I1LsA7+djsM4= -github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= -github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= -github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= -github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= -github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= -github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= -github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.1 h1:2cdSIDQCt7emNhlyUqUFQnKo2XvecARoIcurIKFjPD8= -github.com/ipfs/go-unixfsnode v1.9.1/go.mod h1:u8WxhmXzyrq3xfSYkhfx+uI+n91O+0L7KFjq3TS7d6g= -github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= -github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= -github.com/ipfs/kubo v0.31.0 h1:as8MrXyYN0G6YfcipeTmiJaiUNvJLlAsgQ/KIwo8SEY= -github.com/ipfs/kubo v0.31.0/go.mod h1:7rsi1jvjqjFVxccKAtNf9c/lwk2GbR1p9PaKwQ/HoyA= -github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= -github.com/ipld/go-car v0.6.2/go.mod h1:oEGXdwp6bmxJCZ+rARSkDliTeYnVzv3++eXajZ+Bmr8= -github.com/ipld/go-car/v2 v2.14.2 h1:9ERr7KXpCC7If0rChZLhYDlyr6Bes6yRKPJnCO3hdHY= -github.com/ipld/go-car/v2 v2.14.2/go.mod h1:0iPB/825lTZLU2zPK5bVTk/R3V2612E1VI279OGSXWA= -github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= -github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= -github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= -github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= -github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= -github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= -github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= @@ -1806,7 +1659,6 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm 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 h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= @@ -1849,12 +1701,9 @@ github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY 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/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= -github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 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.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -1881,51 +1730,15 @@ github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+0S7FQqw= -github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= -github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= -github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.7.0 h1:4a0TMjrWNTZlNvcqxZmrMRDi/NQWrhwO2pkTuLSQ/IQ= github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-kad-dht v0.26.1 h1:AazV3LCImYVkDUGAHx5lIEgZ9iUI2QQKH5GMRQU8uEA= -github.com/libp2p/go-libp2p-kad-dht v0.26.1/go.mod h1:mqRUGJ/+7ziQ3XknU2kKHfsbbgb9xL65DXjPOJwmZF8= -github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= -github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= -github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= -github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= -github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= -github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= -github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.4 h1:6LqS1Bzn5CfDJ4tzvP9uwh42IB7TJLNFJA6dEeGBv84= -github.com/libp2p/go-libp2p-routing-helpers v0.7.4/go.mod h1:we5WDj9tbolBXOuF1hGOkR+r7Uh1408tQbAKaT5n1LE= -github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= -github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= -github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= -github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= -github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= -github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= -github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= -github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= -github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= -github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= -github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= -github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= -github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= github.com/linxGnu/grocksdb v1.8.14/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= @@ -1940,8 +1753,6 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= -github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= 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= @@ -1961,7 +1772,6 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -1992,12 +1802,6 @@ github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQ github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= -github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= -github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= -github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= @@ -2057,10 +1861,6 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= -github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU= -github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc= -github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= -github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= @@ -2070,8 +1870,6 @@ github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUj github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= -github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= @@ -2109,8 +1907,6 @@ github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1ls github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= -github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 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= @@ -2122,29 +1918,19 @@ github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/ github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= -github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= 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/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= -github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= -github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= -github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= 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/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= @@ -2158,38 +1944,6 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= -github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= -github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= -github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= -github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= -github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= -github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= -github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= -github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= -github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= -github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= -github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= -github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= -github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= -github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= -github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= -github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= -github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= -github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= -github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= -github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= -github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= -github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= -github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= -github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -2203,8 +1957,6 @@ github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUI github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= -github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= @@ -2231,14 +1983,6 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= -github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= -github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= -github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= -github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= -github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= @@ -2272,7 +2016,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= -github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.15.0/go.mod h1:5rwNNax6Mlk9sZ40AcyVtiEw24Z4J04cfSioF2COKmc= @@ -2281,8 +2024,6 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= -github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= @@ -2301,11 +2042,7 @@ github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= -github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= -github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= @@ -2386,14 +2123,11 @@ github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:s github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ucan-wg/go-ucan v0.7.0 h1:88A6rbd222Bi1zO6vANvQwDveBnpcUArdjVL0sdwr0w= github.com/ucan-wg/go-ucan v0.7.0/go.mod h1:e6jS6eb29JevZ8Pb3DpwPXYHqQai87ohwcIfQkEgM1Y= -github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ= -github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= 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/urfave/cli/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= @@ -2411,25 +2145,7 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= -github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= -github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= -github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.1.2 h1:WQFlrPhpcQl+M2/3dP5cvlTLWPVsL6LGBb9jJt6l/cA= -github.com/whyrusleeping/cbor-gen v0.1.2/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= -github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= -github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= -github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= -github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -2476,16 +2192,6 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFbtXp+21lkXgI0QE5avTWA2HjU9/WE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= -go.opentelemetry.io/otel/exporters/zipkin v1.27.0 h1:aXcxb7F6ZDC1o2Z52LDfS2g6M2FB5CrxdR2gzY4QRNs= -go.opentelemetry.io/otel/exporters/zipkin v1.27.0/go.mod h1:+WMURoi4KmVB7ypbFPx3xtZTWen2Ca3lRK9u6DVTO5M= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= @@ -2495,48 +2201,27 @@ go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVf go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= -go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= -go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= -go4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -2642,8 +2327,6 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= @@ -2992,8 +2675,6 @@ golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/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= @@ -3049,8 +2730,6 @@ golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= @@ -3067,8 +2746,6 @@ gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= -gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= -gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= 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= @@ -3420,8 +3097,6 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 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= diff --git a/x/dwn/client/cli/tx.go b/x/dwn/client/cli/tx.go index 3e7706d59..b4bb79e37 100644 --- a/x/dwn/client/cli/tx.go +++ b/x/dwn/client/cli/tx.go @@ -1,8 +1,6 @@ package cli import ( - "strconv" - "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" @@ -46,16 +44,9 @@ func MsgUpdateParams() *cobra.Command { senderAddress := cliCtx.GetFromAddress() - someValue, err := strconv.ParseBool(args[0]) - if err != nil { - return err - } - msg := &types.MsgUpdateParams{ Authority: senderAddress.String(), - Params: types.Params{ - SomeValue: someValue, - }, + Params: types.Params{}, } if err := msg.Validate(); err != nil { diff --git a/x/svc/client/cli/tx.go b/x/svc/client/cli/tx.go index 14fbb4670..f389a8d5c 100644 --- a/x/svc/client/cli/tx.go +++ b/x/svc/client/cli/tx.go @@ -1,8 +1,6 @@ package cli import ( - "strconv" - "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" @@ -46,16 +44,9 @@ func MsgUpdateParams() *cobra.Command { senderAddress := cliCtx.GetFromAddress() - someValue, err := strconv.ParseBool(args[0]) - if err != nil { - return err - } - msg := &types.MsgUpdateParams{ Authority: senderAddress.String(), - Params: types.Params{ - SomeValue: someValue, - }, + Params: types.Params{}, } if err := msg.Validate(); err != nil { From d9815cc96c8da7d930bc3a24f7f94748dd0d6725 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 15:54:05 -0500 Subject: [PATCH 10/30] refactor: remove dependency on DWN.pkl --- pkg/services/ipfsapi/ipfsapi.go | 1 + pkg/services/ipfsget/ipfsget.go | 1 + pkl/base.types/Ctx.pkl | 1 - pkl/pkl.exts/PklProject | 22 ++ .../PklProject.deps.json | 0 pkl/pkl.exts/json.pkl | 0 pkl/{chain.sonr => sonr.chain}/App.pkl | 0 pkl/{chain.sonr => sonr.chain}/Chain.pkl | 0 pkl/{chain.sonr => sonr.chain}/Genesis.pkl | 0 pkl/{chain.sonr => sonr.chain}/PklProject | 0 pkl/sonr.chain/PklProject.deps.json | 4 + pkl/sonr.dwn/ORM.pkl | 275 ++++++++++++++++++ pkl/sonr.dwn/PklProject | 22 ++ pkl/sonr.dwn/PklProject.deps.json | 4 + 14 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 pkg/services/ipfsapi/ipfsapi.go create mode 100644 pkg/services/ipfsget/ipfsget.go create mode 100644 pkl/pkl.exts/PklProject rename pkl/{chain.sonr => pkl.exts}/PklProject.deps.json (100%) create mode 100644 pkl/pkl.exts/json.pkl rename pkl/{chain.sonr => sonr.chain}/App.pkl (100%) rename pkl/{chain.sonr => sonr.chain}/Chain.pkl (100%) rename pkl/{chain.sonr => sonr.chain}/Genesis.pkl (100%) rename pkl/{chain.sonr => sonr.chain}/PklProject (100%) create mode 100644 pkl/sonr.chain/PklProject.deps.json create mode 100644 pkl/sonr.dwn/ORM.pkl create mode 100644 pkl/sonr.dwn/PklProject create mode 100644 pkl/sonr.dwn/PklProject.deps.json diff --git a/pkg/services/ipfsapi/ipfsapi.go b/pkg/services/ipfsapi/ipfsapi.go new file mode 100644 index 000000000..f017ba8b8 --- /dev/null +++ b/pkg/services/ipfsapi/ipfsapi.go @@ -0,0 +1 @@ +package ipfsapi diff --git a/pkg/services/ipfsget/ipfsget.go b/pkg/services/ipfsget/ipfsget.go new file mode 100644 index 000000000..c77e53a5d --- /dev/null +++ b/pkg/services/ipfsget/ipfsget.go @@ -0,0 +1 @@ +package ipfsget diff --git a/pkl/base.types/Ctx.pkl b/pkl/base.types/Ctx.pkl index 9feef81b7..8d199db56 100644 --- a/pkl/base.types/Ctx.pkl +++ b/pkl/base.types/Ctx.pkl @@ -3,7 +3,6 @@ module common.types.Ctx import "package://pkg.pkl-lang.org/pkl-go/pkl.golang@0.5.0#/go.pkl" -import "./DWN.pkl" class JsonField extends go.Field { structTags { diff --git a/pkl/pkl.exts/PklProject b/pkl/pkl.exts/PklProject new file mode 100644 index 000000000..23bb2d48e --- /dev/null +++ b/pkl/pkl.exts/PklProject @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//===----------------------------------------------------------------------===// +/// Configuration files for integrating the Matrix service +amends "../basePklProject.pkl" + +package { + name = "net.matrix" + version = "0.0.1" +} diff --git a/pkl/chain.sonr/PklProject.deps.json b/pkl/pkl.exts/PklProject.deps.json similarity index 100% rename from pkl/chain.sonr/PklProject.deps.json rename to pkl/pkl.exts/PklProject.deps.json diff --git a/pkl/pkl.exts/json.pkl b/pkl/pkl.exts/json.pkl new file mode 100644 index 000000000..e69de29bb diff --git a/pkl/chain.sonr/App.pkl b/pkl/sonr.chain/App.pkl similarity index 100% rename from pkl/chain.sonr/App.pkl rename to pkl/sonr.chain/App.pkl diff --git a/pkl/chain.sonr/Chain.pkl b/pkl/sonr.chain/Chain.pkl similarity index 100% rename from pkl/chain.sonr/Chain.pkl rename to pkl/sonr.chain/Chain.pkl diff --git a/pkl/chain.sonr/Genesis.pkl b/pkl/sonr.chain/Genesis.pkl similarity index 100% rename from pkl/chain.sonr/Genesis.pkl rename to pkl/sonr.chain/Genesis.pkl diff --git a/pkl/chain.sonr/PklProject b/pkl/sonr.chain/PklProject similarity index 100% rename from pkl/chain.sonr/PklProject rename to pkl/sonr.chain/PklProject diff --git a/pkl/sonr.chain/PklProject.deps.json b/pkl/sonr.chain/PklProject.deps.json new file mode 100644 index 000000000..836079aad --- /dev/null +++ b/pkl/sonr.chain/PklProject.deps.json @@ -0,0 +1,4 @@ +{ + "schemaVersion": 1, + "resolvedDependencies": {} +} \ No newline at end of file diff --git a/pkl/sonr.dwn/ORM.pkl b/pkl/sonr.dwn/ORM.pkl new file mode 100644 index 000000000..d6a59b1b5 --- /dev/null +++ b/pkl/sonr.dwn/ORM.pkl @@ -0,0 +1,275 @@ +@go.Package { name = "github.com/onsonr/sonr/pkg/common/models" } + +module common.types.ORM + +import "package://pkg.pkl-lang.org/pkl-go/pkl.golang@0.5.0#/go.pkl" + + +// Enums +typealias AssetType = "native"|"wrapped"|"staking"|"pool"|"ibc"|"cw20" + +typealias DIDMethod = "ipfs"|"sonr"|"bitcoin"|"ethereum"|"ibc"|"webauthn"|"dwn"|"service" + +typealias KeyAlgorithm = "es256"|"es384"|"es512"|"eddsa"|"es256k"|"ecdsa" + +typealias KeyCurve = "p256"|"p384"|"p521"|"x25519"|"x448"|"ed25519"|"ed448"|"secp256k1"|"bls12381"|"keccak256" + +typealias KeyEncoding = "raw"|"hex"|"multibase" + +typealias KeyRole = "authentication"|"assertion"|"delegation"|"invocation" + +typealias KeyType = "octet"|"elliptic"|"rsa"|"symmetric"|"hmac"|"mpc"|"zk"|"webauthn"|"bip32" + +typealias KeyShareRole = "user"|"validator" + +typealias PermissionGrant = "none"|"read"|"write"|"verify"|"broadcast"|"admin" + +typealias PermissionScope = "profile"|"metadata"|"permissions"|"wallets"|"transactions"|"user"|"validator" + +typealias Base58 = String +typealias Base64 = String + +typealias Bech32 = String +typealias Keccak = String + +typealias ChainCode = UInt +typealias Scope = String + +typealias Hex = String + +class PrimaryKey extends go.Field { + structTags { + ["json"] = "%{name},omitempty" + ["query"] = "%{name}" + } +} + +class JsonField extends go.Field { + structTags { + ["json"] = "%{name},omitempty" + } +} + + +class Account { + @PrimaryKey + id: String + + @JsonField + name: String + + @JsonField + address: Bech32|Keccak|String + + @JsonField + publicKey: Base58 + + @JsonField + chainCode: ChainCode + + @JsonField + index: Int + + @JsonField + controller: Bech32 + + @JsonField + createdAt: String? +} + +class Asset { + @PrimaryKey + id: String + + @JsonField + name: String + + @JsonField + symbol: String + + @JsonField + decimals: Int + + @JsonField + chainCode: ChainCode + + @JsonField + createdAt: String? +} + +class Chain { + @PrimaryKey + id: String + + @JsonField + name: String + + @JsonField + networkId: String + + @JsonField + chainCode: ChainCode + + @JsonField + createdAt: String? +} + +class Credential { + @PrimaryKey + id: String + + @JsonField + subject: String + + @JsonField + controller: Bech32 + + @JsonField + attestationType: String + + @JsonField + origin: String + + @JsonField + label: String? + + @JsonField + deviceId: String? + + @JsonField + credentialId: Base64 + + @JsonField + publicKey: Base64 + + @JsonField + transport: List + + @JsonField + signCount: UInt + + @JsonField + userPresent: Boolean + + @JsonField + userVerified: Boolean + + @JsonField + backupEligible: Boolean + + @JsonField + backupState: Boolean + + @JsonField + cloneWarning: Boolean + + @JsonField + createdAt: String? + + @JsonField + updatedAt: String? +} + +class DID { + @PrimaryKey + id: String + role: KeyRole + algorithm: KeyAlgorithm + encoding: KeyEncoding + curve: KeyCurve + key_type: KeyType + raw: Base64 + jwk: JWK +} + +class JWK { + @JsonField + kty: String + + @JsonField + crv: String + + @JsonField + x: String + + @JsonField + y: String + + @JsonField + n: String + + @JsonField + e: String +} + +class Grant { + @PrimaryKey + id: UInt + + @JsonField + subject: String + + @JsonField + controller: Bech32 + + @JsonField + origin: String + + @JsonField + token: String + + @JsonField + scopes: List + + @JsonField + createdAt: String? + + @JsonField + updatedAt: String? +} + +class Keyshare { + @PrimaryKey + id: String + + @JsonField + data: Base64 + + @JsonField + role: Int + + @JsonField + createdAt: String? + + @JsonField + lastRefreshed: String? +} + +class Profile { + @PrimaryKey + id: String + + @JsonField + subject: String + + @JsonField + controller: Bech32 + + @JsonField + originUri: String? + + @JsonField + publicMetadata: String? + + @JsonField + privateMetadata: String? + + @JsonField + createdAt: String? + + @JsonField + updatedAt: String? +} + +db_name: String = "vault" +db_version: Int = 1 diff --git a/pkl/sonr.dwn/PklProject b/pkl/sonr.dwn/PklProject new file mode 100644 index 000000000..f5363cc8e --- /dev/null +++ b/pkl/sonr.dwn/PklProject @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//===----------------------------------------------------------------------===// +/// Common types for operations across the sonr ecosystem +amends "../basePklProject.pkl" + +package { + name = "base.types" + version = "0.0.1" +} diff --git a/pkl/sonr.dwn/PklProject.deps.json b/pkl/sonr.dwn/PklProject.deps.json new file mode 100644 index 000000000..836079aad --- /dev/null +++ b/pkl/sonr.dwn/PklProject.deps.json @@ -0,0 +1,4 @@ +{ + "schemaVersion": 1, + "resolvedDependencies": {} +} \ No newline at end of file From 6a761c05e6de85b148715c32d190cc6a2cb14e14 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 15:56:54 -0500 Subject: [PATCH 11/30] refactor: Move IPFS interaction functions to common package --- pkg/{services => common}/ipfsapi/ipfsapi.go | 0 pkg/{services => common}/ipfsget/ipfsget.go | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename pkg/{services => common}/ipfsapi/ipfsapi.go (100%) rename pkg/{services => common}/ipfsget/ipfsget.go (100%) diff --git a/pkg/services/ipfsapi/ipfsapi.go b/pkg/common/ipfsapi/ipfsapi.go similarity index 100% rename from pkg/services/ipfsapi/ipfsapi.go rename to pkg/common/ipfsapi/ipfsapi.go diff --git a/pkg/services/ipfsget/ipfsget.go b/pkg/common/ipfsget/ipfsget.go similarity index 100% rename from pkg/services/ipfsget/ipfsget.go rename to pkg/common/ipfsget/ipfsget.go From e4c21e8552ac57c33e60253cebe53cc74c8236f5 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 16:03:29 -0500 Subject: [PATCH 12/30] refactor: remove unused TUI components --- app/cli/dexmodel/dexmodel.go | 165 ------------------ app/cli/tui.go | 44 ----- app/cli/txmodel/txmodel.go | 322 ----------------------------------- cmd/sonrd/main.go | 3 - 4 files changed, 534 deletions(-) delete mode 100644 app/cli/dexmodel/dexmodel.go delete mode 100644 app/cli/tui.go delete mode 100644 app/cli/txmodel/txmodel.go diff --git a/app/cli/dexmodel/dexmodel.go b/app/cli/dexmodel/dexmodel.go deleted file mode 100644 index c6a77a8d8..000000000 --- a/app/cli/dexmodel/dexmodel.go +++ /dev/null @@ -1,165 +0,0 @@ -package dexmodel - -import ( - "fmt" - "time" - - "github.com/charmbracelet/bubbles/table" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/spf13/cobra" -) - -var ( - subtle = lipgloss.AdaptiveColor{Light: "#D9DCCF", Dark: "#383838"} - highlight = lipgloss.AdaptiveColor{Light: "#874BFD", Dark: "#7D56F4"} - special = lipgloss.AdaptiveColor{Light: "#43BF6D", Dark: "#73F59F"} - - titleStyle = lipgloss.NewStyle(). - MarginLeft(1). - MarginRight(5). - Padding(0, 1). - Italic(true). - Foreground(lipgloss.Color("#FFF7DB")). - SetString("Cosmos Block Explorer") - - infoStyle = lipgloss.NewStyle(). - BorderStyle(lipgloss.NormalBorder()). - BorderTop(true). - BorderForeground(subtle) -) - -type model struct { - blocks []string - transactionTable table.Model - stats map[string]string - width int - height int -} - -func initialModel() model { - columns := []table.Column{ - {Title: "Hash", Width: 10}, - {Title: "Type", Width: 15}, - {Title: "Height", Width: 10}, - {Title: "Time", Width: 20}, - } - - rows := []table.Row{ - {"abc123", "Transfer", "1000", time.Now().Format(time.RFC3339)}, - {"def456", "Delegate", "999", time.Now().Add(-1 * time.Minute).Format(time.RFC3339)}, - {"ghi789", "Vote", "998", time.Now().Add(-2 * time.Minute).Format(time.RFC3339)}, - } - - t := table.New( - table.WithColumns(columns), - table.WithRows(rows), - table.WithFocused(true), - table.WithHeight(7), - ) - - s := table.DefaultStyles() - s.Header = s.Header. - BorderStyle(lipgloss.NormalBorder()). - BorderForeground(lipgloss.Color("240")). - BorderBottom(true). - Bold(false) - s.Selected = s.Selected. - Foreground(lipgloss.Color("229")). - Background(lipgloss.Color("57")). - Bold(false) - t.SetStyles(s) - - return model{ - blocks: []string{"Block 1", "Block 2", "Block 3"}, - transactionTable: t, - stats: map[string]string{ - "Latest Block": "1000", - "Validators": "100", - "Bonded Tokens": "1,000,000", - }, - } -} - -func (m model) Init() tea.Cmd { - return tick -} - -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmd tea.Cmd - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "q", "ctrl+c": - return m, tea.Quit - case "enter": - return m, tea.Batch( - tea.Printf("Selected transaction: %s", m.transactionTable.SelectedRow()[0]), - ) - } - case tea.WindowSizeMsg: - m.height = msg.Height - m.width = msg.Width - case tickMsg: - // Update data here - m.blocks = append([]string{"New Block"}, m.blocks...) - if len(m.blocks) > 5 { - m.blocks = m.blocks[:5] - } - - // Add a new transaction to the table - newRow := table.Row{ - fmt.Sprintf("tx%d", time.Now().Unix()), - "NewTxType", - fmt.Sprintf("%d", 1000+len(m.transactionTable.Rows())), - time.Now().Format(time.RFC3339), - } - m.transactionTable.SetRows(append([]table.Row{newRow}, m.transactionTable.Rows()...)) - if len(m.transactionTable.Rows()) > 10 { - m.transactionTable.SetRows(m.transactionTable.Rows()[:10]) - } - - return m, tick - } - m.transactionTable, cmd = m.transactionTable.Update(msg) - return m, cmd -} - -func (m model) View() string { - s := titleStyle.Render("Cosmos Block Explorer") - s += "\n\n" - - // Blocks - s += lipgloss.NewStyle().Bold(true).Render("Recent Blocks") + "\n" - for _, block := range m.blocks { - s += "• " + block + "\n" - } - s += "\n" - - // Transactions - s += lipgloss.NewStyle().Bold(true).Render("Recent Transactions") + "\n" - s += m.transactionTable.View() + "\n\n" - - // Stats - s += lipgloss.NewStyle().Bold(true).Render("Network Statistics") + "\n" - for key, value := range m.stats { - s += fmt.Sprintf("%s: %s\n", key, value) - } - - return s -} - -type tickMsg time.Time - -func tick() tea.Msg { - time.Sleep(time.Second) - return tickMsg{} -} - -func RunExplorerTUI(cmd *cobra.Command, args []string) error { - p := tea.NewProgram(initialModel(), tea.WithAltScreen()) - if _, err := p.Run(); err != nil { - return fmt.Errorf("error running explorer: %v", err) - } - return nil -} diff --git a/app/cli/tui.go b/app/cli/tui.go deleted file mode 100644 index b5305baff..000000000 --- a/app/cli/tui.go +++ /dev/null @@ -1,44 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/onsonr/sonr/app/cli/dexmodel" - "github.com/onsonr/sonr/app/cli/txmodel" - "github.com/spf13/cobra" -) - -func NewBuildTxnTUICmd() *cobra.Command { - return &cobra.Command{ - Use: "dash", - Short: "TUI for managing the local Sonr validator node", - RunE: func(cmd *cobra.Command, args []string) error { - txBody, err := txmodel.RunBuildTxnTUI() - if err != nil { - return err - } - - interfaceRegistry := codectypes.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - jsonBytes, err := marshaler.MarshalJSON(txBody) - if err != nil { - return fmt.Errorf("failed to marshal tx body: %w", err) - } - - fmt.Println("Generated Protobuf Message (JSON format):") - fmt.Println(string(jsonBytes)) - - return nil - }, - } -} - -func NewExplorerTUICmd() *cobra.Command { - return &cobra.Command{ - Use: "cosmos-explorer", - Short: "A terminal-based Cosmos blockchain explorer", - RunE: dexmodel.RunExplorerTUI, - } -} diff --git a/app/cli/txmodel/txmodel.go b/app/cli/txmodel/txmodel.go deleted file mode 100644 index 4c493ad24..000000000 --- a/app/cli/txmodel/txmodel.go +++ /dev/null @@ -1,322 +0,0 @@ -package txmodel - -import ( - "fmt" - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/huh" - "github.com/charmbracelet/lipgloss" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/tx" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -) - -const maxWidth = 100 - -var ( - red = lipgloss.AdaptiveColor{Light: "#FE5F86", Dark: "#FE5F86"} - indigo = lipgloss.AdaptiveColor{Light: "#5A56E0", Dark: "#7571F9"} - green = lipgloss.AdaptiveColor{Light: "#02BA84", Dark: "#02BF87"} -) - -type Styles struct { - Base, - HeaderText, - Status, - StatusHeader, - Highlight, - ErrorHeaderText, - Help lipgloss.Style -} - -func NewStyles(lg *lipgloss.Renderer) *Styles { - s := Styles{} - s.Base = lg.NewStyle(). - Padding(1, 2, 0, 1) - s.HeaderText = lg.NewStyle(). - Foreground(indigo). - Bold(true). - Padding(0, 1, 0, 1) - s.Status = lg.NewStyle(). - Border(lipgloss.RoundedBorder()). - BorderForeground(indigo). - PaddingLeft(1). - MarginTop(1) - s.StatusHeader = lg.NewStyle(). - Foreground(green). - Bold(true) - s.Highlight = lg.NewStyle(). - Foreground(lipgloss.Color("212")) - s.ErrorHeaderText = s.HeaderText. - Foreground(red) - s.Help = lg.NewStyle(). - Foreground(lipgloss.Color("240")) - return &s -} - -type state int - -const ( - statusNormal state = iota - stateDone -) - -type Model struct { - state state - lg *lipgloss.Renderer - styles *Styles - form *huh.Form - width int - message *tx.TxBody -} - -func NewModel() Model { - m := Model{width: maxWidth} - m.lg = lipgloss.DefaultRenderer() - m.styles = NewStyles(m.lg) - - m.form = huh.NewForm( - huh.NewGroup( - huh.NewInput(). - Key("from"). - Title("From Address"). - Placeholder("cosmos1..."). - Validate(func(s string) error { - if !strings.HasPrefix(s, "cosmos1") { - return fmt.Errorf("invalid address format") - } - return nil - }), - - huh.NewInput(). - Key("to"). - Title("To Address"). - Placeholder("cosmos1..."). - Validate(func(s string) error { - if !strings.HasPrefix(s, "cosmos1") { - return fmt.Errorf("invalid address format") - } - return nil - }), - - huh.NewInput(). - Key("amount"). - Title("Amount"). - Placeholder("100"). - Validate(func(s string) error { - if _, err := sdk.ParseCoinNormalized(s + "atom"); err != nil { - return fmt.Errorf("invalid coin amount") - } - return nil - }), - - huh.NewSelect[string](). - Key("denom"). - Title("Denom"). - Options(huh.NewOptions("atom", "osmo", "usnr", "snr")...), - - huh.NewInput(). - Key("memo"). - Title("Memo"). - Placeholder("Optional"), - - huh.NewConfirm(). - Key("done"). - Title("Ready to convert?"). - Validate(func(v bool) error { - if !v { - return fmt.Errorf("Please confirm when you're ready to convert") - } - return nil - }). - Affirmative("Yes, convert!"). - Negative("Not yet"), - ), - ). - WithWidth(60). - WithShowHelp(false). - WithShowErrors(false) - - return m -} - -func (m Model) Init() tea.Cmd { - return m.form.Init() -} - -func min(x, y int) int { - if x > y { - return y - } - return x -} - -func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.WindowSizeMsg: - m.width = min(msg.Width, maxWidth) - m.styles.Base.GetHorizontalFrameSize() - case tea.KeyMsg: - switch msg.String() { - case "esc", "ctrl+c", "q": - return m, tea.Quit - } - } - - var cmds []tea.Cmd - - form, cmd := m.form.Update(msg) - if f, ok := form.(*huh.Form); ok { - m.form = f - cmds = append(cmds, cmd) - } - - if m.form.State == huh.StateCompleted { - m.buildMessage() - cmds = append(cmds, tea.Quit) - } - - return m, tea.Batch(cmds...) -} - -func (m Model) View() string { - s := m.styles - - switch m.form.State { - case huh.StateCompleted: - pklCode := m.generatePkl() - messageView := m.getMessageView() - var b strings.Builder - fmt.Fprintf(&b, "Final Tx:\n\n%s\n\n%s", pklCode, messageView) - return s.Status.Margin(0, 1).Padding(1, 2).Width(80).Render(b.String()) + "\n\n" - default: - var schemaType string - if m.form.GetString("schemaType") != "" { - schemaType = "Schema Type: " + m.form.GetString("schemaType") - } - - v := strings.TrimSuffix(m.form.View(), "\n\n") - form := m.lg.NewStyle().Margin(1, 0).Render(v) - - var status string - { - preview := "(Preview will appear here)" - if m.form.GetString("schema") != "" { - preview = m.generatePkl() - } - - const statusWidth = 40 - statusMarginLeft := m.width - statusWidth - lipgloss.Width(form) - s.Status.GetMarginRight() - status = s.Status. - Height(lipgloss.Height(form)). - Width(statusWidth). - MarginLeft(statusMarginLeft). - Render(s.StatusHeader.Render("Pkl Preview") + "\n" + - schemaType + "\n\n" + - preview) - } - - errors := m.form.Errors() - header := m.appBoundaryView("Sonr TX Builder") - if len(errors) > 0 { - header = m.appErrorBoundaryView(m.errorView()) - } - body := lipgloss.JoinHorizontal(lipgloss.Top, form, status) - - footer := m.appBoundaryView(m.form.Help().ShortHelpView(m.form.KeyBinds())) - if len(errors) > 0 { - footer = m.appErrorBoundaryView("") - } - - return s.Base.Render(header + "\n" + body + "\n\n" + footer) - } -} - -func (m Model) errorView() string { - var s string - for _, err := range m.form.Errors() { - s += err.Error() - } - return s -} - -func (m Model) appBoundaryView(text string) string { - return lipgloss.PlaceHorizontal( - m.width, - lipgloss.Left, - m.styles.HeaderText.Render(text), - lipgloss.WithWhitespaceChars("="), - lipgloss.WithWhitespaceForeground(indigo), - ) -} - -func (m Model) appErrorBoundaryView(text string) string { - return lipgloss.PlaceHorizontal( - m.width, - lipgloss.Left, - m.styles.ErrorHeaderText.Render(text), - lipgloss.WithWhitespaceChars("="), - lipgloss.WithWhitespaceForeground(red), - ) -} - -func (m Model) generatePkl() string { - schemaType := m.form.GetString("schemaType") - schema := m.form.GetString("schema") - - // This is a placeholder for the actual conversion logic - // In a real implementation, you would parse the schema and generate Pkl code - return fmt.Sprintf("// Converted from %s\n\nclass ConvertedSchema {\n // TODO: Implement conversion from %s\n // Original schema:\n /*\n%s\n */\n}", schemaType, schemaType, schema) -} - -func (m *Model) buildMessage() { - from := m.form.GetString("from") - to := m.form.GetString("to") - amount := m.form.GetString("amount") - denom := m.form.GetString("denom") - memo := m.form.GetString("memo") - - coin, _ := sdk.ParseCoinNormalized(fmt.Sprintf("%s%s", amount, denom)) - sendMsg := &banktypes.MsgSend{ - FromAddress: from, - ToAddress: to, - Amount: sdk.NewCoins(coin), - } - - anyMsg, _ := codectypes.NewAnyWithValue(sendMsg) - m.message = &tx.TxBody{ - Messages: []*codectypes.Any{anyMsg}, - Memo: memo, - } -} - -func (m Model) getMessageView() string { - if m.message == nil { - return "Current Message: None" - } - - interfaceRegistry := codectypes.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - jsonBytes, _ := marshaler.MarshalJSON(m.message) - - return fmt.Sprintf("Current Message:\n%s", string(jsonBytes)) -} - -func RunBuildTxnTUI() (*tx.TxBody, error) { - m := NewModel() - p := tea.NewProgram(m) - - finalModel, err := p.Run() - if err != nil { - return nil, fmt.Errorf("failed to run program: %w", err) - } - - finalM, ok := finalModel.(Model) - if !ok || finalM.message == nil { - return nil, fmt.Errorf("form not completed") - } - - return finalM.message, nil -} diff --git a/cmd/sonrd/main.go b/cmd/sonrd/main.go index d3f50eab5..7080ac6d8 100644 --- a/cmd/sonrd/main.go +++ b/cmd/sonrd/main.go @@ -8,13 +8,10 @@ import ( _ "github.com/joho/godotenv/autoload" "github.com/onsonr/sonr/app" - "github.com/onsonr/sonr/app/cli" ) func main() { rootCmd := NewRootCmd() - rootCmd.AddCommand(cli.NewBuildTxnTUICmd()) - rootCmd.AddCommand(cli.NewExplorerTUICmd()) if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err) From 9e7f70c45558b7fde31e281495fb11250c7cc9e5 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 16:27:03 -0500 Subject: [PATCH 13/30] feat: add gum package and update devbox configuration --- .gitignore | 1 + devbox.json | 25 ++++++++++++++++++++----- go.mod | 19 ------------------- go.sum | 44 -------------------------------------------- 4 files changed, 21 insertions(+), 68 deletions(-) diff --git a/.gitignore b/.gitignore index 204014c97..77a37edf4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ .session.vim aof* dist +**/.haptic # Test binary *.test diff --git a/devbox.json b/devbox.json index bc31be2f9..fcc628a9c 100644 --- a/devbox.json +++ b/devbox.json @@ -1,17 +1,32 @@ { "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", - "packages": ["go@1.22", "bun@latest", "ipfs@latest", "templ@latest"], + "packages": [ + "go@1.22", + "bun@latest", + "ipfs@latest", + "templ@latest", + "gum@latest" + ], "env": { "GOPATH": "$HOME/go", "PATH": "./build:$HOME/go/bin:$PATH", "TEMPL_EXPERIMENT": "rawgo" }, "shell": { - "init_hook": ["./scripts/init_env.sh"], + "init_hook": [ + "./scripts/init_env.sh" + ], "scripts": { - "start-local": ["cd deploy/local && devbox services up"], - "start-testnet": ["cd deploy/testnet && devbox services up"], - "start-gex": ["go install github.com/cosmos/gex@latest", "gex"] + "start-local": [ + "cd deploy/local && devbox services up" + ], + "start-testnet": [ + "cd deploy/testnet && devbox services up" + ], + "start-gex": [ + "go install github.com/cosmos/gex@latest", + "gex" + ] } } } diff --git a/go.mod b/go.mod index 9107f8fb9..0328bce87 100644 --- a/go.mod +++ b/go.mod @@ -53,10 +53,6 @@ require ( github.com/apple/pkl-go v0.8.0 github.com/btcsuite/btcd/btcec/v2 v2.3.4 github.com/bwesterb/go-ristretto v1.2.3 - github.com/charmbracelet/bubbles v0.19.0 - github.com/charmbracelet/bubbletea v1.1.0 - github.com/charmbracelet/huh v0.5.3 - github.com/charmbracelet/lipgloss v0.13.0 github.com/cometbft/cometbft v0.38.12 github.com/consensys/gnark-crypto v0.12.1 github.com/cosmos/btcutil v1.0.5 @@ -112,21 +108,15 @@ require ( github.com/99designs/keyring v1.2.1 // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/DataDog/zstd v1.5.5 // indirect - github.com/atotto/clipboard v0.1.4 // indirect github.com/aws/aws-sdk-go v1.44.224 // indirect - github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd v0.20.1-beta // indirect - github.com/catppuccin/go v0.2.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/charmbracelet/x/ansi v0.2.3 // indirect - github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect - github.com/charmbracelet/x/term v0.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.11.3 // indirect @@ -154,7 +144,6 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/emicklei/dot v1.6.1 // indirect - github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -217,26 +206,19 @@ require ( github.com/libp2p/go-libp2p-core v0.7.0 // indirect github.com/libp2p/go-openssl v0.1.0 // indirect github.com/linxGnu/grocksdb v1.8.14 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-pointer v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect - github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect - github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect @@ -252,7 +234,6 @@ require ( github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.11.1 // indirect github.com/rs/zerolog v1.32.0 // indirect diff --git a/go.sum b/go.sum index d54e9b6ed..25b4a6d83 100644 --- a/go.sum +++ b/go.sum @@ -852,8 +852,6 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXY github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= -github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= -github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -903,8 +901,6 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= -github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ= github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= @@ -930,10 +926,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxq github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= -github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= -github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -972,8 +964,6 @@ github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g1 github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= -github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA= -github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -989,22 +979,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/bubbles v0.19.0 h1:gKZkKXPP6GlDk6EcfujDK19PCQqRjaJZQ7QRERx1UF0= -github.com/charmbracelet/bubbles v0.19.0/go.mod h1:WILteEqZ+krG5c3ntGEMeG99nCupcuIk7V0/zOP0tOA= -github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c= -github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4= -github.com/charmbracelet/huh v0.5.3 h1:3KLP4a/K1/S4dq4xFMTNMt3XWhgMl/yx8NYtygQ0bmg= -github.com/charmbracelet/huh v0.5.3/go.mod h1:OZC3lshuF+/y8laj//DoZdFSHxC51OrtXLJI8xWVouQ= -github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= -github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY= -github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY= -github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= -github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q= -github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= -github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4= -github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= -github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= -github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= @@ -1211,8 +1185,6 @@ github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6Ni github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= @@ -1741,8 +1713,6 @@ github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+O github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= github.com/linxGnu/grocksdb v1.8.14/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= @@ -1778,16 +1748,12 @@ github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= -github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -1820,8 +1786,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= -github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -1846,12 +1810,6 @@ github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= -github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= -github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= -github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a h1:2MaM6YC3mGu54x+RKAA6JiFFHlHDY1UbkxqppT7wYOg= -github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= @@ -1993,8 +1951,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qq github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= From 179a69df1cbfb240dc3fd222f5805fc5905b0a1a Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 26 Nov 2024 00:07:45 -0500 Subject: [PATCH 14/30] refactor: rename Assertion to Account and update related code --- Makefile | 13 +- api/did/v1/state.cosmos_orm.go | 690 +-- api/did/v1/state.pulsar.go | 2817 ++--------- api/dwn/v1/state.cosmos_orm.go | 259 +- api/dwn/v1/state.pulsar.go | 736 ++- api/service/module/v1/module.pulsar.go | 500 -- api/service/v1/genesis.pulsar.go | 3267 ------------- api/service/v1/query.pulsar.go | 997 ---- api/service/v1/query_grpc.pb.go | 127 - api/service/v1/state.cosmos_orm.go | 368 -- api/service/v1/state.pulsar.go | 1752 ------- api/service/v1/tx.pulsar.go | 2199 --------- api/service/v1/tx_grpc.pb.go | 173 - api/svc/v1/state.cosmos_orm.go | 394 +- api/svc/v1/state.pulsar.go | 590 +-- api/vault/module/v1/module.pulsar.go | 499 -- api/vault/v1/genesis.pulsar.go | 2323 --------- api/vault/v1/query.pulsar.go | 4221 ----------------- api/vault/v1/query_grpc.pb.go | 253 - api/vault/v1/state.cosmos_orm.go | 235 - api/vault/v1/state.pulsar.go | 772 --- api/vault/v1/tx.pulsar.go | 2066 -------- api/vault/v1/tx_grpc.pb.go | 171 - .../components/auth/create_credential.templ | 49 - .../auth/create_credential_templ.go | 71 - pkg/webapp/components/auth/current.templ | 30 + pkg/webapp/components/auth/current_templ.go | 69 + .../components/auth/get_credential.templ | 35 - .../components/auth/get_credential_templ.go | 71 - pkg/webapp/components/auth/register.templ | 66 +- .../components/auth/register_start.templ | 53 - .../components/auth/register_start_templ.go | 135 - pkg/webapp/components/auth/register_templ.go | 65 +- pkg/webapp/components/dash/layout.templ | 17 + pkg/webapp/components/dash/layout_templ.go | 58 + .../components/landing/highlights.templ | 28 +- .../components/landing/highlights_templ.go | 52 +- proto/did/v1/state.proto | 64 +- proto/dwn/v1/state.proto | 15 +- proto/svc/v1/state.proto | 6 +- x/did/controller/table.go | 29 +- x/did/keeper/genesis.go | 24 +- x/did/types/pubkey.go | 5 - x/did/types/state.pb.go | 1201 +---- x/dwn/keeper/orm_test.go | 31 - x/dwn/types/state.pb.go | 278 +- x/svc/types/state.pb.go | 288 +- 47 files changed, 2781 insertions(+), 25381 deletions(-) delete mode 100644 api/service/module/v1/module.pulsar.go delete mode 100644 api/service/v1/genesis.pulsar.go delete mode 100644 api/service/v1/query.pulsar.go delete mode 100644 api/service/v1/query_grpc.pb.go delete mode 100644 api/service/v1/state.cosmos_orm.go delete mode 100644 api/service/v1/state.pulsar.go delete mode 100644 api/service/v1/tx.pulsar.go delete mode 100644 api/service/v1/tx_grpc.pb.go delete mode 100644 api/vault/module/v1/module.pulsar.go delete mode 100644 api/vault/v1/genesis.pulsar.go delete mode 100644 api/vault/v1/query.pulsar.go delete mode 100644 api/vault/v1/query_grpc.pb.go delete mode 100644 api/vault/v1/state.cosmos_orm.go delete mode 100644 api/vault/v1/state.pulsar.go delete mode 100644 api/vault/v1/tx.pulsar.go delete mode 100644 api/vault/v1/tx_grpc.pb.go delete mode 100644 pkg/webapp/components/auth/create_credential.templ delete mode 100644 pkg/webapp/components/auth/create_credential_templ.go create mode 100644 pkg/webapp/components/auth/current.templ create mode 100644 pkg/webapp/components/auth/current_templ.go delete mode 100644 pkg/webapp/components/auth/get_credential.templ delete mode 100644 pkg/webapp/components/auth/get_credential_templ.go delete mode 100644 pkg/webapp/components/auth/register_start.templ delete mode 100644 pkg/webapp/components/auth/register_start_templ.go create mode 100644 pkg/webapp/components/dash/layout.templ create mode 100644 pkg/webapp/components/dash/layout_templ.go delete mode 100644 x/dwn/keeper/orm_test.go diff --git a/Makefile b/Makefile index fda10386a..b928892b8 100644 --- a/Makefile +++ b/Makefile @@ -286,10 +286,21 @@ testnet-basic: setup-testnet sh-testnet: mod-tidy CHAIN_ID="sonr-testnet-1" BLOCK_TIME="1000ms" CLEAN=true sh scripts/test_node.sh +.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet + +############################################################################### +### extras ### +############################################################################### + +.PHONY: buf-publish templ-gen + +templ-gen: + templ generate + buf-publish: cd ./proto && bunx buf dep update && bunx buf build && bunx buf push -.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet buf-publish + ############################################################################### ### help ### diff --git a/api/did/v1/state.cosmos_orm.go b/api/did/v1/state.cosmos_orm.go index 39ed930dc..11d080e04 100644 --- a/api/did/v1/state.cosmos_orm.go +++ b/api/did/v1/state.cosmos_orm.go @@ -9,121 +9,121 @@ import ( ormerrors "cosmossdk.io/orm/types/ormerrors" ) -type AssertionTable interface { - Insert(ctx context.Context, assertion *Assertion) error - Update(ctx context.Context, assertion *Assertion) error - Save(ctx context.Context, assertion *Assertion) error - Delete(ctx context.Context, assertion *Assertion) error +type AccountTable interface { + Insert(ctx context.Context, account *Account) error + Update(ctx context.Context, account *Account) error + Save(ctx context.Context, account *Account) error + Delete(ctx context.Context, account *Account) error Has(ctx context.Context, did string) (found bool, err error) // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, did string) (*Assertion, error) + Get(ctx context.Context, did string) (*Account, error) HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error) // GetByControllerSubject returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByControllerSubject(ctx context.Context, controller string, subject string) (*Assertion, error) - List(ctx context.Context, prefixKey AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error) - ListRange(ctx context.Context, from, to AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error) - DeleteBy(ctx context.Context, prefixKey AssertionIndexKey) error - DeleteRange(ctx context.Context, from, to AssertionIndexKey) error + GetByControllerSubject(ctx context.Context, controller string, subject string) (*Account, error) + List(ctx context.Context, prefixKey AccountIndexKey, opts ...ormlist.Option) (AccountIterator, error) + ListRange(ctx context.Context, from, to AccountIndexKey, opts ...ormlist.Option) (AccountIterator, error) + DeleteBy(ctx context.Context, prefixKey AccountIndexKey) error + DeleteRange(ctx context.Context, from, to AccountIndexKey) error doNotImplement() } -type AssertionIterator struct { +type AccountIterator struct { ormtable.Iterator } -func (i AssertionIterator) Value() (*Assertion, error) { - var assertion Assertion - err := i.UnmarshalMessage(&assertion) - return &assertion, err +func (i AccountIterator) Value() (*Account, error) { + var account Account + err := i.UnmarshalMessage(&account) + return &account, err } -type AssertionIndexKey interface { +type AccountIndexKey interface { id() uint32 values() []interface{} - assertionIndexKey() + accountIndexKey() } // primary key starting index.. -type AssertionPrimaryKey = AssertionDidIndexKey +type AccountPrimaryKey = AccountDidIndexKey -type AssertionDidIndexKey struct { +type AccountDidIndexKey struct { vs []interface{} } -func (x AssertionDidIndexKey) id() uint32 { return 0 } -func (x AssertionDidIndexKey) values() []interface{} { return x.vs } -func (x AssertionDidIndexKey) assertionIndexKey() {} +func (x AccountDidIndexKey) id() uint32 { return 0 } +func (x AccountDidIndexKey) values() []interface{} { return x.vs } +func (x AccountDidIndexKey) accountIndexKey() {} -func (this AssertionDidIndexKey) WithDid(did string) AssertionDidIndexKey { +func (this AccountDidIndexKey) WithDid(did string) AccountDidIndexKey { this.vs = []interface{}{did} return this } -type AssertionControllerSubjectIndexKey struct { +type AccountControllerSubjectIndexKey struct { vs []interface{} } -func (x AssertionControllerSubjectIndexKey) id() uint32 { return 1 } -func (x AssertionControllerSubjectIndexKey) values() []interface{} { return x.vs } -func (x AssertionControllerSubjectIndexKey) assertionIndexKey() {} +func (x AccountControllerSubjectIndexKey) id() uint32 { return 1 } +func (x AccountControllerSubjectIndexKey) values() []interface{} { return x.vs } +func (x AccountControllerSubjectIndexKey) accountIndexKey() {} -func (this AssertionControllerSubjectIndexKey) WithController(controller string) AssertionControllerSubjectIndexKey { +func (this AccountControllerSubjectIndexKey) WithController(controller string) AccountControllerSubjectIndexKey { this.vs = []interface{}{controller} return this } -func (this AssertionControllerSubjectIndexKey) WithControllerSubject(controller string, subject string) AssertionControllerSubjectIndexKey { +func (this AccountControllerSubjectIndexKey) WithControllerSubject(controller string, subject string) AccountControllerSubjectIndexKey { this.vs = []interface{}{controller, subject} return this } -type assertionTable struct { +type accountTable struct { table ormtable.Table } -func (this assertionTable) Insert(ctx context.Context, assertion *Assertion) error { - return this.table.Insert(ctx, assertion) +func (this accountTable) Insert(ctx context.Context, account *Account) error { + return this.table.Insert(ctx, account) } -func (this assertionTable) Update(ctx context.Context, assertion *Assertion) error { - return this.table.Update(ctx, assertion) +func (this accountTable) Update(ctx context.Context, account *Account) error { + return this.table.Update(ctx, account) } -func (this assertionTable) Save(ctx context.Context, assertion *Assertion) error { - return this.table.Save(ctx, assertion) +func (this accountTable) Save(ctx context.Context, account *Account) error { + return this.table.Save(ctx, account) } -func (this assertionTable) Delete(ctx context.Context, assertion *Assertion) error { - return this.table.Delete(ctx, assertion) +func (this accountTable) Delete(ctx context.Context, account *Account) error { + return this.table.Delete(ctx, account) } -func (this assertionTable) Has(ctx context.Context, did string) (found bool, err error) { +func (this accountTable) Has(ctx context.Context, did string) (found bool, err error) { return this.table.PrimaryKey().Has(ctx, did) } -func (this assertionTable) Get(ctx context.Context, did string) (*Assertion, error) { - var assertion Assertion - found, err := this.table.PrimaryKey().Get(ctx, &assertion, did) +func (this accountTable) Get(ctx context.Context, did string) (*Account, error) { + var account Account + found, err := this.table.PrimaryKey().Get(ctx, &account, did) if err != nil { return nil, err } if !found { return nil, ormerrors.NotFound } - return &assertion, nil + return &account, nil } -func (this assertionTable) HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error) { +func (this accountTable) HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error) { return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, controller, subject, ) } -func (this assertionTable) GetByControllerSubject(ctx context.Context, controller string, subject string) (*Assertion, error) { - var assertion Assertion - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &assertion, +func (this accountTable) GetByControllerSubject(ctx context.Context, controller string, subject string) (*Account, error) { + var account Account + found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &account, controller, subject, ) @@ -133,530 +133,206 @@ func (this assertionTable) GetByControllerSubject(ctx context.Context, controlle if !found { return nil, ormerrors.NotFound } - return &assertion, nil + return &account, nil } -func (this assertionTable) List(ctx context.Context, prefixKey AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error) { +func (this accountTable) List(ctx context.Context, prefixKey AccountIndexKey, opts ...ormlist.Option) (AccountIterator, error) { it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return AssertionIterator{it}, err + return AccountIterator{it}, err } -func (this assertionTable) ListRange(ctx context.Context, from, to AssertionIndexKey, opts ...ormlist.Option) (AssertionIterator, error) { +func (this accountTable) ListRange(ctx context.Context, from, to AccountIndexKey, opts ...ormlist.Option) (AccountIterator, error) { it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return AssertionIterator{it}, err + return AccountIterator{it}, err } -func (this assertionTable) DeleteBy(ctx context.Context, prefixKey AssertionIndexKey) error { +func (this accountTable) DeleteBy(ctx context.Context, prefixKey AccountIndexKey) error { return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) } -func (this assertionTable) DeleteRange(ctx context.Context, from, to AssertionIndexKey) error { +func (this accountTable) DeleteRange(ctx context.Context, from, to AccountIndexKey) error { return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) } -func (this assertionTable) doNotImplement() {} +func (this accountTable) doNotImplement() {} -var _ AssertionTable = assertionTable{} +var _ AccountTable = accountTable{} -func NewAssertionTable(db ormtable.Schema) (AssertionTable, error) { - table := db.GetTable(&Assertion{}) +func NewAccountTable(db ormtable.Schema) (AccountTable, error) { + table := db.GetTable(&Account{}) if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Assertion{}).ProtoReflect().Descriptor().FullName())) + return nil, ormerrors.TableNotFound.Wrap(string((&Account{}).ProtoReflect().Descriptor().FullName())) } - return assertionTable{table}, nil + return accountTable{table}, nil } -type AuthenticationTable interface { - Insert(ctx context.Context, authentication *Authentication) error - Update(ctx context.Context, authentication *Authentication) error - Save(ctx context.Context, authentication *Authentication) error - Delete(ctx context.Context, authentication *Authentication) error - Has(ctx context.Context, did string) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, did string) (*Authentication, error) - HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error) - // GetByControllerSubject returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByControllerSubject(ctx context.Context, controller string, subject string) (*Authentication, error) - List(ctx context.Context, prefixKey AuthenticationIndexKey, opts ...ormlist.Option) (AuthenticationIterator, error) - ListRange(ctx context.Context, from, to AuthenticationIndexKey, opts ...ormlist.Option) (AuthenticationIterator, error) - DeleteBy(ctx context.Context, prefixKey AuthenticationIndexKey) error - DeleteRange(ctx context.Context, from, to AuthenticationIndexKey) error - - doNotImplement() -} - -type AuthenticationIterator struct { - ormtable.Iterator -} - -func (i AuthenticationIterator) Value() (*Authentication, error) { - var authentication Authentication - err := i.UnmarshalMessage(&authentication) - return &authentication, err -} - -type AuthenticationIndexKey interface { - id() uint32 - values() []interface{} - authenticationIndexKey() -} - -// primary key starting index.. -type AuthenticationPrimaryKey = AuthenticationDidIndexKey - -type AuthenticationDidIndexKey struct { - vs []interface{} -} - -func (x AuthenticationDidIndexKey) id() uint32 { return 0 } -func (x AuthenticationDidIndexKey) values() []interface{} { return x.vs } -func (x AuthenticationDidIndexKey) authenticationIndexKey() {} - -func (this AuthenticationDidIndexKey) WithDid(did string) AuthenticationDidIndexKey { - this.vs = []interface{}{did} - return this -} - -type AuthenticationControllerSubjectIndexKey struct { - vs []interface{} -} - -func (x AuthenticationControllerSubjectIndexKey) id() uint32 { return 1 } -func (x AuthenticationControllerSubjectIndexKey) values() []interface{} { return x.vs } -func (x AuthenticationControllerSubjectIndexKey) authenticationIndexKey() {} - -func (this AuthenticationControllerSubjectIndexKey) WithController(controller string) AuthenticationControllerSubjectIndexKey { - this.vs = []interface{}{controller} - return this -} - -func (this AuthenticationControllerSubjectIndexKey) WithControllerSubject(controller string, subject string) AuthenticationControllerSubjectIndexKey { - this.vs = []interface{}{controller, subject} - return this -} - -type authenticationTable struct { - table ormtable.Table -} - -func (this authenticationTable) Insert(ctx context.Context, authentication *Authentication) error { - return this.table.Insert(ctx, authentication) -} - -func (this authenticationTable) Update(ctx context.Context, authentication *Authentication) error { - return this.table.Update(ctx, authentication) -} - -func (this authenticationTable) Save(ctx context.Context, authentication *Authentication) error { - return this.table.Save(ctx, authentication) -} - -func (this authenticationTable) Delete(ctx context.Context, authentication *Authentication) error { - return this.table.Delete(ctx, authentication) -} - -func (this authenticationTable) Has(ctx context.Context, did string) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, did) -} - -func (this authenticationTable) Get(ctx context.Context, did string) (*Authentication, error) { - var authentication Authentication - found, err := this.table.PrimaryKey().Get(ctx, &authentication, did) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &authentication, nil -} - -func (this authenticationTable) HasByControllerSubject(ctx context.Context, controller string, subject string) (found bool, err error) { - return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, - controller, - subject, - ) -} - -func (this authenticationTable) GetByControllerSubject(ctx context.Context, controller string, subject string) (*Authentication, error) { - var authentication Authentication - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &authentication, - controller, - subject, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &authentication, nil -} - -func (this authenticationTable) List(ctx context.Context, prefixKey AuthenticationIndexKey, opts ...ormlist.Option) (AuthenticationIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return AuthenticationIterator{it}, err -} - -func (this authenticationTable) ListRange(ctx context.Context, from, to AuthenticationIndexKey, opts ...ormlist.Option) (AuthenticationIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return AuthenticationIterator{it}, err -} - -func (this authenticationTable) DeleteBy(ctx context.Context, prefixKey AuthenticationIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this authenticationTable) DeleteRange(ctx context.Context, from, to AuthenticationIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this authenticationTable) doNotImplement() {} - -var _ AuthenticationTable = authenticationTable{} - -func NewAuthenticationTable(db ormtable.Schema) (AuthenticationTable, error) { - table := db.GetTable(&Authentication{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Authentication{}).ProtoReflect().Descriptor().FullName())) - } - return authenticationTable{table}, nil -} - -type BiscuitTable interface { - Insert(ctx context.Context, biscuit *Biscuit) error - InsertReturningId(ctx context.Context, biscuit *Biscuit) (uint64, error) +type PublicKeyTable interface { + Insert(ctx context.Context, publicKey *PublicKey) error + InsertReturningNumber(ctx context.Context, publicKey *PublicKey) (uint64, error) LastInsertedSequence(ctx context.Context) (uint64, error) - Update(ctx context.Context, biscuit *Biscuit) error - Save(ctx context.Context, biscuit *Biscuit) error - Delete(ctx context.Context, biscuit *Biscuit) error - Has(ctx context.Context, id uint64) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, id uint64) (*Biscuit, error) - HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) - // GetBySubjectOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Biscuit, error) - List(ctx context.Context, prefixKey BiscuitIndexKey, opts ...ormlist.Option) (BiscuitIterator, error) - ListRange(ctx context.Context, from, to BiscuitIndexKey, opts ...ormlist.Option) (BiscuitIterator, error) - DeleteBy(ctx context.Context, prefixKey BiscuitIndexKey) error - DeleteRange(ctx context.Context, from, to BiscuitIndexKey) error - - doNotImplement() -} - -type BiscuitIterator struct { - ormtable.Iterator -} - -func (i BiscuitIterator) Value() (*Biscuit, error) { - var biscuit Biscuit - err := i.UnmarshalMessage(&biscuit) - return &biscuit, err -} - -type BiscuitIndexKey interface { - id() uint32 - values() []interface{} - biscuitIndexKey() -} - -// primary key starting index.. -type BiscuitPrimaryKey = BiscuitIdIndexKey - -type BiscuitIdIndexKey struct { - vs []interface{} -} - -func (x BiscuitIdIndexKey) id() uint32 { return 0 } -func (x BiscuitIdIndexKey) values() []interface{} { return x.vs } -func (x BiscuitIdIndexKey) biscuitIndexKey() {} - -func (this BiscuitIdIndexKey) WithId(id uint64) BiscuitIdIndexKey { - this.vs = []interface{}{id} - return this -} - -type BiscuitSubjectOriginIndexKey struct { - vs []interface{} -} - -func (x BiscuitSubjectOriginIndexKey) id() uint32 { return 1 } -func (x BiscuitSubjectOriginIndexKey) values() []interface{} { return x.vs } -func (x BiscuitSubjectOriginIndexKey) biscuitIndexKey() {} - -func (this BiscuitSubjectOriginIndexKey) WithSubject(subject string) BiscuitSubjectOriginIndexKey { - this.vs = []interface{}{subject} - return this -} - -func (this BiscuitSubjectOriginIndexKey) WithSubjectOrigin(subject string, origin string) BiscuitSubjectOriginIndexKey { - this.vs = []interface{}{subject, origin} - return this -} - -type biscuitTable struct { - table ormtable.AutoIncrementTable -} - -func (this biscuitTable) Insert(ctx context.Context, biscuit *Biscuit) error { - return this.table.Insert(ctx, biscuit) -} - -func (this biscuitTable) Update(ctx context.Context, biscuit *Biscuit) error { - return this.table.Update(ctx, biscuit) -} - -func (this biscuitTable) Save(ctx context.Context, biscuit *Biscuit) error { - return this.table.Save(ctx, biscuit) -} - -func (this biscuitTable) Delete(ctx context.Context, biscuit *Biscuit) error { - return this.table.Delete(ctx, biscuit) -} - -func (this biscuitTable) InsertReturningId(ctx context.Context, biscuit *Biscuit) (uint64, error) { - return this.table.InsertReturningPKey(ctx, biscuit) -} - -func (this biscuitTable) LastInsertedSequence(ctx context.Context) (uint64, error) { - return this.table.LastInsertedSequence(ctx) -} - -func (this biscuitTable) Has(ctx context.Context, id uint64) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, id) -} - -func (this biscuitTable) Get(ctx context.Context, id uint64) (*Biscuit, error) { - var biscuit Biscuit - found, err := this.table.PrimaryKey().Get(ctx, &biscuit, id) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &biscuit, nil -} - -func (this biscuitTable) HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) { - return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, - subject, - origin, - ) -} - -func (this biscuitTable) GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Biscuit, error) { - var biscuit Biscuit - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &biscuit, - subject, - origin, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &biscuit, nil -} - -func (this biscuitTable) List(ctx context.Context, prefixKey BiscuitIndexKey, opts ...ormlist.Option) (BiscuitIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return BiscuitIterator{it}, err -} - -func (this biscuitTable) ListRange(ctx context.Context, from, to BiscuitIndexKey, opts ...ormlist.Option) (BiscuitIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return BiscuitIterator{it}, err -} - -func (this biscuitTable) DeleteBy(ctx context.Context, prefixKey BiscuitIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this biscuitTable) DeleteRange(ctx context.Context, from, to BiscuitIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this biscuitTable) doNotImplement() {} - -var _ BiscuitTable = biscuitTable{} - -func NewBiscuitTable(db ormtable.Schema) (BiscuitTable, error) { - table := db.GetTable(&Biscuit{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Biscuit{}).ProtoReflect().Descriptor().FullName())) - } - return biscuitTable{table.(ormtable.AutoIncrementTable)}, nil -} - -type ControllerTable interface { - Insert(ctx context.Context, controller *Controller) error - InsertReturningNumber(ctx context.Context, controller *Controller) (uint64, error) - LastInsertedSequence(ctx context.Context) (uint64, error) - Update(ctx context.Context, controller *Controller) error - Save(ctx context.Context, controller *Controller) error - Delete(ctx context.Context, controller *Controller) error + Update(ctx context.Context, publicKey *PublicKey) error + Save(ctx context.Context, publicKey *PublicKey) error + Delete(ctx context.Context, publicKey *PublicKey) error Has(ctx context.Context, number uint64) (found bool, err error) // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, number uint64) (*Controller, error) + Get(ctx context.Context, number uint64) (*PublicKey, error) HasBySonrAddress(ctx context.Context, sonr_address string) (found bool, err error) // GetBySonrAddress returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetBySonrAddress(ctx context.Context, sonr_address string) (*Controller, error) + GetBySonrAddress(ctx context.Context, sonr_address string) (*PublicKey, error) HasByEthAddress(ctx context.Context, eth_address string) (found bool, err error) // GetByEthAddress returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByEthAddress(ctx context.Context, eth_address string) (*Controller, error) + GetByEthAddress(ctx context.Context, eth_address string) (*PublicKey, error) HasByBtcAddress(ctx context.Context, btc_address string) (found bool, err error) // GetByBtcAddress returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByBtcAddress(ctx context.Context, btc_address string) (*Controller, error) + GetByBtcAddress(ctx context.Context, btc_address string) (*PublicKey, error) HasByDid(ctx context.Context, did string) (found bool, err error) // GetByDid returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByDid(ctx context.Context, did string) (*Controller, error) - List(ctx context.Context, prefixKey ControllerIndexKey, opts ...ormlist.Option) (ControllerIterator, error) - ListRange(ctx context.Context, from, to ControllerIndexKey, opts ...ormlist.Option) (ControllerIterator, error) - DeleteBy(ctx context.Context, prefixKey ControllerIndexKey) error - DeleteRange(ctx context.Context, from, to ControllerIndexKey) error + GetByDid(ctx context.Context, did string) (*PublicKey, error) + List(ctx context.Context, prefixKey PublicKeyIndexKey, opts ...ormlist.Option) (PublicKeyIterator, error) + ListRange(ctx context.Context, from, to PublicKeyIndexKey, opts ...ormlist.Option) (PublicKeyIterator, error) + DeleteBy(ctx context.Context, prefixKey PublicKeyIndexKey) error + DeleteRange(ctx context.Context, from, to PublicKeyIndexKey) error doNotImplement() } -type ControllerIterator struct { +type PublicKeyIterator struct { ormtable.Iterator } -func (i ControllerIterator) Value() (*Controller, error) { - var controller Controller - err := i.UnmarshalMessage(&controller) - return &controller, err +func (i PublicKeyIterator) Value() (*PublicKey, error) { + var publicKey PublicKey + err := i.UnmarshalMessage(&publicKey) + return &publicKey, err } -type ControllerIndexKey interface { +type PublicKeyIndexKey interface { id() uint32 values() []interface{} - controllerIndexKey() + publicKeyIndexKey() } // primary key starting index.. -type ControllerPrimaryKey = ControllerNumberIndexKey +type PublicKeyPrimaryKey = PublicKeyNumberIndexKey -type ControllerNumberIndexKey struct { +type PublicKeyNumberIndexKey struct { vs []interface{} } -func (x ControllerNumberIndexKey) id() uint32 { return 0 } -func (x ControllerNumberIndexKey) values() []interface{} { return x.vs } -func (x ControllerNumberIndexKey) controllerIndexKey() {} +func (x PublicKeyNumberIndexKey) id() uint32 { return 0 } +func (x PublicKeyNumberIndexKey) values() []interface{} { return x.vs } +func (x PublicKeyNumberIndexKey) publicKeyIndexKey() {} -func (this ControllerNumberIndexKey) WithNumber(number uint64) ControllerNumberIndexKey { +func (this PublicKeyNumberIndexKey) WithNumber(number uint64) PublicKeyNumberIndexKey { this.vs = []interface{}{number} return this } -type ControllerSonrAddressIndexKey struct { +type PublicKeySonrAddressIndexKey struct { vs []interface{} } -func (x ControllerSonrAddressIndexKey) id() uint32 { return 1 } -func (x ControllerSonrAddressIndexKey) values() []interface{} { return x.vs } -func (x ControllerSonrAddressIndexKey) controllerIndexKey() {} +func (x PublicKeySonrAddressIndexKey) id() uint32 { return 1 } +func (x PublicKeySonrAddressIndexKey) values() []interface{} { return x.vs } +func (x PublicKeySonrAddressIndexKey) publicKeyIndexKey() {} -func (this ControllerSonrAddressIndexKey) WithSonrAddress(sonr_address string) ControllerSonrAddressIndexKey { +func (this PublicKeySonrAddressIndexKey) WithSonrAddress(sonr_address string) PublicKeySonrAddressIndexKey { this.vs = []interface{}{sonr_address} return this } -type ControllerEthAddressIndexKey struct { +type PublicKeyEthAddressIndexKey struct { vs []interface{} } -func (x ControllerEthAddressIndexKey) id() uint32 { return 2 } -func (x ControllerEthAddressIndexKey) values() []interface{} { return x.vs } -func (x ControllerEthAddressIndexKey) controllerIndexKey() {} +func (x PublicKeyEthAddressIndexKey) id() uint32 { return 2 } +func (x PublicKeyEthAddressIndexKey) values() []interface{} { return x.vs } +func (x PublicKeyEthAddressIndexKey) publicKeyIndexKey() {} -func (this ControllerEthAddressIndexKey) WithEthAddress(eth_address string) ControllerEthAddressIndexKey { +func (this PublicKeyEthAddressIndexKey) WithEthAddress(eth_address string) PublicKeyEthAddressIndexKey { this.vs = []interface{}{eth_address} return this } -type ControllerBtcAddressIndexKey struct { +type PublicKeyBtcAddressIndexKey struct { vs []interface{} } -func (x ControllerBtcAddressIndexKey) id() uint32 { return 3 } -func (x ControllerBtcAddressIndexKey) values() []interface{} { return x.vs } -func (x ControllerBtcAddressIndexKey) controllerIndexKey() {} +func (x PublicKeyBtcAddressIndexKey) id() uint32 { return 3 } +func (x PublicKeyBtcAddressIndexKey) values() []interface{} { return x.vs } +func (x PublicKeyBtcAddressIndexKey) publicKeyIndexKey() {} -func (this ControllerBtcAddressIndexKey) WithBtcAddress(btc_address string) ControllerBtcAddressIndexKey { +func (this PublicKeyBtcAddressIndexKey) WithBtcAddress(btc_address string) PublicKeyBtcAddressIndexKey { this.vs = []interface{}{btc_address} return this } -type ControllerDidIndexKey struct { +type PublicKeyDidIndexKey struct { vs []interface{} } -func (x ControllerDidIndexKey) id() uint32 { return 4 } -func (x ControllerDidIndexKey) values() []interface{} { return x.vs } -func (x ControllerDidIndexKey) controllerIndexKey() {} +func (x PublicKeyDidIndexKey) id() uint32 { return 4 } +func (x PublicKeyDidIndexKey) values() []interface{} { return x.vs } +func (x PublicKeyDidIndexKey) publicKeyIndexKey() {} -func (this ControllerDidIndexKey) WithDid(did string) ControllerDidIndexKey { +func (this PublicKeyDidIndexKey) WithDid(did string) PublicKeyDidIndexKey { this.vs = []interface{}{did} return this } -type controllerTable struct { +type publicKeyTable struct { table ormtable.AutoIncrementTable } -func (this controllerTable) Insert(ctx context.Context, controller *Controller) error { - return this.table.Insert(ctx, controller) +func (this publicKeyTable) Insert(ctx context.Context, publicKey *PublicKey) error { + return this.table.Insert(ctx, publicKey) } -func (this controllerTable) Update(ctx context.Context, controller *Controller) error { - return this.table.Update(ctx, controller) +func (this publicKeyTable) Update(ctx context.Context, publicKey *PublicKey) error { + return this.table.Update(ctx, publicKey) } -func (this controllerTable) Save(ctx context.Context, controller *Controller) error { - return this.table.Save(ctx, controller) +func (this publicKeyTable) Save(ctx context.Context, publicKey *PublicKey) error { + return this.table.Save(ctx, publicKey) } -func (this controllerTable) Delete(ctx context.Context, controller *Controller) error { - return this.table.Delete(ctx, controller) +func (this publicKeyTable) Delete(ctx context.Context, publicKey *PublicKey) error { + return this.table.Delete(ctx, publicKey) } -func (this controllerTable) InsertReturningNumber(ctx context.Context, controller *Controller) (uint64, error) { - return this.table.InsertReturningPKey(ctx, controller) +func (this publicKeyTable) InsertReturningNumber(ctx context.Context, publicKey *PublicKey) (uint64, error) { + return this.table.InsertReturningPKey(ctx, publicKey) } -func (this controllerTable) LastInsertedSequence(ctx context.Context) (uint64, error) { +func (this publicKeyTable) LastInsertedSequence(ctx context.Context) (uint64, error) { return this.table.LastInsertedSequence(ctx) } -func (this controllerTable) Has(ctx context.Context, number uint64) (found bool, err error) { +func (this publicKeyTable) Has(ctx context.Context, number uint64) (found bool, err error) { return this.table.PrimaryKey().Has(ctx, number) } -func (this controllerTable) Get(ctx context.Context, number uint64) (*Controller, error) { - var controller Controller - found, err := this.table.PrimaryKey().Get(ctx, &controller, number) +func (this publicKeyTable) Get(ctx context.Context, number uint64) (*PublicKey, error) { + var publicKey PublicKey + found, err := this.table.PrimaryKey().Get(ctx, &publicKey, number) if err != nil { return nil, err } if !found { return nil, ormerrors.NotFound } - return &controller, nil + return &publicKey, nil } -func (this controllerTable) HasBySonrAddress(ctx context.Context, sonr_address string) (found bool, err error) { +func (this publicKeyTable) HasBySonrAddress(ctx context.Context, sonr_address string) (found bool, err error) { return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, sonr_address, ) } -func (this controllerTable) GetBySonrAddress(ctx context.Context, sonr_address string) (*Controller, error) { - var controller Controller - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &controller, +func (this publicKeyTable) GetBySonrAddress(ctx context.Context, sonr_address string) (*PublicKey, error) { + var publicKey PublicKey + found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &publicKey, sonr_address, ) if err != nil { @@ -665,18 +341,18 @@ func (this controllerTable) GetBySonrAddress(ctx context.Context, sonr_address s if !found { return nil, ormerrors.NotFound } - return &controller, nil + return &publicKey, nil } -func (this controllerTable) HasByEthAddress(ctx context.Context, eth_address string) (found bool, err error) { +func (this publicKeyTable) HasByEthAddress(ctx context.Context, eth_address string) (found bool, err error) { return this.table.GetIndexByID(2).(ormtable.UniqueIndex).Has(ctx, eth_address, ) } -func (this controllerTable) GetByEthAddress(ctx context.Context, eth_address string) (*Controller, error) { - var controller Controller - found, err := this.table.GetIndexByID(2).(ormtable.UniqueIndex).Get(ctx, &controller, +func (this publicKeyTable) GetByEthAddress(ctx context.Context, eth_address string) (*PublicKey, error) { + var publicKey PublicKey + found, err := this.table.GetIndexByID(2).(ormtable.UniqueIndex).Get(ctx, &publicKey, eth_address, ) if err != nil { @@ -685,18 +361,18 @@ func (this controllerTable) GetByEthAddress(ctx context.Context, eth_address str if !found { return nil, ormerrors.NotFound } - return &controller, nil + return &publicKey, nil } -func (this controllerTable) HasByBtcAddress(ctx context.Context, btc_address string) (found bool, err error) { +func (this publicKeyTable) HasByBtcAddress(ctx context.Context, btc_address string) (found bool, err error) { return this.table.GetIndexByID(3).(ormtable.UniqueIndex).Has(ctx, btc_address, ) } -func (this controllerTable) GetByBtcAddress(ctx context.Context, btc_address string) (*Controller, error) { - var controller Controller - found, err := this.table.GetIndexByID(3).(ormtable.UniqueIndex).Get(ctx, &controller, +func (this publicKeyTable) GetByBtcAddress(ctx context.Context, btc_address string) (*PublicKey, error) { + var publicKey PublicKey + found, err := this.table.GetIndexByID(3).(ormtable.UniqueIndex).Get(ctx, &publicKey, btc_address, ) if err != nil { @@ -705,18 +381,18 @@ func (this controllerTable) GetByBtcAddress(ctx context.Context, btc_address str if !found { return nil, ormerrors.NotFound } - return &controller, nil + return &publicKey, nil } -func (this controllerTable) HasByDid(ctx context.Context, did string) (found bool, err error) { +func (this publicKeyTable) HasByDid(ctx context.Context, did string) (found bool, err error) { return this.table.GetIndexByID(4).(ormtable.UniqueIndex).Has(ctx, did, ) } -func (this controllerTable) GetByDid(ctx context.Context, did string) (*Controller, error) { - var controller Controller - found, err := this.table.GetIndexByID(4).(ormtable.UniqueIndex).Get(ctx, &controller, +func (this publicKeyTable) GetByDid(ctx context.Context, did string) (*PublicKey, error) { + var publicKey PublicKey + found, err := this.table.GetIndexByID(4).(ormtable.UniqueIndex).Get(ctx, &publicKey, did, ) if err != nil { @@ -725,37 +401,37 @@ func (this controllerTable) GetByDid(ctx context.Context, did string) (*Controll if !found { return nil, ormerrors.NotFound } - return &controller, nil + return &publicKey, nil } -func (this controllerTable) List(ctx context.Context, prefixKey ControllerIndexKey, opts ...ormlist.Option) (ControllerIterator, error) { +func (this publicKeyTable) List(ctx context.Context, prefixKey PublicKeyIndexKey, opts ...ormlist.Option) (PublicKeyIterator, error) { it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return ControllerIterator{it}, err + return PublicKeyIterator{it}, err } -func (this controllerTable) ListRange(ctx context.Context, from, to ControllerIndexKey, opts ...ormlist.Option) (ControllerIterator, error) { +func (this publicKeyTable) ListRange(ctx context.Context, from, to PublicKeyIndexKey, opts ...ormlist.Option) (PublicKeyIterator, error) { it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return ControllerIterator{it}, err + return PublicKeyIterator{it}, err } -func (this controllerTable) DeleteBy(ctx context.Context, prefixKey ControllerIndexKey) error { +func (this publicKeyTable) DeleteBy(ctx context.Context, prefixKey PublicKeyIndexKey) error { return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) } -func (this controllerTable) DeleteRange(ctx context.Context, from, to ControllerIndexKey) error { +func (this publicKeyTable) DeleteRange(ctx context.Context, from, to PublicKeyIndexKey) error { return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) } -func (this controllerTable) doNotImplement() {} +func (this publicKeyTable) doNotImplement() {} -var _ ControllerTable = controllerTable{} +var _ PublicKeyTable = publicKeyTable{} -func NewControllerTable(db ormtable.Schema) (ControllerTable, error) { - table := db.GetTable(&Controller{}) +func NewPublicKeyTable(db ormtable.Schema) (PublicKeyTable, error) { + table := db.GetTable(&PublicKey{}) if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Controller{}).ProtoReflect().Descriptor().FullName())) + return nil, ormerrors.TableNotFound.Wrap(string((&PublicKey{}).ProtoReflect().Descriptor().FullName())) } - return controllerTable{table.(ormtable.AutoIncrementTable)}, nil + return publicKeyTable{table.(ormtable.AutoIncrementTable)}, nil } type VerificationTable interface { @@ -1016,37 +692,25 @@ func NewVerificationTable(db ormtable.Schema) (VerificationTable, error) { } type StateStore interface { - AssertionTable() AssertionTable - AuthenticationTable() AuthenticationTable - BiscuitTable() BiscuitTable - ControllerTable() ControllerTable + AccountTable() AccountTable + PublicKeyTable() PublicKeyTable VerificationTable() VerificationTable doNotImplement() } type stateStore struct { - assertion AssertionTable - authentication AuthenticationTable - biscuit BiscuitTable - controller ControllerTable - verification VerificationTable + account AccountTable + publicKey PublicKeyTable + verification VerificationTable } -func (x stateStore) AssertionTable() AssertionTable { - return x.assertion +func (x stateStore) AccountTable() AccountTable { + return x.account } -func (x stateStore) AuthenticationTable() AuthenticationTable { - return x.authentication -} - -func (x stateStore) BiscuitTable() BiscuitTable { - return x.biscuit -} - -func (x stateStore) ControllerTable() ControllerTable { - return x.controller +func (x stateStore) PublicKeyTable() PublicKeyTable { + return x.publicKey } func (x stateStore) VerificationTable() VerificationTable { @@ -1058,22 +722,12 @@ func (stateStore) doNotImplement() {} var _ StateStore = stateStore{} func NewStateStore(db ormtable.Schema) (StateStore, error) { - assertionTable, err := NewAssertionTable(db) + accountTable, err := NewAccountTable(db) if err != nil { return nil, err } - authenticationTable, err := NewAuthenticationTable(db) - if err != nil { - return nil, err - } - - biscuitTable, err := NewBiscuitTable(db) - if err != nil { - return nil, err - } - - controllerTable, err := NewControllerTable(db) + publicKeyTable, err := NewPublicKeyTable(db) if err != nil { return nil, err } @@ -1084,10 +738,8 @@ func NewStateStore(db ormtable.Schema) (StateStore, error) { } return stateStore{ - assertionTable, - authenticationTable, - biscuitTable, - controllerTable, + accountTable, + publicKeyTable, verificationTable, }, nil } diff --git a/api/did/v1/state.pulsar.go b/api/did/v1/state.pulsar.go index 7fe1e9a98..af60e7946 100644 --- a/api/did/v1/state.pulsar.go +++ b/api/did/v1/state.pulsar.go @@ -14,20 +14,20 @@ import ( sync "sync" ) -var _ protoreflect.Map = (*_Assertion_6_map)(nil) +var _ protoreflect.Map = (*_Account_6_map)(nil) -type _Assertion_6_map struct { +type _Account_6_map struct { m *map[string][]byte } -func (x *_Assertion_6_map) Len() int { +func (x *_Account_6_map) Len() int { if x.m == nil { return 0 } return len(*x.m) } -func (x *_Assertion_6_map) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { +func (x *_Account_6_map) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { if x.m == nil { return } @@ -40,7 +40,7 @@ func (x *_Assertion_6_map) Range(f func(protoreflect.MapKey, protoreflect.Value) } } -func (x *_Assertion_6_map) Has(key protoreflect.MapKey) bool { +func (x *_Account_6_map) Has(key protoreflect.MapKey) bool { if x.m == nil { return false } @@ -50,7 +50,7 @@ func (x *_Assertion_6_map) Has(key protoreflect.MapKey) bool { return ok } -func (x *_Assertion_6_map) Clear(key protoreflect.MapKey) { +func (x *_Account_6_map) Clear(key protoreflect.MapKey) { if x.m == nil { return } @@ -59,7 +59,7 @@ func (x *_Assertion_6_map) Clear(key protoreflect.MapKey) { delete(*x.m, concreteKey) } -func (x *_Assertion_6_map) Get(key protoreflect.MapKey) protoreflect.Value { +func (x *_Account_6_map) Get(key protoreflect.MapKey) protoreflect.Value { if x.m == nil { return protoreflect.Value{} } @@ -72,7 +72,7 @@ func (x *_Assertion_6_map) Get(key protoreflect.MapKey) protoreflect.Value { return protoreflect.ValueOfBytes(v) } -func (x *_Assertion_6_map) Set(key protoreflect.MapKey, value protoreflect.Value) { +func (x *_Account_6_map) Set(key protoreflect.MapKey, value protoreflect.Value) { if !key.IsValid() || !value.IsValid() { panic("invalid key or value provided") } @@ -83,51 +83,51 @@ func (x *_Assertion_6_map) Set(key protoreflect.MapKey, value protoreflect.Value (*x.m)[concreteKey] = concreteValue } -func (x *_Assertion_6_map) Mutable(key protoreflect.MapKey) protoreflect.Value { +func (x *_Account_6_map) Mutable(key protoreflect.MapKey) protoreflect.Value { panic("should not call Mutable on protoreflect.Map whose value is not of type protoreflect.Message") } -func (x *_Assertion_6_map) NewValue() protoreflect.Value { +func (x *_Account_6_map) NewValue() protoreflect.Value { var v []byte return protoreflect.ValueOfBytes(v) } -func (x *_Assertion_6_map) IsValid() bool { +func (x *_Account_6_map) IsValid() bool { return x.m != nil } var ( - md_Assertion protoreflect.MessageDescriptor - fd_Assertion_did protoreflect.FieldDescriptor - fd_Assertion_controller protoreflect.FieldDescriptor - fd_Assertion_subject protoreflect.FieldDescriptor - fd_Assertion_public_key_hex protoreflect.FieldDescriptor - fd_Assertion_assertion_type protoreflect.FieldDescriptor - fd_Assertion_accumulator protoreflect.FieldDescriptor - fd_Assertion_creation_block protoreflect.FieldDescriptor + md_Account protoreflect.MessageDescriptor + fd_Account_did protoreflect.FieldDescriptor + fd_Account_controller protoreflect.FieldDescriptor + fd_Account_subject protoreflect.FieldDescriptor + fd_Account_public_key_hex protoreflect.FieldDescriptor + fd_Account_assertion_type protoreflect.FieldDescriptor + fd_Account_accumulator protoreflect.FieldDescriptor + fd_Account_creation_block protoreflect.FieldDescriptor ) func init() { file_did_v1_state_proto_init() - md_Assertion = File_did_v1_state_proto.Messages().ByName("Assertion") - fd_Assertion_did = md_Assertion.Fields().ByName("did") - fd_Assertion_controller = md_Assertion.Fields().ByName("controller") - fd_Assertion_subject = md_Assertion.Fields().ByName("subject") - fd_Assertion_public_key_hex = md_Assertion.Fields().ByName("public_key_hex") - fd_Assertion_assertion_type = md_Assertion.Fields().ByName("assertion_type") - fd_Assertion_accumulator = md_Assertion.Fields().ByName("accumulator") - fd_Assertion_creation_block = md_Assertion.Fields().ByName("creation_block") + md_Account = File_did_v1_state_proto.Messages().ByName("Account") + fd_Account_did = md_Account.Fields().ByName("did") + fd_Account_controller = md_Account.Fields().ByName("controller") + fd_Account_subject = md_Account.Fields().ByName("subject") + fd_Account_public_key_hex = md_Account.Fields().ByName("public_key_hex") + fd_Account_assertion_type = md_Account.Fields().ByName("assertion_type") + fd_Account_accumulator = md_Account.Fields().ByName("accumulator") + fd_Account_creation_block = md_Account.Fields().ByName("creation_block") } -var _ protoreflect.Message = (*fastReflection_Assertion)(nil) +var _ protoreflect.Message = (*fastReflection_Account)(nil) -type fastReflection_Assertion Assertion +type fastReflection_Account Account -func (x *Assertion) ProtoReflect() protoreflect.Message { - return (*fastReflection_Assertion)(x) +func (x *Account) ProtoReflect() protoreflect.Message { + return (*fastReflection_Account)(x) } -func (x *Assertion) slowProtoReflect() protoreflect.Message { +func (x *Account) slowProtoReflect() protoreflect.Message { mi := &file_did_v1_state_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -139,43 +139,43 @@ func (x *Assertion) slowProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -var _fastReflection_Assertion_messageType fastReflection_Assertion_messageType -var _ protoreflect.MessageType = fastReflection_Assertion_messageType{} +var _fastReflection_Account_messageType fastReflection_Account_messageType +var _ protoreflect.MessageType = fastReflection_Account_messageType{} -type fastReflection_Assertion_messageType struct{} +type fastReflection_Account_messageType struct{} -func (x fastReflection_Assertion_messageType) Zero() protoreflect.Message { - return (*fastReflection_Assertion)(nil) +func (x fastReflection_Account_messageType) Zero() protoreflect.Message { + return (*fastReflection_Account)(nil) } -func (x fastReflection_Assertion_messageType) New() protoreflect.Message { - return new(fastReflection_Assertion) +func (x fastReflection_Account_messageType) New() protoreflect.Message { + return new(fastReflection_Account) } -func (x fastReflection_Assertion_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Assertion +func (x fastReflection_Account_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Account } // Descriptor returns message descriptor, which contains only the protobuf // type information for the message. -func (x *fastReflection_Assertion) Descriptor() protoreflect.MessageDescriptor { - return md_Assertion +func (x *fastReflection_Account) Descriptor() protoreflect.MessageDescriptor { + return md_Account } // Type returns the message type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the message descriptor be used instead. -func (x *fastReflection_Assertion) Type() protoreflect.MessageType { - return _fastReflection_Assertion_messageType +func (x *fastReflection_Account) Type() protoreflect.MessageType { + return _fastReflection_Account_messageType } // New returns a newly allocated and mutable empty message. -func (x *fastReflection_Assertion) New() protoreflect.Message { - return new(fastReflection_Assertion) +func (x *fastReflection_Account) New() protoreflect.Message { + return new(fastReflection_Account) } // Interface unwraps the message reflection interface and // returns the underlying ProtoMessage interface. -func (x *fastReflection_Assertion) Interface() protoreflect.ProtoMessage { - return (*Assertion)(x) +func (x *fastReflection_Account) Interface() protoreflect.ProtoMessage { + return (*Account)(x) } // Range iterates over every populated field in an undefined order, @@ -183,46 +183,46 @@ func (x *fastReflection_Assertion) Interface() protoreflect.ProtoMessage { // Range returns immediately if f returns false. // While iterating, mutating operations may only be performed // on the current field descriptor. -func (x *fastReflection_Assertion) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +func (x *fastReflection_Account) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { if x.Did != "" { value := protoreflect.ValueOfString(x.Did) - if !f(fd_Assertion_did, value) { + if !f(fd_Account_did, value) { return } } if x.Controller != "" { value := protoreflect.ValueOfString(x.Controller) - if !f(fd_Assertion_controller, value) { + if !f(fd_Account_controller, value) { return } } if x.Subject != "" { value := protoreflect.ValueOfString(x.Subject) - if !f(fd_Assertion_subject, value) { + if !f(fd_Account_subject, value) { return } } if x.PublicKeyHex != "" { value := protoreflect.ValueOfString(x.PublicKeyHex) - if !f(fd_Assertion_public_key_hex, value) { + if !f(fd_Account_public_key_hex, value) { return } } if x.AssertionType != "" { value := protoreflect.ValueOfString(x.AssertionType) - if !f(fd_Assertion_assertion_type, value) { + if !f(fd_Account_assertion_type, value) { return } } if len(x.Accumulator) != 0 { - value := protoreflect.ValueOfMap(&_Assertion_6_map{m: &x.Accumulator}) - if !f(fd_Assertion_accumulator, value) { + value := protoreflect.ValueOfMap(&_Account_6_map{m: &x.Accumulator}) + if !f(fd_Account_accumulator, value) { return } } if x.CreationBlock != int64(0) { value := protoreflect.ValueOfInt64(x.CreationBlock) - if !f(fd_Assertion_creation_block, value) { + if !f(fd_Account_creation_block, value) { return } } @@ -239,27 +239,27 @@ func (x *fastReflection_Assertion) Range(f func(protoreflect.FieldDescriptor, pr // In other cases (aside from the nullable cases above), // a proto3 scalar field is populated if it contains a non-zero value, and // a repeated field is populated if it is non-empty. -func (x *fastReflection_Assertion) Has(fd protoreflect.FieldDescriptor) bool { +func (x *fastReflection_Account) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "did.v1.Assertion.did": + case "did.v1.Account.did": return x.Did != "" - case "did.v1.Assertion.controller": + case "did.v1.Account.controller": return x.Controller != "" - case "did.v1.Assertion.subject": + case "did.v1.Account.subject": return x.Subject != "" - case "did.v1.Assertion.public_key_hex": + case "did.v1.Account.public_key_hex": return x.PublicKeyHex != "" - case "did.v1.Assertion.assertion_type": + case "did.v1.Account.assertion_type": return x.AssertionType != "" - case "did.v1.Assertion.accumulator": + case "did.v1.Account.accumulator": return len(x.Accumulator) != 0 - case "did.v1.Assertion.creation_block": + case "did.v1.Account.creation_block": return x.CreationBlock != int64(0) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Assertion")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Account")) } - panic(fmt.Errorf("message did.v1.Assertion does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Account does not contain field %s", fd.FullName())) } } @@ -269,27 +269,27 @@ func (x *fastReflection_Assertion) Has(fd protoreflect.FieldDescriptor) bool { // associated with the given field number. // // Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Assertion) Clear(fd protoreflect.FieldDescriptor) { +func (x *fastReflection_Account) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "did.v1.Assertion.did": + case "did.v1.Account.did": x.Did = "" - case "did.v1.Assertion.controller": + case "did.v1.Account.controller": x.Controller = "" - case "did.v1.Assertion.subject": + case "did.v1.Account.subject": x.Subject = "" - case "did.v1.Assertion.public_key_hex": + case "did.v1.Account.public_key_hex": x.PublicKeyHex = "" - case "did.v1.Assertion.assertion_type": + case "did.v1.Account.assertion_type": x.AssertionType = "" - case "did.v1.Assertion.accumulator": + case "did.v1.Account.accumulator": x.Accumulator = nil - case "did.v1.Assertion.creation_block": + case "did.v1.Account.creation_block": x.CreationBlock = int64(0) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Assertion")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Account")) } - panic(fmt.Errorf("message did.v1.Assertion does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Account does not contain field %s", fd.FullName())) } } @@ -299,37 +299,37 @@ func (x *fastReflection_Assertion) Clear(fd protoreflect.FieldDescriptor) { // the default value of a bytes scalar is guaranteed to be a copy. // For unpopulated composite types, it returns an empty, read-only view // of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Assertion) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Account) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "did.v1.Assertion.did": + case "did.v1.Account.did": value := x.Did return protoreflect.ValueOfString(value) - case "did.v1.Assertion.controller": + case "did.v1.Account.controller": value := x.Controller return protoreflect.ValueOfString(value) - case "did.v1.Assertion.subject": + case "did.v1.Account.subject": value := x.Subject return protoreflect.ValueOfString(value) - case "did.v1.Assertion.public_key_hex": + case "did.v1.Account.public_key_hex": value := x.PublicKeyHex return protoreflect.ValueOfString(value) - case "did.v1.Assertion.assertion_type": + case "did.v1.Account.assertion_type": value := x.AssertionType return protoreflect.ValueOfString(value) - case "did.v1.Assertion.accumulator": + case "did.v1.Account.accumulator": if len(x.Accumulator) == 0 { - return protoreflect.ValueOfMap(&_Assertion_6_map{}) + return protoreflect.ValueOfMap(&_Account_6_map{}) } - mapValue := &_Assertion_6_map{m: &x.Accumulator} + mapValue := &_Account_6_map{m: &x.Accumulator} return protoreflect.ValueOfMap(mapValue) - case "did.v1.Assertion.creation_block": + case "did.v1.Account.creation_block": value := x.CreationBlock return protoreflect.ValueOfInt64(value) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Assertion")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Account")) } - panic(fmt.Errorf("message did.v1.Assertion does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message did.v1.Account does not contain field %s", descriptor.FullName())) } } @@ -343,29 +343,29 @@ func (x *fastReflection_Assertion) Get(descriptor protoreflect.FieldDescriptor) // empty, read-only value, then it panics. // // Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Assertion) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { +func (x *fastReflection_Account) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "did.v1.Assertion.did": + case "did.v1.Account.did": x.Did = value.Interface().(string) - case "did.v1.Assertion.controller": + case "did.v1.Account.controller": x.Controller = value.Interface().(string) - case "did.v1.Assertion.subject": + case "did.v1.Account.subject": x.Subject = value.Interface().(string) - case "did.v1.Assertion.public_key_hex": + case "did.v1.Account.public_key_hex": x.PublicKeyHex = value.Interface().(string) - case "did.v1.Assertion.assertion_type": + case "did.v1.Account.assertion_type": x.AssertionType = value.Interface().(string) - case "did.v1.Assertion.accumulator": + case "did.v1.Account.accumulator": mv := value.Map() - cmv := mv.(*_Assertion_6_map) + cmv := mv.(*_Account_6_map) x.Accumulator = *cmv.m - case "did.v1.Assertion.creation_block": + case "did.v1.Account.creation_block": x.CreationBlock = value.Int() default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Assertion")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Account")) } - panic(fmt.Errorf("message did.v1.Assertion does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Account does not contain field %s", fd.FullName())) } } @@ -379,69 +379,69 @@ func (x *fastReflection_Assertion) Set(fd protoreflect.FieldDescriptor, value pr // It panics if the field does not contain a composite type. // // Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Assertion) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Account) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Assertion.accumulator": + case "did.v1.Account.accumulator": if x.Accumulator == nil { x.Accumulator = make(map[string][]byte) } - value := &_Assertion_6_map{m: &x.Accumulator} + value := &_Account_6_map{m: &x.Accumulator} return protoreflect.ValueOfMap(value) - case "did.v1.Assertion.did": - panic(fmt.Errorf("field did of message did.v1.Assertion is not mutable")) - case "did.v1.Assertion.controller": - panic(fmt.Errorf("field controller of message did.v1.Assertion is not mutable")) - case "did.v1.Assertion.subject": - panic(fmt.Errorf("field subject of message did.v1.Assertion is not mutable")) - case "did.v1.Assertion.public_key_hex": - panic(fmt.Errorf("field public_key_hex of message did.v1.Assertion is not mutable")) - case "did.v1.Assertion.assertion_type": - panic(fmt.Errorf("field assertion_type of message did.v1.Assertion is not mutable")) - case "did.v1.Assertion.creation_block": - panic(fmt.Errorf("field creation_block of message did.v1.Assertion is not mutable")) + case "did.v1.Account.did": + panic(fmt.Errorf("field did of message did.v1.Account is not mutable")) + case "did.v1.Account.controller": + panic(fmt.Errorf("field controller of message did.v1.Account is not mutable")) + case "did.v1.Account.subject": + panic(fmt.Errorf("field subject of message did.v1.Account is not mutable")) + case "did.v1.Account.public_key_hex": + panic(fmt.Errorf("field public_key_hex of message did.v1.Account is not mutable")) + case "did.v1.Account.assertion_type": + panic(fmt.Errorf("field assertion_type of message did.v1.Account is not mutable")) + case "did.v1.Account.creation_block": + panic(fmt.Errorf("field creation_block of message did.v1.Account is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Assertion")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Account")) } - panic(fmt.Errorf("message did.v1.Assertion does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Account does not contain field %s", fd.FullName())) } } // NewField returns a new value that is assignable to the field // for the given descriptor. For scalars, this returns the default value. // For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Assertion) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Account) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Assertion.did": + case "did.v1.Account.did": return protoreflect.ValueOfString("") - case "did.v1.Assertion.controller": + case "did.v1.Account.controller": return protoreflect.ValueOfString("") - case "did.v1.Assertion.subject": + case "did.v1.Account.subject": return protoreflect.ValueOfString("") - case "did.v1.Assertion.public_key_hex": + case "did.v1.Account.public_key_hex": return protoreflect.ValueOfString("") - case "did.v1.Assertion.assertion_type": + case "did.v1.Account.assertion_type": return protoreflect.ValueOfString("") - case "did.v1.Assertion.accumulator": + case "did.v1.Account.accumulator": m := make(map[string][]byte) - return protoreflect.ValueOfMap(&_Assertion_6_map{m: &m}) - case "did.v1.Assertion.creation_block": + return protoreflect.ValueOfMap(&_Account_6_map{m: &m}) + case "did.v1.Account.creation_block": return protoreflect.ValueOfInt64(int64(0)) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Assertion")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Account")) } - panic(fmt.Errorf("message did.v1.Assertion does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.Account does not contain field %s", fd.FullName())) } } // WhichOneof reports which field within the oneof is populated, // returning nil if none are populated. // It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Assertion) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { +func (x *fastReflection_Account) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Assertion", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in did.v1.Account", d.FullName())) } panic("unreachable") } @@ -449,7 +449,7 @@ func (x *fastReflection_Assertion) WhichOneof(d protoreflect.OneofDescriptor) pr // GetUnknown retrieves the entire list of unknown fields. // The caller may only mutate the contents of the RawFields // if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Assertion) GetUnknown() protoreflect.RawFields { +func (x *fastReflection_Account) GetUnknown() protoreflect.RawFields { return x.unknownFields } @@ -460,7 +460,7 @@ func (x *fastReflection_Assertion) GetUnknown() protoreflect.RawFields { // An empty RawFields may be passed to clear the fields. // // SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Assertion) SetUnknown(fields protoreflect.RawFields) { +func (x *fastReflection_Account) SetUnknown(fields protoreflect.RawFields) { x.unknownFields = fields } @@ -472,7 +472,7 @@ func (x *fastReflection_Assertion) SetUnknown(fields protoreflect.RawFields) { // message type, but the details are implementation dependent. // Validity is not part of the protobuf data model, and may not // be preserved in marshaling or other operations. -func (x *fastReflection_Assertion) IsValid() bool { +func (x *fastReflection_Account) IsValid() bool { return x != nil } @@ -482,9 +482,9 @@ func (x *fastReflection_Assertion) IsValid() bool { // The returned methods type is identical to // "google.golang.org/protobuf/runtime/protoiface".Methods. // Consult the protoiface package documentation for details. -func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { +func (x *fastReflection_Account) ProtoMethods() *protoiface.Methods { size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Assertion) + x := input.Message.Interface().(*Account) if x == nil { return protoiface.SizeOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -551,7 +551,7 @@ func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Assertion) + x := input.Message.Interface().(*Account) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -664,7 +664,7 @@ func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Assertion) + x := input.Message.Interface().(*Account) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -696,10 +696,10 @@ func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Assertion: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Account: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Assertion: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Account: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1044,120 +1044,42 @@ func (x *fastReflection_Assertion) ProtoMethods() *protoiface.Methods { } } -var _ protoreflect.Map = (*_Authentication_6_map)(nil) - -type _Authentication_6_map struct { - m *map[string]string -} - -func (x *_Authentication_6_map) Len() int { - if x.m == nil { - return 0 - } - return len(*x.m) -} - -func (x *_Authentication_6_map) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { - if x.m == nil { - return - } - for k, v := range *x.m { - mapKey := (protoreflect.MapKey)(protoreflect.ValueOfString(k)) - mapValue := protoreflect.ValueOfString(v) - if !f(mapKey, mapValue) { - break - } - } -} - -func (x *_Authentication_6_map) Has(key protoreflect.MapKey) bool { - if x.m == nil { - return false - } - keyUnwrapped := key.String() - concreteValue := keyUnwrapped - _, ok := (*x.m)[concreteValue] - return ok -} - -func (x *_Authentication_6_map) Clear(key protoreflect.MapKey) { - if x.m == nil { - return - } - keyUnwrapped := key.String() - concreteKey := keyUnwrapped - delete(*x.m, concreteKey) -} - -func (x *_Authentication_6_map) Get(key protoreflect.MapKey) protoreflect.Value { - if x.m == nil { - return protoreflect.Value{} - } - keyUnwrapped := key.String() - concreteKey := keyUnwrapped - v, ok := (*x.m)[concreteKey] - if !ok { - return protoreflect.Value{} - } - return protoreflect.ValueOfString(v) -} - -func (x *_Authentication_6_map) Set(key protoreflect.MapKey, value protoreflect.Value) { - if !key.IsValid() || !value.IsValid() { - panic("invalid key or value provided") - } - keyUnwrapped := key.String() - concreteKey := keyUnwrapped - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.m)[concreteKey] = concreteValue -} - -func (x *_Authentication_6_map) Mutable(key protoreflect.MapKey) protoreflect.Value { - panic("should not call Mutable on protoreflect.Map whose value is not of type protoreflect.Message") -} - -func (x *_Authentication_6_map) NewValue() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Authentication_6_map) IsValid() bool { - return x.m != nil -} - var ( - md_Authentication protoreflect.MessageDescriptor - fd_Authentication_did protoreflect.FieldDescriptor - fd_Authentication_controller protoreflect.FieldDescriptor - fd_Authentication_subject protoreflect.FieldDescriptor - fd_Authentication_public_key_hex protoreflect.FieldDescriptor - fd_Authentication_credential_id protoreflect.FieldDescriptor - fd_Authentication_metadata protoreflect.FieldDescriptor - fd_Authentication_creation_block protoreflect.FieldDescriptor + md_PublicKey protoreflect.MessageDescriptor + fd_PublicKey_number protoreflect.FieldDescriptor + fd_PublicKey_did protoreflect.FieldDescriptor + fd_PublicKey_sonr_address protoreflect.FieldDescriptor + fd_PublicKey_eth_address protoreflect.FieldDescriptor + fd_PublicKey_btc_address protoreflect.FieldDescriptor + fd_PublicKey_public_key_hex protoreflect.FieldDescriptor + fd_PublicKey_ks_val protoreflect.FieldDescriptor + fd_PublicKey_claimed_block protoreflect.FieldDescriptor + fd_PublicKey_creation_block protoreflect.FieldDescriptor ) func init() { file_did_v1_state_proto_init() - md_Authentication = File_did_v1_state_proto.Messages().ByName("Authentication") - fd_Authentication_did = md_Authentication.Fields().ByName("did") - fd_Authentication_controller = md_Authentication.Fields().ByName("controller") - fd_Authentication_subject = md_Authentication.Fields().ByName("subject") - fd_Authentication_public_key_hex = md_Authentication.Fields().ByName("public_key_hex") - fd_Authentication_credential_id = md_Authentication.Fields().ByName("credential_id") - fd_Authentication_metadata = md_Authentication.Fields().ByName("metadata") - fd_Authentication_creation_block = md_Authentication.Fields().ByName("creation_block") + md_PublicKey = File_did_v1_state_proto.Messages().ByName("PublicKey") + fd_PublicKey_number = md_PublicKey.Fields().ByName("number") + fd_PublicKey_did = md_PublicKey.Fields().ByName("did") + fd_PublicKey_sonr_address = md_PublicKey.Fields().ByName("sonr_address") + fd_PublicKey_eth_address = md_PublicKey.Fields().ByName("eth_address") + fd_PublicKey_btc_address = md_PublicKey.Fields().ByName("btc_address") + fd_PublicKey_public_key_hex = md_PublicKey.Fields().ByName("public_key_hex") + fd_PublicKey_ks_val = md_PublicKey.Fields().ByName("ks_val") + fd_PublicKey_claimed_block = md_PublicKey.Fields().ByName("claimed_block") + fd_PublicKey_creation_block = md_PublicKey.Fields().ByName("creation_block") } -var _ protoreflect.Message = (*fastReflection_Authentication)(nil) +var _ protoreflect.Message = (*fastReflection_PublicKey)(nil) -type fastReflection_Authentication Authentication +type fastReflection_PublicKey PublicKey -func (x *Authentication) ProtoReflect() protoreflect.Message { - return (*fastReflection_Authentication)(x) +func (x *PublicKey) ProtoReflect() protoreflect.Message { + return (*fastReflection_PublicKey)(x) } -func (x *Authentication) slowProtoReflect() protoreflect.Message { +func (x *PublicKey) slowProtoReflect() protoreflect.Message { mi := &file_did_v1_state_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1169,43 +1091,43 @@ func (x *Authentication) slowProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -var _fastReflection_Authentication_messageType fastReflection_Authentication_messageType -var _ protoreflect.MessageType = fastReflection_Authentication_messageType{} +var _fastReflection_PublicKey_messageType fastReflection_PublicKey_messageType +var _ protoreflect.MessageType = fastReflection_PublicKey_messageType{} -type fastReflection_Authentication_messageType struct{} +type fastReflection_PublicKey_messageType struct{} -func (x fastReflection_Authentication_messageType) Zero() protoreflect.Message { - return (*fastReflection_Authentication)(nil) +func (x fastReflection_PublicKey_messageType) Zero() protoreflect.Message { + return (*fastReflection_PublicKey)(nil) } -func (x fastReflection_Authentication_messageType) New() protoreflect.Message { - return new(fastReflection_Authentication) +func (x fastReflection_PublicKey_messageType) New() protoreflect.Message { + return new(fastReflection_PublicKey) } -func (x fastReflection_Authentication_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Authentication +func (x fastReflection_PublicKey_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_PublicKey } // Descriptor returns message descriptor, which contains only the protobuf // type information for the message. -func (x *fastReflection_Authentication) Descriptor() protoreflect.MessageDescriptor { - return md_Authentication +func (x *fastReflection_PublicKey) Descriptor() protoreflect.MessageDescriptor { + return md_PublicKey } // Type returns the message type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the message descriptor be used instead. -func (x *fastReflection_Authentication) Type() protoreflect.MessageType { - return _fastReflection_Authentication_messageType +func (x *fastReflection_PublicKey) Type() protoreflect.MessageType { + return _fastReflection_PublicKey_messageType } // New returns a newly allocated and mutable empty message. -func (x *fastReflection_Authentication) New() protoreflect.Message { - return new(fastReflection_Authentication) +func (x *fastReflection_PublicKey) New() protoreflect.Message { + return new(fastReflection_PublicKey) } // Interface unwraps the message reflection interface and // returns the underlying ProtoMessage interface. -func (x *fastReflection_Authentication) Interface() protoreflect.ProtoMessage { - return (*Authentication)(x) +func (x *fastReflection_PublicKey) Interface() protoreflect.ProtoMessage { + return (*PublicKey)(x) } // Range iterates over every populated field in an undefined order, @@ -1213,1718 +1135,58 @@ func (x *fastReflection_Authentication) Interface() protoreflect.ProtoMessage { // Range returns immediately if f returns false. // While iterating, mutating operations may only be performed // on the current field descriptor. -func (x *fastReflection_Authentication) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Did != "" { - value := protoreflect.ValueOfString(x.Did) - if !f(fd_Authentication_did, value) { - return - } - } - if x.Controller != "" { - value := protoreflect.ValueOfString(x.Controller) - if !f(fd_Authentication_controller, value) { - return - } - } - if x.Subject != "" { - value := protoreflect.ValueOfString(x.Subject) - if !f(fd_Authentication_subject, value) { - return - } - } - if x.PublicKeyHex != "" { - value := protoreflect.ValueOfString(x.PublicKeyHex) - if !f(fd_Authentication_public_key_hex, value) { - return - } - } - if len(x.CredentialId) != 0 { - value := protoreflect.ValueOfBytes(x.CredentialId) - if !f(fd_Authentication_credential_id, value) { - return - } - } - if len(x.Metadata) != 0 { - value := protoreflect.ValueOfMap(&_Authentication_6_map{m: &x.Metadata}) - if !f(fd_Authentication_metadata, value) { - return - } - } - if x.CreationBlock != int64(0) { - value := protoreflect.ValueOfInt64(x.CreationBlock) - if !f(fd_Authentication_creation_block, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Authentication) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.Authentication.did": - return x.Did != "" - case "did.v1.Authentication.controller": - return x.Controller != "" - case "did.v1.Authentication.subject": - return x.Subject != "" - case "did.v1.Authentication.public_key_hex": - return x.PublicKeyHex != "" - case "did.v1.Authentication.credential_id": - return len(x.CredentialId) != 0 - case "did.v1.Authentication.metadata": - return len(x.Metadata) != 0 - case "did.v1.Authentication.creation_block": - return x.CreationBlock != int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Authentication")) - } - panic(fmt.Errorf("message did.v1.Authentication does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Authentication) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.Authentication.did": - x.Did = "" - case "did.v1.Authentication.controller": - x.Controller = "" - case "did.v1.Authentication.subject": - x.Subject = "" - case "did.v1.Authentication.public_key_hex": - x.PublicKeyHex = "" - case "did.v1.Authentication.credential_id": - x.CredentialId = nil - case "did.v1.Authentication.metadata": - x.Metadata = nil - case "did.v1.Authentication.creation_block": - x.CreationBlock = int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Authentication")) - } - panic(fmt.Errorf("message did.v1.Authentication does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Authentication) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.Authentication.did": - value := x.Did - return protoreflect.ValueOfString(value) - case "did.v1.Authentication.controller": - value := x.Controller - return protoreflect.ValueOfString(value) - case "did.v1.Authentication.subject": - value := x.Subject - return protoreflect.ValueOfString(value) - case "did.v1.Authentication.public_key_hex": - value := x.PublicKeyHex - return protoreflect.ValueOfString(value) - case "did.v1.Authentication.credential_id": - value := x.CredentialId - return protoreflect.ValueOfBytes(value) - case "did.v1.Authentication.metadata": - if len(x.Metadata) == 0 { - return protoreflect.ValueOfMap(&_Authentication_6_map{}) - } - mapValue := &_Authentication_6_map{m: &x.Metadata} - return protoreflect.ValueOfMap(mapValue) - case "did.v1.Authentication.creation_block": - value := x.CreationBlock - return protoreflect.ValueOfInt64(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Authentication")) - } - panic(fmt.Errorf("message did.v1.Authentication does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Authentication) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.Authentication.did": - x.Did = value.Interface().(string) - case "did.v1.Authentication.controller": - x.Controller = value.Interface().(string) - case "did.v1.Authentication.subject": - x.Subject = value.Interface().(string) - case "did.v1.Authentication.public_key_hex": - x.PublicKeyHex = value.Interface().(string) - case "did.v1.Authentication.credential_id": - x.CredentialId = value.Bytes() - case "did.v1.Authentication.metadata": - mv := value.Map() - cmv := mv.(*_Authentication_6_map) - x.Metadata = *cmv.m - case "did.v1.Authentication.creation_block": - x.CreationBlock = value.Int() - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Authentication")) - } - panic(fmt.Errorf("message did.v1.Authentication does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Authentication) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Authentication.metadata": - if x.Metadata == nil { - x.Metadata = make(map[string]string) - } - value := &_Authentication_6_map{m: &x.Metadata} - return protoreflect.ValueOfMap(value) - case "did.v1.Authentication.did": - panic(fmt.Errorf("field did of message did.v1.Authentication is not mutable")) - case "did.v1.Authentication.controller": - panic(fmt.Errorf("field controller of message did.v1.Authentication is not mutable")) - case "did.v1.Authentication.subject": - panic(fmt.Errorf("field subject of message did.v1.Authentication is not mutable")) - case "did.v1.Authentication.public_key_hex": - panic(fmt.Errorf("field public_key_hex of message did.v1.Authentication is not mutable")) - case "did.v1.Authentication.credential_id": - panic(fmt.Errorf("field credential_id of message did.v1.Authentication is not mutable")) - case "did.v1.Authentication.creation_block": - panic(fmt.Errorf("field creation_block of message did.v1.Authentication is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Authentication")) - } - panic(fmt.Errorf("message did.v1.Authentication does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Authentication) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Authentication.did": - return protoreflect.ValueOfString("") - case "did.v1.Authentication.controller": - return protoreflect.ValueOfString("") - case "did.v1.Authentication.subject": - return protoreflect.ValueOfString("") - case "did.v1.Authentication.public_key_hex": - return protoreflect.ValueOfString("") - case "did.v1.Authentication.credential_id": - return protoreflect.ValueOfBytes(nil) - case "did.v1.Authentication.metadata": - m := make(map[string]string) - return protoreflect.ValueOfMap(&_Authentication_6_map{m: &m}) - case "did.v1.Authentication.creation_block": - return protoreflect.ValueOfInt64(int64(0)) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Authentication")) - } - panic(fmt.Errorf("message did.v1.Authentication does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Authentication) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Authentication", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Authentication) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Authentication) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Authentication) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Authentication) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Authentication) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Did) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Controller) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Subject) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.PublicKeyHex) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.CredentialId) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if len(x.Metadata) > 0 { - SiZeMaP := func(k string, v string) { - mapEntrySize := 1 + len(k) + runtime.Sov(uint64(len(k))) + 1 + len(v) + runtime.Sov(uint64(len(v))) - n += mapEntrySize + 1 + runtime.Sov(uint64(mapEntrySize)) - } - if options.Deterministic { - sortme := make([]string, 0, len(x.Metadata)) - for k := range x.Metadata { - sortme = append(sortme, k) - } - sort.Strings(sortme) - for _, k := range sortme { - v := x.Metadata[k] - SiZeMaP(k, v) - } - } else { - for k, v := range x.Metadata { - SiZeMaP(k, v) - } - } - } - if x.CreationBlock != 0 { - n += 1 + runtime.Sov(uint64(x.CreationBlock)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Authentication) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.CreationBlock != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.CreationBlock)) - i-- - dAtA[i] = 0x38 - } - if len(x.Metadata) > 0 { - MaRsHaLmAp := func(k string, v string) (protoiface.MarshalOutput, error) { - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = runtime.EncodeVarint(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = runtime.EncodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = runtime.EncodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x32 - return protoiface.MarshalOutput{}, nil - } - if options.Deterministic { - keysForMetadata := make([]string, 0, len(x.Metadata)) - for k := range x.Metadata { - keysForMetadata = append(keysForMetadata, string(k)) - } - sort.Slice(keysForMetadata, func(i, j int) bool { - return keysForMetadata[i] < keysForMetadata[j] - }) - for iNdEx := len(keysForMetadata) - 1; iNdEx >= 0; iNdEx-- { - v := x.Metadata[string(keysForMetadata[iNdEx])] - out, err := MaRsHaLmAp(keysForMetadata[iNdEx], v) - if err != nil { - return out, err - } - } - } else { - for k := range x.Metadata { - v := x.Metadata[k] - out, err := MaRsHaLmAp(k, v) - if err != nil { - return out, err - } - } - } - } - if len(x.CredentialId) > 0 { - i -= len(x.CredentialId) - copy(dAtA[i:], x.CredentialId) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.CredentialId))) - i-- - dAtA[i] = 0x2a - } - if len(x.PublicKeyHex) > 0 { - i -= len(x.PublicKeyHex) - copy(dAtA[i:], x.PublicKeyHex) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicKeyHex))) - i-- - dAtA[i] = 0x22 - } - if len(x.Subject) > 0 { - i -= len(x.Subject) - copy(dAtA[i:], x.Subject) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Subject))) - i-- - dAtA[i] = 0x1a - } - if len(x.Controller) > 0 { - i -= len(x.Controller) - copy(dAtA[i:], x.Controller) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) - i-- - dAtA[i] = 0x12 - } - if len(x.Did) > 0 { - i -= len(x.Did) - copy(dAtA[i:], x.Did) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Did))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Authentication) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Authentication: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Authentication: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Did", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Did = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.PublicKeyHex = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CredentialId", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.CredentialId = append(x.CredentialId[:0], dAtA[iNdEx:postIndex]...) - if x.CredentialId == nil { - x.CredentialId = []byte{} - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Metadata == nil { - x.Metadata = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postStringIndexmapkey > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postStringIndexmapvalue > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - x.Metadata[mapkey] = mapvalue - iNdEx = postIndex - case 7: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CreationBlock", wireType) - } - x.CreationBlock = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.CreationBlock |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_Biscuit protoreflect.MessageDescriptor - fd_Biscuit_id protoreflect.FieldDescriptor - fd_Biscuit_controller protoreflect.FieldDescriptor - fd_Biscuit_subject protoreflect.FieldDescriptor - fd_Biscuit_origin protoreflect.FieldDescriptor - fd_Biscuit_expiry_height protoreflect.FieldDescriptor - fd_Biscuit_macaroon protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_state_proto_init() - md_Biscuit = File_did_v1_state_proto.Messages().ByName("Biscuit") - fd_Biscuit_id = md_Biscuit.Fields().ByName("id") - fd_Biscuit_controller = md_Biscuit.Fields().ByName("controller") - fd_Biscuit_subject = md_Biscuit.Fields().ByName("subject") - fd_Biscuit_origin = md_Biscuit.Fields().ByName("origin") - fd_Biscuit_expiry_height = md_Biscuit.Fields().ByName("expiry_height") - fd_Biscuit_macaroon = md_Biscuit.Fields().ByName("macaroon") -} - -var _ protoreflect.Message = (*fastReflection_Biscuit)(nil) - -type fastReflection_Biscuit Biscuit - -func (x *Biscuit) ProtoReflect() protoreflect.Message { - return (*fastReflection_Biscuit)(x) -} - -func (x *Biscuit) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_state_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Biscuit_messageType fastReflection_Biscuit_messageType -var _ protoreflect.MessageType = fastReflection_Biscuit_messageType{} - -type fastReflection_Biscuit_messageType struct{} - -func (x fastReflection_Biscuit_messageType) Zero() protoreflect.Message { - return (*fastReflection_Biscuit)(nil) -} -func (x fastReflection_Biscuit_messageType) New() protoreflect.Message { - return new(fastReflection_Biscuit) -} -func (x fastReflection_Biscuit_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Biscuit -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Biscuit) Descriptor() protoreflect.MessageDescriptor { - return md_Biscuit -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Biscuit) Type() protoreflect.MessageType { - return _fastReflection_Biscuit_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Biscuit) New() protoreflect.Message { - return new(fastReflection_Biscuit) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Biscuit) Interface() protoreflect.ProtoMessage { - return (*Biscuit)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Biscuit) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != uint64(0) { - value := protoreflect.ValueOfUint64(x.Id) - if !f(fd_Biscuit_id, value) { - return - } - } - if x.Controller != "" { - value := protoreflect.ValueOfString(x.Controller) - if !f(fd_Biscuit_controller, value) { - return - } - } - if x.Subject != "" { - value := protoreflect.ValueOfString(x.Subject) - if !f(fd_Biscuit_subject, value) { - return - } - } - if x.Origin != "" { - value := protoreflect.ValueOfString(x.Origin) - if !f(fd_Biscuit_origin, value) { - return - } - } - if x.ExpiryHeight != int64(0) { - value := protoreflect.ValueOfInt64(x.ExpiryHeight) - if !f(fd_Biscuit_expiry_height, value) { - return - } - } - if x.Macaroon != "" { - value := protoreflect.ValueOfString(x.Macaroon) - if !f(fd_Biscuit_macaroon, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Biscuit) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "did.v1.Biscuit.id": - return x.Id != uint64(0) - case "did.v1.Biscuit.controller": - return x.Controller != "" - case "did.v1.Biscuit.subject": - return x.Subject != "" - case "did.v1.Biscuit.origin": - return x.Origin != "" - case "did.v1.Biscuit.expiry_height": - return x.ExpiryHeight != int64(0) - case "did.v1.Biscuit.macaroon": - return x.Macaroon != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) - } - panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Biscuit) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "did.v1.Biscuit.id": - x.Id = uint64(0) - case "did.v1.Biscuit.controller": - x.Controller = "" - case "did.v1.Biscuit.subject": - x.Subject = "" - case "did.v1.Biscuit.origin": - x.Origin = "" - case "did.v1.Biscuit.expiry_height": - x.ExpiryHeight = int64(0) - case "did.v1.Biscuit.macaroon": - x.Macaroon = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) - } - panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Biscuit) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "did.v1.Biscuit.id": - value := x.Id - return protoreflect.ValueOfUint64(value) - case "did.v1.Biscuit.controller": - value := x.Controller - return protoreflect.ValueOfString(value) - case "did.v1.Biscuit.subject": - value := x.Subject - return protoreflect.ValueOfString(value) - case "did.v1.Biscuit.origin": - value := x.Origin - return protoreflect.ValueOfString(value) - case "did.v1.Biscuit.expiry_height": - value := x.ExpiryHeight - return protoreflect.ValueOfInt64(value) - case "did.v1.Biscuit.macaroon": - value := x.Macaroon - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) - } - panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Biscuit) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "did.v1.Biscuit.id": - x.Id = value.Uint() - case "did.v1.Biscuit.controller": - x.Controller = value.Interface().(string) - case "did.v1.Biscuit.subject": - x.Subject = value.Interface().(string) - case "did.v1.Biscuit.origin": - x.Origin = value.Interface().(string) - case "did.v1.Biscuit.expiry_height": - x.ExpiryHeight = value.Int() - case "did.v1.Biscuit.macaroon": - x.Macaroon = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) - } - panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Biscuit) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Biscuit.id": - panic(fmt.Errorf("field id of message did.v1.Biscuit is not mutable")) - case "did.v1.Biscuit.controller": - panic(fmt.Errorf("field controller of message did.v1.Biscuit is not mutable")) - case "did.v1.Biscuit.subject": - panic(fmt.Errorf("field subject of message did.v1.Biscuit is not mutable")) - case "did.v1.Biscuit.origin": - panic(fmt.Errorf("field origin of message did.v1.Biscuit is not mutable")) - case "did.v1.Biscuit.expiry_height": - panic(fmt.Errorf("field expiry_height of message did.v1.Biscuit is not mutable")) - case "did.v1.Biscuit.macaroon": - panic(fmt.Errorf("field macaroon of message did.v1.Biscuit is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) - } - panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Biscuit) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "did.v1.Biscuit.id": - return protoreflect.ValueOfUint64(uint64(0)) - case "did.v1.Biscuit.controller": - return protoreflect.ValueOfString("") - case "did.v1.Biscuit.subject": - return protoreflect.ValueOfString("") - case "did.v1.Biscuit.origin": - return protoreflect.ValueOfString("") - case "did.v1.Biscuit.expiry_height": - return protoreflect.ValueOfInt64(int64(0)) - case "did.v1.Biscuit.macaroon": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Biscuit")) - } - panic(fmt.Errorf("message did.v1.Biscuit does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Biscuit) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Biscuit", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Biscuit) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Biscuit) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Biscuit) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Biscuit) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Biscuit) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Id != 0 { - n += 1 + runtime.Sov(uint64(x.Id)) - } - l = len(x.Controller) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Subject) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Origin) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.ExpiryHeight != 0 { - n += 1 + runtime.Sov(uint64(x.ExpiryHeight)) - } - l = len(x.Macaroon) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Biscuit) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Macaroon) > 0 { - i -= len(x.Macaroon) - copy(dAtA[i:], x.Macaroon) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Macaroon))) - i-- - dAtA[i] = 0x32 - } - if x.ExpiryHeight != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryHeight)) - i-- - dAtA[i] = 0x28 - } - if len(x.Origin) > 0 { - i -= len(x.Origin) - copy(dAtA[i:], x.Origin) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) - i-- - dAtA[i] = 0x22 - } - if len(x.Subject) > 0 { - i -= len(x.Subject) - copy(dAtA[i:], x.Subject) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Subject))) - i-- - dAtA[i] = 0x1a - } - if len(x.Controller) > 0 { - i -= len(x.Controller) - copy(dAtA[i:], x.Controller) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) - i-- - dAtA[i] = 0x12 - } - if x.Id != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Id)) - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Biscuit) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Biscuit: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Biscuit: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - x.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) - } - x.ExpiryHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.ExpiryHeight |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Macaroon", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Macaroon = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_Controller protoreflect.MessageDescriptor - fd_Controller_number protoreflect.FieldDescriptor - fd_Controller_did protoreflect.FieldDescriptor - fd_Controller_sonr_address protoreflect.FieldDescriptor - fd_Controller_eth_address protoreflect.FieldDescriptor - fd_Controller_btc_address protoreflect.FieldDescriptor - fd_Controller_public_key_hex protoreflect.FieldDescriptor - fd_Controller_ks_val protoreflect.FieldDescriptor - fd_Controller_claimed_block protoreflect.FieldDescriptor - fd_Controller_creation_block protoreflect.FieldDescriptor -) - -func init() { - file_did_v1_state_proto_init() - md_Controller = File_did_v1_state_proto.Messages().ByName("Controller") - fd_Controller_number = md_Controller.Fields().ByName("number") - fd_Controller_did = md_Controller.Fields().ByName("did") - fd_Controller_sonr_address = md_Controller.Fields().ByName("sonr_address") - fd_Controller_eth_address = md_Controller.Fields().ByName("eth_address") - fd_Controller_btc_address = md_Controller.Fields().ByName("btc_address") - fd_Controller_public_key_hex = md_Controller.Fields().ByName("public_key_hex") - fd_Controller_ks_val = md_Controller.Fields().ByName("ks_val") - fd_Controller_claimed_block = md_Controller.Fields().ByName("claimed_block") - fd_Controller_creation_block = md_Controller.Fields().ByName("creation_block") -} - -var _ protoreflect.Message = (*fastReflection_Controller)(nil) - -type fastReflection_Controller Controller - -func (x *Controller) ProtoReflect() protoreflect.Message { - return (*fastReflection_Controller)(x) -} - -func (x *Controller) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_state_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Controller_messageType fastReflection_Controller_messageType -var _ protoreflect.MessageType = fastReflection_Controller_messageType{} - -type fastReflection_Controller_messageType struct{} - -func (x fastReflection_Controller_messageType) Zero() protoreflect.Message { - return (*fastReflection_Controller)(nil) -} -func (x fastReflection_Controller_messageType) New() protoreflect.Message { - return new(fastReflection_Controller) -} -func (x fastReflection_Controller_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Controller -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Controller) Descriptor() protoreflect.MessageDescriptor { - return md_Controller -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Controller) Type() protoreflect.MessageType { - return _fastReflection_Controller_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Controller) New() protoreflect.Message { - return new(fastReflection_Controller) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Controller) Interface() protoreflect.ProtoMessage { - return (*Controller)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Controller) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +func (x *fastReflection_PublicKey) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { if x.Number != uint64(0) { value := protoreflect.ValueOfUint64(x.Number) - if !f(fd_Controller_number, value) { + if !f(fd_PublicKey_number, value) { return } } if x.Did != "" { value := protoreflect.ValueOfString(x.Did) - if !f(fd_Controller_did, value) { + if !f(fd_PublicKey_did, value) { return } } if x.SonrAddress != "" { value := protoreflect.ValueOfString(x.SonrAddress) - if !f(fd_Controller_sonr_address, value) { + if !f(fd_PublicKey_sonr_address, value) { return } } if x.EthAddress != "" { value := protoreflect.ValueOfString(x.EthAddress) - if !f(fd_Controller_eth_address, value) { + if !f(fd_PublicKey_eth_address, value) { return } } if x.BtcAddress != "" { value := protoreflect.ValueOfString(x.BtcAddress) - if !f(fd_Controller_btc_address, value) { + if !f(fd_PublicKey_btc_address, value) { return } } if x.PublicKeyHex != "" { value := protoreflect.ValueOfString(x.PublicKeyHex) - if !f(fd_Controller_public_key_hex, value) { + if !f(fd_PublicKey_public_key_hex, value) { return } } if x.KsVal != "" { value := protoreflect.ValueOfString(x.KsVal) - if !f(fd_Controller_ks_val, value) { + if !f(fd_PublicKey_ks_val, value) { return } } if x.ClaimedBlock != int64(0) { value := protoreflect.ValueOfInt64(x.ClaimedBlock) - if !f(fd_Controller_claimed_block, value) { + if !f(fd_PublicKey_claimed_block, value) { return } } if x.CreationBlock != int64(0) { value := protoreflect.ValueOfInt64(x.CreationBlock) - if !f(fd_Controller_creation_block, value) { + if !f(fd_PublicKey_creation_block, value) { return } } @@ -2941,31 +1203,31 @@ func (x *fastReflection_Controller) Range(f func(protoreflect.FieldDescriptor, p // In other cases (aside from the nullable cases above), // a proto3 scalar field is populated if it contains a non-zero value, and // a repeated field is populated if it is non-empty. -func (x *fastReflection_Controller) Has(fd protoreflect.FieldDescriptor) bool { +func (x *fastReflection_PublicKey) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "did.v1.Controller.number": + case "did.v1.PublicKey.number": return x.Number != uint64(0) - case "did.v1.Controller.did": + case "did.v1.PublicKey.did": return x.Did != "" - case "did.v1.Controller.sonr_address": + case "did.v1.PublicKey.sonr_address": return x.SonrAddress != "" - case "did.v1.Controller.eth_address": + case "did.v1.PublicKey.eth_address": return x.EthAddress != "" - case "did.v1.Controller.btc_address": + case "did.v1.PublicKey.btc_address": return x.BtcAddress != "" - case "did.v1.Controller.public_key_hex": + case "did.v1.PublicKey.public_key_hex": return x.PublicKeyHex != "" - case "did.v1.Controller.ks_val": + case "did.v1.PublicKey.ks_val": return x.KsVal != "" - case "did.v1.Controller.claimed_block": + case "did.v1.PublicKey.claimed_block": return x.ClaimedBlock != int64(0) - case "did.v1.Controller.creation_block": + case "did.v1.PublicKey.creation_block": return x.CreationBlock != int64(0) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Controller")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PublicKey")) } - panic(fmt.Errorf("message did.v1.Controller does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.PublicKey does not contain field %s", fd.FullName())) } } @@ -2975,31 +1237,31 @@ func (x *fastReflection_Controller) Has(fd protoreflect.FieldDescriptor) bool { // associated with the given field number. // // Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Controller) Clear(fd protoreflect.FieldDescriptor) { +func (x *fastReflection_PublicKey) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "did.v1.Controller.number": + case "did.v1.PublicKey.number": x.Number = uint64(0) - case "did.v1.Controller.did": + case "did.v1.PublicKey.did": x.Did = "" - case "did.v1.Controller.sonr_address": + case "did.v1.PublicKey.sonr_address": x.SonrAddress = "" - case "did.v1.Controller.eth_address": + case "did.v1.PublicKey.eth_address": x.EthAddress = "" - case "did.v1.Controller.btc_address": + case "did.v1.PublicKey.btc_address": x.BtcAddress = "" - case "did.v1.Controller.public_key_hex": + case "did.v1.PublicKey.public_key_hex": x.PublicKeyHex = "" - case "did.v1.Controller.ks_val": + case "did.v1.PublicKey.ks_val": x.KsVal = "" - case "did.v1.Controller.claimed_block": + case "did.v1.PublicKey.claimed_block": x.ClaimedBlock = int64(0) - case "did.v1.Controller.creation_block": + case "did.v1.PublicKey.creation_block": x.CreationBlock = int64(0) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Controller")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PublicKey")) } - panic(fmt.Errorf("message did.v1.Controller does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.PublicKey does not contain field %s", fd.FullName())) } } @@ -3009,40 +1271,40 @@ func (x *fastReflection_Controller) Clear(fd protoreflect.FieldDescriptor) { // the default value of a bytes scalar is guaranteed to be a copy. // For unpopulated composite types, it returns an empty, read-only view // of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Controller) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_PublicKey) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "did.v1.Controller.number": + case "did.v1.PublicKey.number": value := x.Number return protoreflect.ValueOfUint64(value) - case "did.v1.Controller.did": + case "did.v1.PublicKey.did": value := x.Did return protoreflect.ValueOfString(value) - case "did.v1.Controller.sonr_address": + case "did.v1.PublicKey.sonr_address": value := x.SonrAddress return protoreflect.ValueOfString(value) - case "did.v1.Controller.eth_address": + case "did.v1.PublicKey.eth_address": value := x.EthAddress return protoreflect.ValueOfString(value) - case "did.v1.Controller.btc_address": + case "did.v1.PublicKey.btc_address": value := x.BtcAddress return protoreflect.ValueOfString(value) - case "did.v1.Controller.public_key_hex": + case "did.v1.PublicKey.public_key_hex": value := x.PublicKeyHex return protoreflect.ValueOfString(value) - case "did.v1.Controller.ks_val": + case "did.v1.PublicKey.ks_val": value := x.KsVal return protoreflect.ValueOfString(value) - case "did.v1.Controller.claimed_block": + case "did.v1.PublicKey.claimed_block": value := x.ClaimedBlock return protoreflect.ValueOfInt64(value) - case "did.v1.Controller.creation_block": + case "did.v1.PublicKey.creation_block": value := x.CreationBlock return protoreflect.ValueOfInt64(value) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Controller")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PublicKey")) } - panic(fmt.Errorf("message did.v1.Controller does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message did.v1.PublicKey does not contain field %s", descriptor.FullName())) } } @@ -3056,31 +1318,31 @@ func (x *fastReflection_Controller) Get(descriptor protoreflect.FieldDescriptor) // empty, read-only value, then it panics. // // Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Controller) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { +func (x *fastReflection_PublicKey) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "did.v1.Controller.number": + case "did.v1.PublicKey.number": x.Number = value.Uint() - case "did.v1.Controller.did": + case "did.v1.PublicKey.did": x.Did = value.Interface().(string) - case "did.v1.Controller.sonr_address": + case "did.v1.PublicKey.sonr_address": x.SonrAddress = value.Interface().(string) - case "did.v1.Controller.eth_address": + case "did.v1.PublicKey.eth_address": x.EthAddress = value.Interface().(string) - case "did.v1.Controller.btc_address": + case "did.v1.PublicKey.btc_address": x.BtcAddress = value.Interface().(string) - case "did.v1.Controller.public_key_hex": + case "did.v1.PublicKey.public_key_hex": x.PublicKeyHex = value.Interface().(string) - case "did.v1.Controller.ks_val": + case "did.v1.PublicKey.ks_val": x.KsVal = value.Interface().(string) - case "did.v1.Controller.claimed_block": + case "did.v1.PublicKey.claimed_block": x.ClaimedBlock = value.Int() - case "did.v1.Controller.creation_block": + case "did.v1.PublicKey.creation_block": x.CreationBlock = value.Int() default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Controller")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PublicKey")) } - panic(fmt.Errorf("message did.v1.Controller does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.PublicKey does not contain field %s", fd.FullName())) } } @@ -3094,72 +1356,72 @@ func (x *fastReflection_Controller) Set(fd protoreflect.FieldDescriptor, value p // It panics if the field does not contain a composite type. // // Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Controller) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_PublicKey) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Controller.number": - panic(fmt.Errorf("field number of message did.v1.Controller is not mutable")) - case "did.v1.Controller.did": - panic(fmt.Errorf("field did of message did.v1.Controller is not mutable")) - case "did.v1.Controller.sonr_address": - panic(fmt.Errorf("field sonr_address of message did.v1.Controller is not mutable")) - case "did.v1.Controller.eth_address": - panic(fmt.Errorf("field eth_address of message did.v1.Controller is not mutable")) - case "did.v1.Controller.btc_address": - panic(fmt.Errorf("field btc_address of message did.v1.Controller is not mutable")) - case "did.v1.Controller.public_key_hex": - panic(fmt.Errorf("field public_key_hex of message did.v1.Controller is not mutable")) - case "did.v1.Controller.ks_val": - panic(fmt.Errorf("field ks_val of message did.v1.Controller is not mutable")) - case "did.v1.Controller.claimed_block": - panic(fmt.Errorf("field claimed_block of message did.v1.Controller is not mutable")) - case "did.v1.Controller.creation_block": - panic(fmt.Errorf("field creation_block of message did.v1.Controller is not mutable")) + case "did.v1.PublicKey.number": + panic(fmt.Errorf("field number of message did.v1.PublicKey is not mutable")) + case "did.v1.PublicKey.did": + panic(fmt.Errorf("field did of message did.v1.PublicKey is not mutable")) + case "did.v1.PublicKey.sonr_address": + panic(fmt.Errorf("field sonr_address of message did.v1.PublicKey is not mutable")) + case "did.v1.PublicKey.eth_address": + panic(fmt.Errorf("field eth_address of message did.v1.PublicKey is not mutable")) + case "did.v1.PublicKey.btc_address": + panic(fmt.Errorf("field btc_address of message did.v1.PublicKey is not mutable")) + case "did.v1.PublicKey.public_key_hex": + panic(fmt.Errorf("field public_key_hex of message did.v1.PublicKey is not mutable")) + case "did.v1.PublicKey.ks_val": + panic(fmt.Errorf("field ks_val of message did.v1.PublicKey is not mutable")) + case "did.v1.PublicKey.claimed_block": + panic(fmt.Errorf("field claimed_block of message did.v1.PublicKey is not mutable")) + case "did.v1.PublicKey.creation_block": + panic(fmt.Errorf("field creation_block of message did.v1.PublicKey is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Controller")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PublicKey")) } - panic(fmt.Errorf("message did.v1.Controller does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.PublicKey does not contain field %s", fd.FullName())) } } // NewField returns a new value that is assignable to the field // for the given descriptor. For scalars, this returns the default value. // For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Controller) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_PublicKey) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "did.v1.Controller.number": + case "did.v1.PublicKey.number": return protoreflect.ValueOfUint64(uint64(0)) - case "did.v1.Controller.did": + case "did.v1.PublicKey.did": return protoreflect.ValueOfString("") - case "did.v1.Controller.sonr_address": + case "did.v1.PublicKey.sonr_address": return protoreflect.ValueOfString("") - case "did.v1.Controller.eth_address": + case "did.v1.PublicKey.eth_address": return protoreflect.ValueOfString("") - case "did.v1.Controller.btc_address": + case "did.v1.PublicKey.btc_address": return protoreflect.ValueOfString("") - case "did.v1.Controller.public_key_hex": + case "did.v1.PublicKey.public_key_hex": return protoreflect.ValueOfString("") - case "did.v1.Controller.ks_val": + case "did.v1.PublicKey.ks_val": return protoreflect.ValueOfString("") - case "did.v1.Controller.claimed_block": + case "did.v1.PublicKey.claimed_block": return protoreflect.ValueOfInt64(int64(0)) - case "did.v1.Controller.creation_block": + case "did.v1.PublicKey.creation_block": return protoreflect.ValueOfInt64(int64(0)) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.Controller")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: did.v1.PublicKey")) } - panic(fmt.Errorf("message did.v1.Controller does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message did.v1.PublicKey does not contain field %s", fd.FullName())) } } // WhichOneof reports which field within the oneof is populated, // returning nil if none are populated. // It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Controller) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { +func (x *fastReflection_PublicKey) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in did.v1.Controller", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in did.v1.PublicKey", d.FullName())) } panic("unreachable") } @@ -3167,7 +1429,7 @@ func (x *fastReflection_Controller) WhichOneof(d protoreflect.OneofDescriptor) p // GetUnknown retrieves the entire list of unknown fields. // The caller may only mutate the contents of the RawFields // if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Controller) GetUnknown() protoreflect.RawFields { +func (x *fastReflection_PublicKey) GetUnknown() protoreflect.RawFields { return x.unknownFields } @@ -3178,7 +1440,7 @@ func (x *fastReflection_Controller) GetUnknown() protoreflect.RawFields { // An empty RawFields may be passed to clear the fields. // // SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Controller) SetUnknown(fields protoreflect.RawFields) { +func (x *fastReflection_PublicKey) SetUnknown(fields protoreflect.RawFields) { x.unknownFields = fields } @@ -3190,7 +1452,7 @@ func (x *fastReflection_Controller) SetUnknown(fields protoreflect.RawFields) { // message type, but the details are implementation dependent. // Validity is not part of the protobuf data model, and may not // be preserved in marshaling or other operations. -func (x *fastReflection_Controller) IsValid() bool { +func (x *fastReflection_PublicKey) IsValid() bool { return x != nil } @@ -3200,9 +1462,9 @@ func (x *fastReflection_Controller) IsValid() bool { // The returned methods type is identical to // "google.golang.org/protobuf/runtime/protoiface".Methods. // Consult the protoiface package documentation for details. -func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { +func (x *fastReflection_PublicKey) ProtoMethods() *protoiface.Methods { size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Controller) + x := input.Message.Interface().(*PublicKey) if x == nil { return protoiface.SizeOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -3257,7 +1519,7 @@ func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Controller) + x := input.Message.Interface().(*PublicKey) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -3344,7 +1606,7 @@ func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Controller) + x := input.Message.Interface().(*PublicKey) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -3376,10 +1638,10 @@ func (x *fastReflection_Controller) ProtoMethods() *protoiface.Methods { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Controller: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: PublicKey: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Controller: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3784,7 +2046,7 @@ func (x *Verification) ProtoReflect() protoreflect.Message { } func (x *Verification) slowProtoReflect() protoreflect.Message { - mi := &file_did_v1_state_proto_msgTypes[4] + mi := &file_did_v1_state_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4835,7 +3097,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type Assertion struct { +type Account struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -4856,8 +3118,8 @@ type Assertion struct { CreationBlock int64 `protobuf:"varint,7,opt,name=creation_block,json=creationBlock,proto3" json:"creation_block,omitempty"` } -func (x *Assertion) Reset() { - *x = Assertion{} +func (x *Account) Reset() { + *x = Account{} if protoimpl.UnsafeEnabled { mi := &file_did_v1_state_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -4865,234 +3127,68 @@ func (x *Assertion) Reset() { } } -func (x *Assertion) String() string { +func (x *Account) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Assertion) ProtoMessage() {} +func (*Account) ProtoMessage() {} -// Deprecated: Use Assertion.ProtoReflect.Descriptor instead. -func (*Assertion) Descriptor() ([]byte, []int) { +// Deprecated: Use Account.ProtoReflect.Descriptor instead. +func (*Account) Descriptor() ([]byte, []int) { return file_did_v1_state_proto_rawDescGZIP(), []int{0} } -func (x *Assertion) GetDid() string { +func (x *Account) GetDid() string { if x != nil { return x.Did } return "" } -func (x *Assertion) GetController() string { +func (x *Account) GetController() string { if x != nil { return x.Controller } return "" } -func (x *Assertion) GetSubject() string { +func (x *Account) GetSubject() string { if x != nil { return x.Subject } return "" } -func (x *Assertion) GetPublicKeyHex() string { +func (x *Account) GetPublicKeyHex() string { if x != nil { return x.PublicKeyHex } return "" } -func (x *Assertion) GetAssertionType() string { +func (x *Account) GetAssertionType() string { if x != nil { return x.AssertionType } return "" } -func (x *Assertion) GetAccumulator() map[string][]byte { +func (x *Account) GetAccumulator() map[string][]byte { if x != nil { return x.Accumulator } return nil } -func (x *Assertion) GetCreationBlock() int64 { +func (x *Account) GetCreationBlock() int64 { if x != nil { return x.CreationBlock } return 0 } -type Authentication struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The unique identifier of the authentication - Did string `protobuf:"bytes,1,opt,name=did,proto3" json:"did,omitempty"` - // The authentication of the DID - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - // Origin of the authentication - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - // string is the verification method - PublicKeyHex string `protobuf:"bytes,4,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` - // CredentialID is the byte representation of the credential ID - CredentialId []byte `protobuf:"bytes,5,opt,name=credential_id,json=credentialId,proto3" json:"credential_id,omitempty"` - // Metadata of the authentication - Metadata map[string]string `protobuf:"bytes,6,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // CreationBlock is the block number of the creation of the authentication - CreationBlock int64 `protobuf:"varint,7,opt,name=creation_block,json=creationBlock,proto3" json:"creation_block,omitempty"` -} - -func (x *Authentication) Reset() { - *x = Authentication{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_state_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Authentication) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Authentication) ProtoMessage() {} - -// Deprecated: Use Authentication.ProtoReflect.Descriptor instead. -func (*Authentication) Descriptor() ([]byte, []int) { - return file_did_v1_state_proto_rawDescGZIP(), []int{1} -} - -func (x *Authentication) GetDid() string { - if x != nil { - return x.Did - } - return "" -} - -func (x *Authentication) GetController() string { - if x != nil { - return x.Controller - } - return "" -} - -func (x *Authentication) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *Authentication) GetPublicKeyHex() string { - if x != nil { - return x.PublicKeyHex - } - return "" -} - -func (x *Authentication) GetCredentialId() []byte { - if x != nil { - return x.CredentialId - } - return nil -} - -func (x *Authentication) GetMetadata() map[string]string { - if x != nil { - return x.Metadata - } - return nil -} - -func (x *Authentication) GetCreationBlock() int64 { - if x != nil { - return x.CreationBlock - } - return 0 -} - -// Macaroon is a Macaroon message type. -type Biscuit struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` - ExpiryHeight int64 `protobuf:"varint,5,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` - Macaroon string `protobuf:"bytes,6,opt,name=macaroon,proto3" json:"macaroon,omitempty"` -} - -func (x *Biscuit) Reset() { - *x = Biscuit{} - if protoimpl.UnsafeEnabled { - mi := &file_did_v1_state_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Biscuit) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Biscuit) ProtoMessage() {} - -// Deprecated: Use Biscuit.ProtoReflect.Descriptor instead. -func (*Biscuit) Descriptor() ([]byte, []int) { - return file_did_v1_state_proto_rawDescGZIP(), []int{2} -} - -func (x *Biscuit) GetId() uint64 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *Biscuit) GetController() string { - if x != nil { - return x.Controller - } - return "" -} - -func (x *Biscuit) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *Biscuit) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *Biscuit) GetExpiryHeight() int64 { - if x != nil { - return x.ExpiryHeight - } - return 0 -} - -func (x *Biscuit) GetMacaroon() string { - if x != nil { - return x.Macaroon - } - return "" -} - -// Controller represents a Sonr DWN Vault -type Controller struct { +// PublicKey represents a public key +type PublicKey struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -5117,83 +3213,83 @@ type Controller struct { CreationBlock int64 `protobuf:"varint,9,opt,name=creation_block,json=creationBlock,proto3" json:"creation_block,omitempty"` } -func (x *Controller) Reset() { - *x = Controller{} +func (x *PublicKey) Reset() { + *x = PublicKey{} if protoimpl.UnsafeEnabled { - mi := &file_did_v1_state_proto_msgTypes[3] + mi := &file_did_v1_state_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *Controller) String() string { +func (x *PublicKey) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Controller) ProtoMessage() {} +func (*PublicKey) ProtoMessage() {} -// Deprecated: Use Controller.ProtoReflect.Descriptor instead. -func (*Controller) Descriptor() ([]byte, []int) { - return file_did_v1_state_proto_rawDescGZIP(), []int{3} +// Deprecated: Use PublicKey.ProtoReflect.Descriptor instead. +func (*PublicKey) Descriptor() ([]byte, []int) { + return file_did_v1_state_proto_rawDescGZIP(), []int{1} } -func (x *Controller) GetNumber() uint64 { +func (x *PublicKey) GetNumber() uint64 { if x != nil { return x.Number } return 0 } -func (x *Controller) GetDid() string { +func (x *PublicKey) GetDid() string { if x != nil { return x.Did } return "" } -func (x *Controller) GetSonrAddress() string { +func (x *PublicKey) GetSonrAddress() string { if x != nil { return x.SonrAddress } return "" } -func (x *Controller) GetEthAddress() string { +func (x *PublicKey) GetEthAddress() string { if x != nil { return x.EthAddress } return "" } -func (x *Controller) GetBtcAddress() string { +func (x *PublicKey) GetBtcAddress() string { if x != nil { return x.BtcAddress } return "" } -func (x *Controller) GetPublicKeyHex() string { +func (x *PublicKey) GetPublicKeyHex() string { if x != nil { return x.PublicKeyHex } return "" } -func (x *Controller) GetKsVal() string { +func (x *PublicKey) GetKsVal() string { if x != nil { return x.KsVal } return "" } -func (x *Controller) GetClaimedBlock() int64 { +func (x *PublicKey) GetClaimedBlock() int64 { if x != nil { return x.ClaimedBlock } return 0 } -func (x *Controller) GetCreationBlock() int64 { +func (x *PublicKey) GetCreationBlock() int64 { if x != nil { return x.CreationBlock } @@ -5229,7 +3325,7 @@ type Verification struct { func (x *Verification) Reset() { *x = Verification{} if protoimpl.UnsafeEnabled { - mi := &file_did_v1_state_proto_msgTypes[4] + mi := &file_did_v1_state_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5243,7 +3339,7 @@ func (*Verification) ProtoMessage() {} // Deprecated: Use Verification.ProtoReflect.Descriptor instead. func (*Verification) Descriptor() ([]byte, []int) { - return file_did_v1_state_proto_rawDescGZIP(), []int{4} + return file_did_v1_state_proto_rawDescGZIP(), []int{2} } func (x *Verification) GetDid() string { @@ -5316,132 +3412,95 @@ var file_did_v1_state_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, - 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfc, 0x02, 0x0a, 0x09, - 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, - 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, 0x12, 0x25, 0x0a, 0x0e, 0x61, - 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, - 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x63, 0x75, 0x6d, - 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x63, 0x63, - 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, - 0x3e, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, - 0x29, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x23, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x18, - 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x10, 0x01, 0x18, 0x01, 0x18, 0x01, 0x22, 0xf8, 0x02, 0x0a, 0x0e, 0x41, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, - 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, - 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, - 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, 0x12, - 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, - 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x3b, 0x0a, - 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x29, 0xf2, 0x9e, 0xd3, 0x8e, - 0x03, 0x23, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x12, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, - 0x01, 0x18, 0x01, 0x18, 0x02, 0x22, 0xd4, 0x01, 0x0a, 0x07, 0x42, 0x69, 0x73, 0x63, 0x75, 0x69, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, - 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, - 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, - 0x67, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x61, - 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x61, - 0x72, 0x6f, 0x6f, 0x6e, 0x3a, 0x26, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x20, 0x0a, 0x06, 0x0a, 0x02, - 0x69, 0x64, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, - 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x05, 0x22, 0xff, 0x02, 0x0a, - 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6f, 0x6e, 0x72, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x6e, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x74, 0x68, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, - 0x74, 0x68, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x74, 0x63, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x62, 0x74, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, - 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6b, 0x73, 0x56, 0x61, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x61, 0x69, 0x6d, - 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, - 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x25, 0x0a, 0x0e, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x3a, 0x59, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x53, 0x0a, 0x0a, 0x0a, 0x06, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0c, 0x73, 0x6f, 0x6e, 0x72, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x01, 0x18, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x65, - 0x74, 0x68, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x02, 0x18, 0x01, 0x12, 0x11, - 0x0a, 0x0b, 0x62, 0x74, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x03, 0x18, - 0x01, 0x12, 0x09, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x10, 0x04, 0x18, 0x01, 0x18, 0x03, 0x22, 0xfb, - 0x03, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, - 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, - 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x69, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x5f, 0x68, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, 0x12, 0x2b, 0x0a, 0x11, 0x76, 0x65, 0x72, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x10, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, - 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf8, 0x02, 0x0a, 0x07, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, + 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x73, 0x73, + 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x42, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, + 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, + 0x61, 0x74, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x3e, 0x0a, 0x10, 0x41, + 0x63, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x29, 0xf2, 0x9e, 0xd3, + 0x8e, 0x03, 0x23, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x12, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x10, 0x01, 0x18, 0x01, 0x18, 0x01, 0x22, 0xfe, 0x02, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, + 0x64, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x21, + 0x0a, 0x0c, 0x73, 0x6f, 0x6e, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6f, 0x6e, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x74, 0x68, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x74, 0x68, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x74, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x74, 0x63, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, + 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, 0x78, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x73, 0x5f, + 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x73, 0x56, 0x61, 0x6c, + 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x3b, 0x0a, 0x0d, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x71, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, - 0x6b, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x0e, 0x69, 0x73, 0x73, 0x75, - 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x01, 0x18, 0x01, 0x12, 0x22, - 0x0a, 0x1c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x64, 0x69, 0x64, - 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x2c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x10, 0x02, - 0x18, 0x01, 0x12, 0x26, 0x0a, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, - 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x10, 0x03, 0x18, 0x01, 0x18, 0x06, 0x42, 0x7a, 0x0a, 0x0a, - 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, - 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, - 0xca, 0x02, 0x06, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, - 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x07, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x3a, 0x59, 0xf2, 0x9e, + 0xd3, 0x8e, 0x03, 0x53, 0x0a, 0x0a, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x10, 0x01, + 0x12, 0x12, 0x0a, 0x0c, 0x73, 0x6f, 0x6e, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x10, 0x01, 0x18, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x65, 0x74, 0x68, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x10, 0x02, 0x18, 0x01, 0x12, 0x11, 0x0a, 0x0b, 0x62, 0x74, 0x63, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x03, 0x18, 0x01, 0x12, 0x09, 0x0a, 0x03, 0x64, 0x69, + 0x64, 0x10, 0x04, 0x18, 0x01, 0x18, 0x02, 0x22, 0xfb, 0x03, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x69, + 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x64, 0x69, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, + 0x75, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x72, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x48, 0x65, + 0x78, 0x12, 0x2b, 0x0a, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3e, + 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x64, 0x69, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, + 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x3a, 0x71, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x6b, 0x0a, 0x05, 0x0a, 0x03, 0x64, 0x69, + 0x64, 0x12, 0x14, 0x0a, 0x0e, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x2c, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x10, 0x01, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x1c, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2c, 0x64, 0x69, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x2c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x10, 0x02, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x20, 0x76, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x10, + 0x03, 0x18, 0x01, 0x18, 0x03, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x69, 0x64, + 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, + 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, + 0x64, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x69, 0x64, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, + 0xaa, 0x02, 0x06, 0x44, 0x69, 0x64, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x69, 0x64, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x69, 0x64, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x69, 0x64, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5456,26 +3515,22 @@ func file_did_v1_state_proto_rawDescGZIP() []byte { return file_did_v1_state_proto_rawDescData } -var file_did_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_did_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_did_v1_state_proto_goTypes = []interface{}{ - (*Assertion)(nil), // 0: did.v1.Assertion - (*Authentication)(nil), // 1: did.v1.Authentication - (*Biscuit)(nil), // 2: did.v1.Biscuit - (*Controller)(nil), // 3: did.v1.Controller - (*Verification)(nil), // 4: did.v1.Verification - nil, // 5: did.v1.Assertion.AccumulatorEntry - nil, // 6: did.v1.Authentication.MetadataEntry - nil, // 7: did.v1.Verification.MetadataEntry + (*Account)(nil), // 0: did.v1.Account + (*PublicKey)(nil), // 1: did.v1.PublicKey + (*Verification)(nil), // 2: did.v1.Verification + nil, // 3: did.v1.Account.AccumulatorEntry + nil, // 4: did.v1.Verification.MetadataEntry } var file_did_v1_state_proto_depIdxs = []int32{ - 5, // 0: did.v1.Assertion.accumulator:type_name -> did.v1.Assertion.AccumulatorEntry - 6, // 1: did.v1.Authentication.metadata:type_name -> did.v1.Authentication.MetadataEntry - 7, // 2: did.v1.Verification.metadata:type_name -> did.v1.Verification.MetadataEntry - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 3, // 0: did.v1.Account.accumulator:type_name -> did.v1.Account.AccumulatorEntry + 4, // 1: did.v1.Verification.metadata:type_name -> did.v1.Verification.MetadataEntry + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_did_v1_state_proto_init() } @@ -5486,7 +3541,7 @@ func file_did_v1_state_proto_init() { file_did_v1_genesis_proto_init() if !protoimpl.UnsafeEnabled { file_did_v1_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Assertion); i { + switch v := v.(*Account); i { case 0: return &v.state case 1: @@ -5498,7 +3553,7 @@ func file_did_v1_state_proto_init() { } } file_did_v1_state_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Authentication); i { + switch v := v.(*PublicKey); i { case 0: return &v.state case 1: @@ -5510,30 +3565,6 @@ func file_did_v1_state_proto_init() { } } file_did_v1_state_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Biscuit); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_did_v1_state_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Controller); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_did_v1_state_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Verification); i { case 0: return &v.state @@ -5552,7 +3583,7 @@ func file_did_v1_state_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_did_v1_state_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/api/dwn/v1/state.cosmos_orm.go b/api/dwn/v1/state.cosmos_orm.go index 8bf5048fc..a6aa6c240 100644 --- a/api/dwn/v1/state.cosmos_orm.go +++ b/api/dwn/v1/state.cosmos_orm.go @@ -9,145 +9,278 @@ import ( ormerrors "cosmossdk.io/orm/types/ormerrors" ) -type ExampleDataTable interface { - Insert(ctx context.Context, exampleData *ExampleData) error - Update(ctx context.Context, exampleData *ExampleData) error - Save(ctx context.Context, exampleData *ExampleData) error - Delete(ctx context.Context, exampleData *ExampleData) error +type CredentialTable interface { + Insert(ctx context.Context, credential *Credential) error + Update(ctx context.Context, credential *Credential) error + Save(ctx context.Context, credential *Credential) error + Delete(ctx context.Context, credential *Credential) error Has(ctx context.Context, account []byte) (found bool, err error) // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, account []byte) (*ExampleData, error) - List(ctx context.Context, prefixKey ExampleDataIndexKey, opts ...ormlist.Option) (ExampleDataIterator, error) - ListRange(ctx context.Context, from, to ExampleDataIndexKey, opts ...ormlist.Option) (ExampleDataIterator, error) - DeleteBy(ctx context.Context, prefixKey ExampleDataIndexKey) error - DeleteRange(ctx context.Context, from, to ExampleDataIndexKey) error + Get(ctx context.Context, account []byte) (*Credential, error) + List(ctx context.Context, prefixKey CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) + ListRange(ctx context.Context, from, to CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) + DeleteBy(ctx context.Context, prefixKey CredentialIndexKey) error + DeleteRange(ctx context.Context, from, to CredentialIndexKey) error doNotImplement() } -type ExampleDataIterator struct { +type CredentialIterator struct { ormtable.Iterator } -func (i ExampleDataIterator) Value() (*ExampleData, error) { - var exampleData ExampleData - err := i.UnmarshalMessage(&exampleData) - return &exampleData, err +func (i CredentialIterator) Value() (*Credential, error) { + var credential Credential + err := i.UnmarshalMessage(&credential) + return &credential, err } -type ExampleDataIndexKey interface { +type CredentialIndexKey interface { id() uint32 values() []interface{} - exampleDataIndexKey() + credentialIndexKey() } // primary key starting index.. -type ExampleDataPrimaryKey = ExampleDataAccountIndexKey +type CredentialPrimaryKey = CredentialAccountIndexKey -type ExampleDataAccountIndexKey struct { +type CredentialAccountIndexKey struct { vs []interface{} } -func (x ExampleDataAccountIndexKey) id() uint32 { return 0 } -func (x ExampleDataAccountIndexKey) values() []interface{} { return x.vs } -func (x ExampleDataAccountIndexKey) exampleDataIndexKey() {} +func (x CredentialAccountIndexKey) id() uint32 { return 0 } +func (x CredentialAccountIndexKey) values() []interface{} { return x.vs } +func (x CredentialAccountIndexKey) credentialIndexKey() {} -func (this ExampleDataAccountIndexKey) WithAccount(account []byte) ExampleDataAccountIndexKey { +func (this CredentialAccountIndexKey) WithAccount(account []byte) CredentialAccountIndexKey { this.vs = []interface{}{account} return this } -type ExampleDataAmountIndexKey struct { +type CredentialAmountIndexKey struct { vs []interface{} } -func (x ExampleDataAmountIndexKey) id() uint32 { return 1 } -func (x ExampleDataAmountIndexKey) values() []interface{} { return x.vs } -func (x ExampleDataAmountIndexKey) exampleDataIndexKey() {} +func (x CredentialAmountIndexKey) id() uint32 { return 1 } +func (x CredentialAmountIndexKey) values() []interface{} { return x.vs } +func (x CredentialAmountIndexKey) credentialIndexKey() {} -func (this ExampleDataAmountIndexKey) WithAmount(amount uint64) ExampleDataAmountIndexKey { +func (this CredentialAmountIndexKey) WithAmount(amount uint64) CredentialAmountIndexKey { this.vs = []interface{}{amount} return this } -type exampleDataTable struct { +type credentialTable struct { table ormtable.Table } -func (this exampleDataTable) Insert(ctx context.Context, exampleData *ExampleData) error { - return this.table.Insert(ctx, exampleData) +func (this credentialTable) Insert(ctx context.Context, credential *Credential) error { + return this.table.Insert(ctx, credential) } -func (this exampleDataTable) Update(ctx context.Context, exampleData *ExampleData) error { - return this.table.Update(ctx, exampleData) +func (this credentialTable) Update(ctx context.Context, credential *Credential) error { + return this.table.Update(ctx, credential) } -func (this exampleDataTable) Save(ctx context.Context, exampleData *ExampleData) error { - return this.table.Save(ctx, exampleData) +func (this credentialTable) Save(ctx context.Context, credential *Credential) error { + return this.table.Save(ctx, credential) } -func (this exampleDataTable) Delete(ctx context.Context, exampleData *ExampleData) error { - return this.table.Delete(ctx, exampleData) +func (this credentialTable) Delete(ctx context.Context, credential *Credential) error { + return this.table.Delete(ctx, credential) } -func (this exampleDataTable) Has(ctx context.Context, account []byte) (found bool, err error) { +func (this credentialTable) Has(ctx context.Context, account []byte) (found bool, err error) { return this.table.PrimaryKey().Has(ctx, account) } -func (this exampleDataTable) Get(ctx context.Context, account []byte) (*ExampleData, error) { - var exampleData ExampleData - found, err := this.table.PrimaryKey().Get(ctx, &exampleData, account) +func (this credentialTable) Get(ctx context.Context, account []byte) (*Credential, error) { + var credential Credential + found, err := this.table.PrimaryKey().Get(ctx, &credential, account) if err != nil { return nil, err } if !found { return nil, ormerrors.NotFound } - return &exampleData, nil + return &credential, nil } -func (this exampleDataTable) List(ctx context.Context, prefixKey ExampleDataIndexKey, opts ...ormlist.Option) (ExampleDataIterator, error) { +func (this credentialTable) List(ctx context.Context, prefixKey CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) { it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return ExampleDataIterator{it}, err + return CredentialIterator{it}, err } -func (this exampleDataTable) ListRange(ctx context.Context, from, to ExampleDataIndexKey, opts ...ormlist.Option) (ExampleDataIterator, error) { +func (this credentialTable) ListRange(ctx context.Context, from, to CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) { it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return ExampleDataIterator{it}, err + return CredentialIterator{it}, err } -func (this exampleDataTable) DeleteBy(ctx context.Context, prefixKey ExampleDataIndexKey) error { +func (this credentialTable) DeleteBy(ctx context.Context, prefixKey CredentialIndexKey) error { return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) } -func (this exampleDataTable) DeleteRange(ctx context.Context, from, to ExampleDataIndexKey) error { +func (this credentialTable) DeleteRange(ctx context.Context, from, to CredentialIndexKey) error { return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) } -func (this exampleDataTable) doNotImplement() {} +func (this credentialTable) doNotImplement() {} -var _ ExampleDataTable = exampleDataTable{} +var _ CredentialTable = credentialTable{} -func NewExampleDataTable(db ormtable.Schema) (ExampleDataTable, error) { - table := db.GetTable(&ExampleData{}) +func NewCredentialTable(db ormtable.Schema) (CredentialTable, error) { + table := db.GetTable(&Credential{}) if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&ExampleData{}).ProtoReflect().Descriptor().FullName())) + return nil, ormerrors.TableNotFound.Wrap(string((&Credential{}).ProtoReflect().Descriptor().FullName())) } - return exampleDataTable{table}, nil + return credentialTable{table}, nil +} + +type ProfileTable interface { + Insert(ctx context.Context, profile *Profile) error + Update(ctx context.Context, profile *Profile) error + Save(ctx context.Context, profile *Profile) error + Delete(ctx context.Context, profile *Profile) error + Has(ctx context.Context, account []byte) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, account []byte) (*Profile, error) + List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) + ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) + DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error + DeleteRange(ctx context.Context, from, to ProfileIndexKey) error + + doNotImplement() +} + +type ProfileIterator struct { + ormtable.Iterator +} + +func (i ProfileIterator) Value() (*Profile, error) { + var profile Profile + err := i.UnmarshalMessage(&profile) + return &profile, err +} + +type ProfileIndexKey interface { + id() uint32 + values() []interface{} + profileIndexKey() +} + +// primary key starting index.. +type ProfilePrimaryKey = ProfileAccountIndexKey + +type ProfileAccountIndexKey struct { + vs []interface{} +} + +func (x ProfileAccountIndexKey) id() uint32 { return 0 } +func (x ProfileAccountIndexKey) values() []interface{} { return x.vs } +func (x ProfileAccountIndexKey) profileIndexKey() {} + +func (this ProfileAccountIndexKey) WithAccount(account []byte) ProfileAccountIndexKey { + this.vs = []interface{}{account} + return this +} + +type ProfileAmountIndexKey struct { + vs []interface{} +} + +func (x ProfileAmountIndexKey) id() uint32 { return 1 } +func (x ProfileAmountIndexKey) values() []interface{} { return x.vs } +func (x ProfileAmountIndexKey) profileIndexKey() {} + +func (this ProfileAmountIndexKey) WithAmount(amount uint64) ProfileAmountIndexKey { + this.vs = []interface{}{amount} + return this +} + +type profileTable struct { + table ormtable.Table +} + +func (this profileTable) Insert(ctx context.Context, profile *Profile) error { + return this.table.Insert(ctx, profile) +} + +func (this profileTable) Update(ctx context.Context, profile *Profile) error { + return this.table.Update(ctx, profile) +} + +func (this profileTable) Save(ctx context.Context, profile *Profile) error { + return this.table.Save(ctx, profile) +} + +func (this profileTable) Delete(ctx context.Context, profile *Profile) error { + return this.table.Delete(ctx, profile) +} + +func (this profileTable) Has(ctx context.Context, account []byte) (found bool, err error) { + return this.table.PrimaryKey().Has(ctx, account) +} + +func (this profileTable) Get(ctx context.Context, account []byte) (*Profile, error) { + var profile Profile + found, err := this.table.PrimaryKey().Get(ctx, &profile, account) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &profile, nil +} + +func (this profileTable) List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { + it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) + return ProfileIterator{it}, err +} + +func (this profileTable) ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { + it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) + return ProfileIterator{it}, err +} + +func (this profileTable) DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error { + return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) +} + +func (this profileTable) DeleteRange(ctx context.Context, from, to ProfileIndexKey) error { + return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) +} + +func (this profileTable) doNotImplement() {} + +var _ ProfileTable = profileTable{} + +func NewProfileTable(db ormtable.Schema) (ProfileTable, error) { + table := db.GetTable(&Profile{}) + if table == nil { + return nil, ormerrors.TableNotFound.Wrap(string((&Profile{}).ProtoReflect().Descriptor().FullName())) + } + return profileTable{table}, nil } type StateStore interface { - ExampleDataTable() ExampleDataTable + CredentialTable() CredentialTable + ProfileTable() ProfileTable doNotImplement() } type stateStore struct { - exampleData ExampleDataTable + credential CredentialTable + profile ProfileTable } -func (x stateStore) ExampleDataTable() ExampleDataTable { - return x.exampleData +func (x stateStore) CredentialTable() CredentialTable { + return x.credential +} + +func (x stateStore) ProfileTable() ProfileTable { + return x.profile } func (stateStore) doNotImplement() {} @@ -155,12 +288,18 @@ func (stateStore) doNotImplement() {} var _ StateStore = stateStore{} func NewStateStore(db ormtable.Schema) (StateStore, error) { - exampleDataTable, err := NewExampleDataTable(db) + credentialTable, err := NewCredentialTable(db) + if err != nil { + return nil, err + } + + profileTable, err := NewProfileTable(db) if err != nil { return nil, err } return stateStore{ - exampleDataTable, + credentialTable, + profileTable, }, nil } diff --git a/api/dwn/v1/state.pulsar.go b/api/dwn/v1/state.pulsar.go index 77acde27b..eba069b68 100644 --- a/api/dwn/v1/state.pulsar.go +++ b/api/dwn/v1/state.pulsar.go @@ -14,27 +14,27 @@ import ( ) var ( - md_ExampleData protoreflect.MessageDescriptor - fd_ExampleData_account protoreflect.FieldDescriptor - fd_ExampleData_amount protoreflect.FieldDescriptor + md_Credential protoreflect.MessageDescriptor + fd_Credential_account protoreflect.FieldDescriptor + fd_Credential_amount protoreflect.FieldDescriptor ) func init() { file_dwn_v1_state_proto_init() - md_ExampleData = File_dwn_v1_state_proto.Messages().ByName("ExampleData") - fd_ExampleData_account = md_ExampleData.Fields().ByName("account") - fd_ExampleData_amount = md_ExampleData.Fields().ByName("amount") + md_Credential = File_dwn_v1_state_proto.Messages().ByName("Credential") + fd_Credential_account = md_Credential.Fields().ByName("account") + fd_Credential_amount = md_Credential.Fields().ByName("amount") } -var _ protoreflect.Message = (*fastReflection_ExampleData)(nil) +var _ protoreflect.Message = (*fastReflection_Credential)(nil) -type fastReflection_ExampleData ExampleData +type fastReflection_Credential Credential -func (x *ExampleData) ProtoReflect() protoreflect.Message { - return (*fastReflection_ExampleData)(x) +func (x *Credential) ProtoReflect() protoreflect.Message { + return (*fastReflection_Credential)(x) } -func (x *ExampleData) slowProtoReflect() protoreflect.Message { +func (x *Credential) slowProtoReflect() protoreflect.Message { mi := &file_dwn_v1_state_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -46,43 +46,43 @@ func (x *ExampleData) slowProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -var _fastReflection_ExampleData_messageType fastReflection_ExampleData_messageType -var _ protoreflect.MessageType = fastReflection_ExampleData_messageType{} +var _fastReflection_Credential_messageType fastReflection_Credential_messageType +var _ protoreflect.MessageType = fastReflection_Credential_messageType{} -type fastReflection_ExampleData_messageType struct{} +type fastReflection_Credential_messageType struct{} -func (x fastReflection_ExampleData_messageType) Zero() protoreflect.Message { - return (*fastReflection_ExampleData)(nil) +func (x fastReflection_Credential_messageType) Zero() protoreflect.Message { + return (*fastReflection_Credential)(nil) } -func (x fastReflection_ExampleData_messageType) New() protoreflect.Message { - return new(fastReflection_ExampleData) +func (x fastReflection_Credential_messageType) New() protoreflect.Message { + return new(fastReflection_Credential) } -func (x fastReflection_ExampleData_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_ExampleData +func (x fastReflection_Credential_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Credential } // Descriptor returns message descriptor, which contains only the protobuf // type information for the message. -func (x *fastReflection_ExampleData) Descriptor() protoreflect.MessageDescriptor { - return md_ExampleData +func (x *fastReflection_Credential) Descriptor() protoreflect.MessageDescriptor { + return md_Credential } // Type returns the message type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the message descriptor be used instead. -func (x *fastReflection_ExampleData) Type() protoreflect.MessageType { - return _fastReflection_ExampleData_messageType +func (x *fastReflection_Credential) Type() protoreflect.MessageType { + return _fastReflection_Credential_messageType } // New returns a newly allocated and mutable empty message. -func (x *fastReflection_ExampleData) New() protoreflect.Message { - return new(fastReflection_ExampleData) +func (x *fastReflection_Credential) New() protoreflect.Message { + return new(fastReflection_Credential) } // Interface unwraps the message reflection interface and // returns the underlying ProtoMessage interface. -func (x *fastReflection_ExampleData) Interface() protoreflect.ProtoMessage { - return (*ExampleData)(x) +func (x *fastReflection_Credential) Interface() protoreflect.ProtoMessage { + return (*Credential)(x) } // Range iterates over every populated field in an undefined order, @@ -90,16 +90,16 @@ func (x *fastReflection_ExampleData) Interface() protoreflect.ProtoMessage { // Range returns immediately if f returns false. // While iterating, mutating operations may only be performed // on the current field descriptor. -func (x *fastReflection_ExampleData) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +func (x *fastReflection_Credential) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { if len(x.Account) != 0 { value := protoreflect.ValueOfBytes(x.Account) - if !f(fd_ExampleData_account, value) { + if !f(fd_Credential_account, value) { return } } if x.Amount != uint64(0) { value := protoreflect.ValueOfUint64(x.Amount) - if !f(fd_ExampleData_amount, value) { + if !f(fd_Credential_amount, value) { return } } @@ -116,17 +116,17 @@ func (x *fastReflection_ExampleData) Range(f func(protoreflect.FieldDescriptor, // In other cases (aside from the nullable cases above), // a proto3 scalar field is populated if it contains a non-zero value, and // a repeated field is populated if it is non-empty. -func (x *fastReflection_ExampleData) Has(fd protoreflect.FieldDescriptor) bool { +func (x *fastReflection_Credential) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "dwn.v1.ExampleData.account": + case "dwn.v1.Credential.account": return len(x.Account) != 0 - case "dwn.v1.ExampleData.amount": + case "dwn.v1.Credential.amount": return x.Amount != uint64(0) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) } - panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message dwn.v1.Credential does not contain field %s", fd.FullName())) } } @@ -136,17 +136,17 @@ func (x *fastReflection_ExampleData) Has(fd protoreflect.FieldDescriptor) bool { // associated with the given field number. // // Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ExampleData) Clear(fd protoreflect.FieldDescriptor) { +func (x *fastReflection_Credential) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "dwn.v1.ExampleData.account": + case "dwn.v1.Credential.account": x.Account = nil - case "dwn.v1.ExampleData.amount": + case "dwn.v1.Credential.amount": x.Amount = uint64(0) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) } - panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message dwn.v1.Credential does not contain field %s", fd.FullName())) } } @@ -156,19 +156,19 @@ func (x *fastReflection_ExampleData) Clear(fd protoreflect.FieldDescriptor) { // the default value of a bytes scalar is guaranteed to be a copy. // For unpopulated composite types, it returns an empty, read-only view // of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_ExampleData) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Credential) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "dwn.v1.ExampleData.account": + case "dwn.v1.Credential.account": value := x.Account return protoreflect.ValueOfBytes(value) - case "dwn.v1.ExampleData.amount": + case "dwn.v1.Credential.amount": value := x.Amount return protoreflect.ValueOfUint64(value) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) } - panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message dwn.v1.Credential does not contain field %s", descriptor.FullName())) } } @@ -182,17 +182,17 @@ func (x *fastReflection_ExampleData) Get(descriptor protoreflect.FieldDescriptor // empty, read-only value, then it panics. // // Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ExampleData) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { +func (x *fastReflection_Credential) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "dwn.v1.ExampleData.account": + case "dwn.v1.Credential.account": x.Account = value.Bytes() - case "dwn.v1.ExampleData.amount": + case "dwn.v1.Credential.amount": x.Amount = value.Uint() default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) } - panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message dwn.v1.Credential does not contain field %s", fd.FullName())) } } @@ -206,44 +206,44 @@ func (x *fastReflection_ExampleData) Set(fd protoreflect.FieldDescriptor, value // It panics if the field does not contain a composite type. // // Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ExampleData) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Credential) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "dwn.v1.ExampleData.account": - panic(fmt.Errorf("field account of message dwn.v1.ExampleData is not mutable")) - case "dwn.v1.ExampleData.amount": - panic(fmt.Errorf("field amount of message dwn.v1.ExampleData is not mutable")) + case "dwn.v1.Credential.account": + panic(fmt.Errorf("field account of message dwn.v1.Credential is not mutable")) + case "dwn.v1.Credential.amount": + panic(fmt.Errorf("field amount of message dwn.v1.Credential is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) } - panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message dwn.v1.Credential does not contain field %s", fd.FullName())) } } // NewField returns a new value that is assignable to the field // for the given descriptor. For scalars, this returns the default value. // For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_ExampleData) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Credential) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "dwn.v1.ExampleData.account": + case "dwn.v1.Credential.account": return protoreflect.ValueOfBytes(nil) - case "dwn.v1.ExampleData.amount": + case "dwn.v1.Credential.amount": return protoreflect.ValueOfUint64(uint64(0)) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.ExampleData")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) } - panic(fmt.Errorf("message dwn.v1.ExampleData does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message dwn.v1.Credential does not contain field %s", fd.FullName())) } } // WhichOneof reports which field within the oneof is populated, // returning nil if none are populated. // It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_ExampleData) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { +func (x *fastReflection_Credential) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in dwn.v1.ExampleData", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.Credential", d.FullName())) } panic("unreachable") } @@ -251,7 +251,7 @@ func (x *fastReflection_ExampleData) WhichOneof(d protoreflect.OneofDescriptor) // GetUnknown retrieves the entire list of unknown fields. // The caller may only mutate the contents of the RawFields // if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_ExampleData) GetUnknown() protoreflect.RawFields { +func (x *fastReflection_Credential) GetUnknown() protoreflect.RawFields { return x.unknownFields } @@ -262,7 +262,7 @@ func (x *fastReflection_ExampleData) GetUnknown() protoreflect.RawFields { // An empty RawFields may be passed to clear the fields. // // SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ExampleData) SetUnknown(fields protoreflect.RawFields) { +func (x *fastReflection_Credential) SetUnknown(fields protoreflect.RawFields) { x.unknownFields = fields } @@ -274,7 +274,7 @@ func (x *fastReflection_ExampleData) SetUnknown(fields protoreflect.RawFields) { // message type, but the details are implementation dependent. // Validity is not part of the protobuf data model, and may not // be preserved in marshaling or other operations. -func (x *fastReflection_ExampleData) IsValid() bool { +func (x *fastReflection_Credential) IsValid() bool { return x != nil } @@ -284,9 +284,9 @@ func (x *fastReflection_ExampleData) IsValid() bool { // The returned methods type is identical to // "google.golang.org/protobuf/runtime/protoiface".Methods. // Consult the protoiface package documentation for details. -func (x *fastReflection_ExampleData) ProtoMethods() *protoiface.Methods { +func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*ExampleData) + x := input.Message.Interface().(*Credential) if x == nil { return protoiface.SizeOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -315,7 +315,7 @@ func (x *fastReflection_ExampleData) ProtoMethods() *protoiface.Methods { } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*ExampleData) + x := input.Message.Interface().(*Credential) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -357,7 +357,7 @@ func (x *fastReflection_ExampleData) ProtoMethods() *protoiface.Methods { }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*ExampleData) + x := input.Message.Interface().(*Credential) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -389,10 +389,480 @@ func (x *fastReflection_ExampleData) ProtoMethods() *protoiface.Methods { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ExampleData: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Credential: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ExampleData: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Credential: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Account = append(x.Account[:0], dAtA[iNdEx:postIndex]...) + if x.Account == nil { + x.Account = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + x.Amount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Amount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_Profile protoreflect.MessageDescriptor + fd_Profile_account protoreflect.FieldDescriptor + fd_Profile_amount protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_state_proto_init() + md_Profile = File_dwn_v1_state_proto.Messages().ByName("Profile") + fd_Profile_account = md_Profile.Fields().ByName("account") + fd_Profile_amount = md_Profile.Fields().ByName("amount") +} + +var _ protoreflect.Message = (*fastReflection_Profile)(nil) + +type fastReflection_Profile Profile + +func (x *Profile) ProtoReflect() protoreflect.Message { + return (*fastReflection_Profile)(x) +} + +func (x *Profile) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_state_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Profile_messageType fastReflection_Profile_messageType +var _ protoreflect.MessageType = fastReflection_Profile_messageType{} + +type fastReflection_Profile_messageType struct{} + +func (x fastReflection_Profile_messageType) Zero() protoreflect.Message { + return (*fastReflection_Profile)(nil) +} +func (x fastReflection_Profile_messageType) New() protoreflect.Message { + return new(fastReflection_Profile) +} +func (x fastReflection_Profile_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Profile +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Profile) Descriptor() protoreflect.MessageDescriptor { + return md_Profile +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Profile) Type() protoreflect.MessageType { + return _fastReflection_Profile_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Profile) New() protoreflect.Message { + return new(fastReflection_Profile) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Profile) Interface() protoreflect.ProtoMessage { + return (*Profile)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Profile) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Account) != 0 { + value := protoreflect.ValueOfBytes(x.Account) + if !f(fd_Profile_account, value) { + return + } + } + if x.Amount != uint64(0) { + value := protoreflect.ValueOfUint64(x.Amount) + if !f(fd_Profile_amount, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Profile) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.Profile.account": + return len(x.Account) != 0 + case "dwn.v1.Profile.amount": + return x.Amount != uint64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Profile")) + } + panic(fmt.Errorf("message dwn.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Profile) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.Profile.account": + x.Account = nil + case "dwn.v1.Profile.amount": + x.Amount = uint64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Profile")) + } + panic(fmt.Errorf("message dwn.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Profile) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.Profile.account": + value := x.Account + return protoreflect.ValueOfBytes(value) + case "dwn.v1.Profile.amount": + value := x.Amount + return protoreflect.ValueOfUint64(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Profile")) + } + panic(fmt.Errorf("message dwn.v1.Profile does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Profile) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.Profile.account": + x.Account = value.Bytes() + case "dwn.v1.Profile.amount": + x.Amount = value.Uint() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Profile")) + } + panic(fmt.Errorf("message dwn.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Profile) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Profile.account": + panic(fmt.Errorf("field account of message dwn.v1.Profile is not mutable")) + case "dwn.v1.Profile.amount": + panic(fmt.Errorf("field amount of message dwn.v1.Profile is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Profile")) + } + panic(fmt.Errorf("message dwn.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Profile) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Profile.account": + return protoreflect.ValueOfBytes(nil) + case "dwn.v1.Profile.amount": + return protoreflect.ValueOfUint64(uint64(0)) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Profile")) + } + panic(fmt.Errorf("message dwn.v1.Profile does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Profile) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.Profile", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Profile) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Profile) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Profile) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Profile) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Profile) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Account) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Amount != 0 { + n += 1 + runtime.Sov(uint64(x.Amount)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Profile) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Amount != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Amount)) + i-- + dAtA[i] = 0x10 + } + if len(x.Account) > 0 { + i -= len(x.Account) + copy(dAtA[i:], x.Account) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Account))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Profile) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Profile: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Profile: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -496,7 +966,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type ExampleData struct { +type Credential struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -505,8 +975,8 @@ type ExampleData struct { Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` } -func (x *ExampleData) Reset() { - *x = ExampleData{} +func (x *Credential) Reset() { + *x = Credential{} if protoimpl.UnsafeEnabled { mi := &file_dwn_v1_state_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -514,25 +984,68 @@ func (x *ExampleData) Reset() { } } -func (x *ExampleData) String() string { +func (x *Credential) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ExampleData) ProtoMessage() {} +func (*Credential) ProtoMessage() {} -// Deprecated: Use ExampleData.ProtoReflect.Descriptor instead. -func (*ExampleData) Descriptor() ([]byte, []int) { +// Deprecated: Use Credential.ProtoReflect.Descriptor instead. +func (*Credential) Descriptor() ([]byte, []int) { return file_dwn_v1_state_proto_rawDescGZIP(), []int{0} } -func (x *ExampleData) GetAccount() []byte { +func (x *Credential) GetAccount() []byte { if x != nil { return x.Account } return nil } -func (x *ExampleData) GetAmount() uint64 { +func (x *Credential) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + +type Profile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Account []byte `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` +} + +func (x *Profile) Reset() { + *x = Profile{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_state_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Profile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Profile) ProtoMessage() {} + +// Deprecated: Use Profile.ProtoReflect.Descriptor instead. +func (*Profile) Descriptor() ([]byte, []int) { + return file_dwn_v1_state_proto_rawDescGZIP(), []int{1} +} + +func (x *Profile) GetAccount() []byte { + if x != nil { + return x.Account + } + return nil +} + +func (x *Profile) GetAmount() uint64 { if x != nil { return x.Amount } @@ -545,21 +1058,27 @@ var file_dwn_v1_state_proto_rawDesc = []byte{ 0x0a, 0x12, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x44, 0x61, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x09, - 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x10, 0x01, 0x18, 0x01, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, - 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, - 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, - 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, - 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x09, 0x0a, + 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x10, 0x01, 0x18, 0x01, 0x22, 0x5c, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x09, 0x0a, 0x07, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x10, 0x01, 0x18, 0x02, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, + 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, + 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x77, 0x6e, + 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, + 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, 0x3a, 0x56, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -574,9 +1093,10 @@ func file_dwn_v1_state_proto_rawDescGZIP() []byte { return file_dwn_v1_state_proto_rawDescData } -var file_dwn_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_dwn_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_dwn_v1_state_proto_goTypes = []interface{}{ - (*ExampleData)(nil), // 0: dwn.v1.ExampleData + (*Credential)(nil), // 0: dwn.v1.Credential + (*Profile)(nil), // 1: dwn.v1.Profile } var file_dwn_v1_state_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -593,7 +1113,19 @@ func file_dwn_v1_state_proto_init() { } if !protoimpl.UnsafeEnabled { file_dwn_v1_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExampleData); i { + switch v := v.(*Credential); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_state_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Profile); i { case 0: return &v.state case 1: @@ -611,7 +1143,7 @@ func file_dwn_v1_state_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_dwn_v1_state_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/api/service/module/v1/module.pulsar.go b/api/service/module/v1/module.pulsar.go deleted file mode 100644 index 0f7d12fc7..000000000 --- a/api/service/module/v1/module.pulsar.go +++ /dev/null @@ -1,500 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package modulev1 - -import ( - _ "cosmossdk.io/api/cosmos/app/v1alpha1" - fmt "fmt" - runtime "github.com/cosmos/cosmos-proto/runtime" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_Module protoreflect.MessageDescriptor -) - -func init() { - file_service_module_v1_module_proto_init() - md_Module = File_service_module_v1_module_proto.Messages().ByName("Module") -} - -var _ protoreflect.Message = (*fastReflection_Module)(nil) - -type fastReflection_Module Module - -func (x *Module) ProtoReflect() protoreflect.Message { - return (*fastReflection_Module)(x) -} - -func (x *Module) slowProtoReflect() protoreflect.Message { - mi := &file_service_module_v1_module_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Module_messageType fastReflection_Module_messageType -var _ protoreflect.MessageType = fastReflection_Module_messageType{} - -type fastReflection_Module_messageType struct{} - -func (x fastReflection_Module_messageType) Zero() protoreflect.Message { - return (*fastReflection_Module)(nil) -} -func (x fastReflection_Module_messageType) New() protoreflect.Message { - return new(fastReflection_Module) -} -func (x fastReflection_Module_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Module -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Module) Descriptor() protoreflect.MessageDescriptor { - return md_Module -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Module) Type() protoreflect.MessageType { - return _fastReflection_Module_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Module) New() protoreflect.Message { - return new(fastReflection_Module) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage { - return (*Module)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) - } - panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) - } - panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) - } - panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) - } - panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) - } - panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.module.v1.Module")) - } - panic(fmt.Errorf("message service.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.module.v1.Module", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Module) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Module) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Module) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Module) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Module) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Module) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: service/module/v1/module.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Module is the app config object of the module. -// Learn more: https://docs.cosmos.network/main/building-modules/depinject -type Module struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Module) Reset() { - *x = Module{} - if protoimpl.UnsafeEnabled { - mi := &file_service_module_v1_module_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Module) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Module) ProtoMessage() {} - -// Deprecated: Use Module.ProtoReflect.Descriptor instead. -func (*Module) Descriptor() ([]byte, []int) { - return file_service_module_v1_module_proto_rawDescGZIP(), []int{0} -} - -var File_service_module_v1_module_proto protoreflect.FileDescriptor - -var file_service_module_v1_module_proto_rawDesc = []byte{ - 0x0a, 0x1e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x11, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, - 0x1e, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x18, 0x0a, 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, - 0xc1, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x6d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, - 0x02, 0x03, 0x53, 0x4d, 0x58, 0xaa, 0x02, 0x11, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x11, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1d, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, - 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, - 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_service_module_v1_module_proto_rawDescOnce sync.Once - file_service_module_v1_module_proto_rawDescData = file_service_module_v1_module_proto_rawDesc -) - -func file_service_module_v1_module_proto_rawDescGZIP() []byte { - file_service_module_v1_module_proto_rawDescOnce.Do(func() { - file_service_module_v1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_module_v1_module_proto_rawDescData) - }) - return file_service_module_v1_module_proto_rawDescData -} - -var file_service_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_service_module_v1_module_proto_goTypes = []interface{}{ - (*Module)(nil), // 0: service.module.v1.Module -} -var file_service_module_v1_module_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_service_module_v1_module_proto_init() } -func file_service_module_v1_module_proto_init() { - if File_service_module_v1_module_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_service_module_v1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Module); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_service_module_v1_module_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_service_module_v1_module_proto_goTypes, - DependencyIndexes: file_service_module_v1_module_proto_depIdxs, - MessageInfos: file_service_module_v1_module_proto_msgTypes, - }.Build() - File_service_module_v1_module_proto = out.File - file_service_module_v1_module_proto_rawDesc = nil - file_service_module_v1_module_proto_goTypes = nil - file_service_module_v1_module_proto_depIdxs = nil -} diff --git a/api/service/v1/genesis.pulsar.go b/api/service/v1/genesis.pulsar.go deleted file mode 100644 index 608d92d49..000000000 --- a/api/service/v1/genesis.pulsar.go +++ /dev/null @@ -1,3267 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package servicev1 - -import ( - _ "cosmossdk.io/api/amino" - fmt "fmt" - runtime "github.com/cosmos/cosmos-proto/runtime" - _ "github.com/cosmos/gogoproto/gogoproto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_GenesisState protoreflect.MessageDescriptor - fd_GenesisState_params protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_genesis_proto_init() - md_GenesisState = File_service_v1_genesis_proto.Messages().ByName("GenesisState") - fd_GenesisState_params = md_GenesisState.Fields().ByName("params") -} - -var _ protoreflect.Message = (*fastReflection_GenesisState)(nil) - -type fastReflection_GenesisState GenesisState - -func (x *GenesisState) ProtoReflect() protoreflect.Message { - return (*fastReflection_GenesisState)(x) -} - -func (x *GenesisState) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_genesis_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_GenesisState_messageType fastReflection_GenesisState_messageType -var _ protoreflect.MessageType = fastReflection_GenesisState_messageType{} - -type fastReflection_GenesisState_messageType struct{} - -func (x fastReflection_GenesisState_messageType) Zero() protoreflect.Message { - return (*fastReflection_GenesisState)(nil) -} -func (x fastReflection_GenesisState_messageType) New() protoreflect.Message { - return new(fastReflection_GenesisState) -} -func (x fastReflection_GenesisState_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_GenesisState -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_GenesisState) Descriptor() protoreflect.MessageDescriptor { - return md_GenesisState -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_GenesisState) Type() protoreflect.MessageType { - return _fastReflection_GenesisState_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_GenesisState) New() protoreflect.Message { - return new(fastReflection_GenesisState) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_GenesisState) Interface() protoreflect.ProtoMessage { - return (*GenesisState)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Params != nil { - value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - if !f(fd_GenesisState_params, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.GenesisState.params": - return x.Params != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.GenesisState")) - } - panic(fmt.Errorf("message service.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.GenesisState.params": - x.Params = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.GenesisState")) - } - panic(fmt.Errorf("message service.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.GenesisState.params": - value := x.Params - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.GenesisState")) - } - panic(fmt.Errorf("message service.v1.GenesisState does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.GenesisState.params": - x.Params = value.Message().Interface().(*Params) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.GenesisState")) - } - panic(fmt.Errorf("message service.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.GenesisState.params": - if x.Params == nil { - x.Params = new(Params) - } - return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.GenesisState")) - } - panic(fmt.Errorf("message service.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.GenesisState.params": - m := new(Params) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.GenesisState")) - } - panic(fmt.Errorf("message service.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_GenesisState) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.GenesisState", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_GenesisState) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_GenesisState) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_GenesisState) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*GenesisState) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Params != nil { - l = options.Size(x.Params) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*GenesisState) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Params != nil { - encoded, err := options.Marshal(x.Params) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*GenesisState) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Params == nil { - x.Params = &Params{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_Params protoreflect.MessageDescriptor - fd_Params_categories protoreflect.FieldDescriptor - fd_Params_types protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_genesis_proto_init() - md_Params = File_service_v1_genesis_proto.Messages().ByName("Params") - fd_Params_categories = md_Params.Fields().ByName("categories") - fd_Params_types = md_Params.Fields().ByName("types") -} - -var _ protoreflect.Message = (*fastReflection_Params)(nil) - -type fastReflection_Params Params - -func (x *Params) ProtoReflect() protoreflect.Message { - return (*fastReflection_Params)(x) -} - -func (x *Params) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_genesis_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Params_messageType fastReflection_Params_messageType -var _ protoreflect.MessageType = fastReflection_Params_messageType{} - -type fastReflection_Params_messageType struct{} - -func (x fastReflection_Params_messageType) Zero() protoreflect.Message { - return (*fastReflection_Params)(nil) -} -func (x fastReflection_Params_messageType) New() protoreflect.Message { - return new(fastReflection_Params) -} -func (x fastReflection_Params_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Params -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Params) Descriptor() protoreflect.MessageDescriptor { - return md_Params -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Params) Type() protoreflect.MessageType { - return _fastReflection_Params_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Params) New() protoreflect.Message { - return new(fastReflection_Params) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { - return (*Params)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Categories != nil { - value := protoreflect.ValueOfMessage(x.Categories.ProtoReflect()) - if !f(fd_Params_categories, value) { - return - } - } - if x.Types != nil { - value := protoreflect.ValueOfMessage(x.Types.ProtoReflect()) - if !f(fd_Params_types, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.Params.categories": - return x.Categories != nil - case "service.v1.Params.types": - return x.Types != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Params")) - } - panic(fmt.Errorf("message service.v1.Params does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.Params.categories": - x.Categories = nil - case "service.v1.Params.types": - x.Types = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Params")) - } - panic(fmt.Errorf("message service.v1.Params does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.Params.categories": - value := x.Categories - return protoreflect.ValueOfMessage(value.ProtoReflect()) - case "service.v1.Params.types": - value := x.Types - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Params")) - } - panic(fmt.Errorf("message service.v1.Params does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.Params.categories": - x.Categories = value.Message().Interface().(*ServiceCategories) - case "service.v1.Params.types": - x.Types = value.Message().Interface().(*ServiceTypes) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Params")) - } - panic(fmt.Errorf("message service.v1.Params does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.Params.categories": - if x.Categories == nil { - x.Categories = new(ServiceCategories) - } - return protoreflect.ValueOfMessage(x.Categories.ProtoReflect()) - case "service.v1.Params.types": - if x.Types == nil { - x.Types = new(ServiceTypes) - } - return protoreflect.ValueOfMessage(x.Types.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Params")) - } - panic(fmt.Errorf("message service.v1.Params does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.Params.categories": - m := new(ServiceCategories) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - case "service.v1.Params.types": - m := new(ServiceTypes) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Params")) - } - panic(fmt.Errorf("message service.v1.Params does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.Params", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Params) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Params) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Params) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Categories != nil { - l = options.Size(x.Categories) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.Types != nil { - l = options.Size(x.Types) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Params) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Types != nil { - encoded, err := options.Marshal(x.Types) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x12 - } - if x.Categories != nil { - encoded, err := options.Marshal(x.Categories) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Params) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Categories", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Categories == nil { - x.Categories = &ServiceCategories{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Categories); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Types", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Types == nil { - x.Types = &ServiceTypes{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Types); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var _ protoreflect.List = (*_ServiceCategories_1_list)(nil) - -type _ServiceCategories_1_list struct { - list *[]string -} - -func (x *_ServiceCategories_1_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_ServiceCategories_1_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_ServiceCategories_1_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_ServiceCategories_1_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_ServiceCategories_1_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message ServiceCategories at list field Categories as it is not of Message kind")) -} - -func (x *_ServiceCategories_1_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_ServiceCategories_1_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_ServiceCategories_1_list) IsValid() bool { - return x.list != nil -} - -var ( - md_ServiceCategories protoreflect.MessageDescriptor - fd_ServiceCategories_categories protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_genesis_proto_init() - md_ServiceCategories = File_service_v1_genesis_proto.Messages().ByName("ServiceCategories") - fd_ServiceCategories_categories = md_ServiceCategories.Fields().ByName("categories") -} - -var _ protoreflect.Message = (*fastReflection_ServiceCategories)(nil) - -type fastReflection_ServiceCategories ServiceCategories - -func (x *ServiceCategories) ProtoReflect() protoreflect.Message { - return (*fastReflection_ServiceCategories)(x) -} - -func (x *ServiceCategories) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_genesis_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_ServiceCategories_messageType fastReflection_ServiceCategories_messageType -var _ protoreflect.MessageType = fastReflection_ServiceCategories_messageType{} - -type fastReflection_ServiceCategories_messageType struct{} - -func (x fastReflection_ServiceCategories_messageType) Zero() protoreflect.Message { - return (*fastReflection_ServiceCategories)(nil) -} -func (x fastReflection_ServiceCategories_messageType) New() protoreflect.Message { - return new(fastReflection_ServiceCategories) -} -func (x fastReflection_ServiceCategories_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_ServiceCategories -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_ServiceCategories) Descriptor() protoreflect.MessageDescriptor { - return md_ServiceCategories -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_ServiceCategories) Type() protoreflect.MessageType { - return _fastReflection_ServiceCategories_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_ServiceCategories) New() protoreflect.Message { - return new(fastReflection_ServiceCategories) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_ServiceCategories) Interface() protoreflect.ProtoMessage { - return (*ServiceCategories)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_ServiceCategories) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if len(x.Categories) != 0 { - value := protoreflect.ValueOfList(&_ServiceCategories_1_list{list: &x.Categories}) - if !f(fd_ServiceCategories_categories, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_ServiceCategories) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.ServiceCategories.categories": - return len(x.Categories) != 0 - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceCategories")) - } - panic(fmt.Errorf("message service.v1.ServiceCategories does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ServiceCategories) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.ServiceCategories.categories": - x.Categories = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceCategories")) - } - panic(fmt.Errorf("message service.v1.ServiceCategories does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_ServiceCategories) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.ServiceCategories.categories": - if len(x.Categories) == 0 { - return protoreflect.ValueOfList(&_ServiceCategories_1_list{}) - } - listValue := &_ServiceCategories_1_list{list: &x.Categories} - return protoreflect.ValueOfList(listValue) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceCategories")) - } - panic(fmt.Errorf("message service.v1.ServiceCategories does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ServiceCategories) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.ServiceCategories.categories": - lv := value.List() - clv := lv.(*_ServiceCategories_1_list) - x.Categories = *clv.list - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceCategories")) - } - panic(fmt.Errorf("message service.v1.ServiceCategories does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ServiceCategories) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.ServiceCategories.categories": - if x.Categories == nil { - x.Categories = []string{} - } - value := &_ServiceCategories_1_list{list: &x.Categories} - return protoreflect.ValueOfList(value) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceCategories")) - } - panic(fmt.Errorf("message service.v1.ServiceCategories does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_ServiceCategories) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.ServiceCategories.categories": - list := []string{} - return protoreflect.ValueOfList(&_ServiceCategories_1_list{list: &list}) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceCategories")) - } - panic(fmt.Errorf("message service.v1.ServiceCategories does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_ServiceCategories) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.ServiceCategories", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_ServiceCategories) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ServiceCategories) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_ServiceCategories) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_ServiceCategories) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*ServiceCategories) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if len(x.Categories) > 0 { - for _, s := range x.Categories { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*ServiceCategories) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Categories) > 0 { - for iNdEx := len(x.Categories) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.Categories[iNdEx]) - copy(dAtA[i:], x.Categories[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Categories[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*ServiceCategories) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ServiceCategories: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ServiceCategories: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Categories", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Categories = append(x.Categories, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var _ protoreflect.List = (*_ServiceTypes_1_list)(nil) - -type _ServiceTypes_1_list struct { - list *[]string -} - -func (x *_ServiceTypes_1_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_ServiceTypes_1_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_ServiceTypes_1_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_ServiceTypes_1_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_ServiceTypes_1_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message ServiceTypes at list field Types as it is not of Message kind")) -} - -func (x *_ServiceTypes_1_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_ServiceTypes_1_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_ServiceTypes_1_list) IsValid() bool { - return x.list != nil -} - -var ( - md_ServiceTypes protoreflect.MessageDescriptor - fd_ServiceTypes_types protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_genesis_proto_init() - md_ServiceTypes = File_service_v1_genesis_proto.Messages().ByName("ServiceTypes") - fd_ServiceTypes_types = md_ServiceTypes.Fields().ByName("types") -} - -var _ protoreflect.Message = (*fastReflection_ServiceTypes)(nil) - -type fastReflection_ServiceTypes ServiceTypes - -func (x *ServiceTypes) ProtoReflect() protoreflect.Message { - return (*fastReflection_ServiceTypes)(x) -} - -func (x *ServiceTypes) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_genesis_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_ServiceTypes_messageType fastReflection_ServiceTypes_messageType -var _ protoreflect.MessageType = fastReflection_ServiceTypes_messageType{} - -type fastReflection_ServiceTypes_messageType struct{} - -func (x fastReflection_ServiceTypes_messageType) Zero() protoreflect.Message { - return (*fastReflection_ServiceTypes)(nil) -} -func (x fastReflection_ServiceTypes_messageType) New() protoreflect.Message { - return new(fastReflection_ServiceTypes) -} -func (x fastReflection_ServiceTypes_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_ServiceTypes -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_ServiceTypes) Descriptor() protoreflect.MessageDescriptor { - return md_ServiceTypes -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_ServiceTypes) Type() protoreflect.MessageType { - return _fastReflection_ServiceTypes_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_ServiceTypes) New() protoreflect.Message { - return new(fastReflection_ServiceTypes) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_ServiceTypes) Interface() protoreflect.ProtoMessage { - return (*ServiceTypes)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_ServiceTypes) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if len(x.Types) != 0 { - value := protoreflect.ValueOfList(&_ServiceTypes_1_list{list: &x.Types}) - if !f(fd_ServiceTypes_types, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_ServiceTypes) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.ServiceTypes.types": - return len(x.Types) != 0 - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceTypes")) - } - panic(fmt.Errorf("message service.v1.ServiceTypes does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ServiceTypes) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.ServiceTypes.types": - x.Types = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceTypes")) - } - panic(fmt.Errorf("message service.v1.ServiceTypes does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_ServiceTypes) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.ServiceTypes.types": - if len(x.Types) == 0 { - return protoreflect.ValueOfList(&_ServiceTypes_1_list{}) - } - listValue := &_ServiceTypes_1_list{list: &x.Types} - return protoreflect.ValueOfList(listValue) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceTypes")) - } - panic(fmt.Errorf("message service.v1.ServiceTypes does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ServiceTypes) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.ServiceTypes.types": - lv := value.List() - clv := lv.(*_ServiceTypes_1_list) - x.Types = *clv.list - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceTypes")) - } - panic(fmt.Errorf("message service.v1.ServiceTypes does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ServiceTypes) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.ServiceTypes.types": - if x.Types == nil { - x.Types = []string{} - } - value := &_ServiceTypes_1_list{list: &x.Types} - return protoreflect.ValueOfList(value) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceTypes")) - } - panic(fmt.Errorf("message service.v1.ServiceTypes does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_ServiceTypes) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.ServiceTypes.types": - list := []string{} - return protoreflect.ValueOfList(&_ServiceTypes_1_list{list: &list}) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.ServiceTypes")) - } - panic(fmt.Errorf("message service.v1.ServiceTypes does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_ServiceTypes) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.ServiceTypes", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_ServiceTypes) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_ServiceTypes) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_ServiceTypes) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_ServiceTypes) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*ServiceTypes) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if len(x.Types) > 0 { - for _, s := range x.Types { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*ServiceTypes) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Types) > 0 { - for iNdEx := len(x.Types) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.Types[iNdEx]) - copy(dAtA[i:], x.Types[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Types[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*ServiceTypes) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ServiceTypes: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ServiceTypes: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Types", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Types = append(x.Types, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var _ protoreflect.List = (*_Service_7_list)(nil) - -type _Service_7_list struct { - list *[]string -} - -func (x *_Service_7_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Service_7_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_Service_7_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_Service_7_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_Service_7_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Service at list field Tags as it is not of Message kind")) -} - -func (x *_Service_7_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_Service_7_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Service_7_list) IsValid() bool { - return x.list != nil -} - -var ( - md_Service protoreflect.MessageDescriptor - fd_Service_id protoreflect.FieldDescriptor - fd_Service_authority protoreflect.FieldDescriptor - fd_Service_origin protoreflect.FieldDescriptor - fd_Service_name protoreflect.FieldDescriptor - fd_Service_description protoreflect.FieldDescriptor - fd_Service_category protoreflect.FieldDescriptor - fd_Service_tags protoreflect.FieldDescriptor - fd_Service_expiry_height protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_genesis_proto_init() - md_Service = File_service_v1_genesis_proto.Messages().ByName("Service") - fd_Service_id = md_Service.Fields().ByName("id") - fd_Service_authority = md_Service.Fields().ByName("authority") - fd_Service_origin = md_Service.Fields().ByName("origin") - fd_Service_name = md_Service.Fields().ByName("name") - fd_Service_description = md_Service.Fields().ByName("description") - fd_Service_category = md_Service.Fields().ByName("category") - fd_Service_tags = md_Service.Fields().ByName("tags") - fd_Service_expiry_height = md_Service.Fields().ByName("expiry_height") -} - -var _ protoreflect.Message = (*fastReflection_Service)(nil) - -type fastReflection_Service Service - -func (x *Service) ProtoReflect() protoreflect.Message { - return (*fastReflection_Service)(x) -} - -func (x *Service) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_genesis_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Service_messageType fastReflection_Service_messageType -var _ protoreflect.MessageType = fastReflection_Service_messageType{} - -type fastReflection_Service_messageType struct{} - -func (x fastReflection_Service_messageType) Zero() protoreflect.Message { - return (*fastReflection_Service)(nil) -} -func (x fastReflection_Service_messageType) New() protoreflect.Message { - return new(fastReflection_Service) -} -func (x fastReflection_Service_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Service -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Service) Descriptor() protoreflect.MessageDescriptor { - return md_Service -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Service) Type() protoreflect.MessageType { - return _fastReflection_Service_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Service) New() protoreflect.Message { - return new(fastReflection_Service) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Service) Interface() protoreflect.ProtoMessage { - return (*Service)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Service) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != "" { - value := protoreflect.ValueOfString(x.Id) - if !f(fd_Service_id, value) { - return - } - } - if x.Authority != "" { - value := protoreflect.ValueOfString(x.Authority) - if !f(fd_Service_authority, value) { - return - } - } - if x.Origin != "" { - value := protoreflect.ValueOfString(x.Origin) - if !f(fd_Service_origin, value) { - return - } - } - if x.Name != "" { - value := protoreflect.ValueOfString(x.Name) - if !f(fd_Service_name, value) { - return - } - } - if x.Description != "" { - value := protoreflect.ValueOfString(x.Description) - if !f(fd_Service_description, value) { - return - } - } - if x.Category != "" { - value := protoreflect.ValueOfString(x.Category) - if !f(fd_Service_category, value) { - return - } - } - if len(x.Tags) != 0 { - value := protoreflect.ValueOfList(&_Service_7_list{list: &x.Tags}) - if !f(fd_Service_tags, value) { - return - } - } - if x.ExpiryHeight != int64(0) { - value := protoreflect.ValueOfInt64(x.ExpiryHeight) - if !f(fd_Service_expiry_height, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Service) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.Service.id": - return x.Id != "" - case "service.v1.Service.authority": - return x.Authority != "" - case "service.v1.Service.origin": - return x.Origin != "" - case "service.v1.Service.name": - return x.Name != "" - case "service.v1.Service.description": - return x.Description != "" - case "service.v1.Service.category": - return x.Category != "" - case "service.v1.Service.tags": - return len(x.Tags) != 0 - case "service.v1.Service.expiry_height": - return x.ExpiryHeight != int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Service")) - } - panic(fmt.Errorf("message service.v1.Service does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Service) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.Service.id": - x.Id = "" - case "service.v1.Service.authority": - x.Authority = "" - case "service.v1.Service.origin": - x.Origin = "" - case "service.v1.Service.name": - x.Name = "" - case "service.v1.Service.description": - x.Description = "" - case "service.v1.Service.category": - x.Category = "" - case "service.v1.Service.tags": - x.Tags = nil - case "service.v1.Service.expiry_height": - x.ExpiryHeight = int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Service")) - } - panic(fmt.Errorf("message service.v1.Service does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Service) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.Service.id": - value := x.Id - return protoreflect.ValueOfString(value) - case "service.v1.Service.authority": - value := x.Authority - return protoreflect.ValueOfString(value) - case "service.v1.Service.origin": - value := x.Origin - return protoreflect.ValueOfString(value) - case "service.v1.Service.name": - value := x.Name - return protoreflect.ValueOfString(value) - case "service.v1.Service.description": - value := x.Description - return protoreflect.ValueOfString(value) - case "service.v1.Service.category": - value := x.Category - return protoreflect.ValueOfString(value) - case "service.v1.Service.tags": - if len(x.Tags) == 0 { - return protoreflect.ValueOfList(&_Service_7_list{}) - } - listValue := &_Service_7_list{list: &x.Tags} - return protoreflect.ValueOfList(listValue) - case "service.v1.Service.expiry_height": - value := x.ExpiryHeight - return protoreflect.ValueOfInt64(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Service")) - } - panic(fmt.Errorf("message service.v1.Service does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Service) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.Service.id": - x.Id = value.Interface().(string) - case "service.v1.Service.authority": - x.Authority = value.Interface().(string) - case "service.v1.Service.origin": - x.Origin = value.Interface().(string) - case "service.v1.Service.name": - x.Name = value.Interface().(string) - case "service.v1.Service.description": - x.Description = value.Interface().(string) - case "service.v1.Service.category": - x.Category = value.Interface().(string) - case "service.v1.Service.tags": - lv := value.List() - clv := lv.(*_Service_7_list) - x.Tags = *clv.list - case "service.v1.Service.expiry_height": - x.ExpiryHeight = value.Int() - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Service")) - } - panic(fmt.Errorf("message service.v1.Service does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Service) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.Service.tags": - if x.Tags == nil { - x.Tags = []string{} - } - value := &_Service_7_list{list: &x.Tags} - return protoreflect.ValueOfList(value) - case "service.v1.Service.id": - panic(fmt.Errorf("field id of message service.v1.Service is not mutable")) - case "service.v1.Service.authority": - panic(fmt.Errorf("field authority of message service.v1.Service is not mutable")) - case "service.v1.Service.origin": - panic(fmt.Errorf("field origin of message service.v1.Service is not mutable")) - case "service.v1.Service.name": - panic(fmt.Errorf("field name of message service.v1.Service is not mutable")) - case "service.v1.Service.description": - panic(fmt.Errorf("field description of message service.v1.Service is not mutable")) - case "service.v1.Service.category": - panic(fmt.Errorf("field category of message service.v1.Service is not mutable")) - case "service.v1.Service.expiry_height": - panic(fmt.Errorf("field expiry_height of message service.v1.Service is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Service")) - } - panic(fmt.Errorf("message service.v1.Service does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Service) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.Service.id": - return protoreflect.ValueOfString("") - case "service.v1.Service.authority": - return protoreflect.ValueOfString("") - case "service.v1.Service.origin": - return protoreflect.ValueOfString("") - case "service.v1.Service.name": - return protoreflect.ValueOfString("") - case "service.v1.Service.description": - return protoreflect.ValueOfString("") - case "service.v1.Service.category": - return protoreflect.ValueOfString("") - case "service.v1.Service.tags": - list := []string{} - return protoreflect.ValueOfList(&_Service_7_list{list: &list}) - case "service.v1.Service.expiry_height": - return protoreflect.ValueOfInt64(int64(0)) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Service")) - } - panic(fmt.Errorf("message service.v1.Service does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Service) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.Service", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Service) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Service) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Service) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Service) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Service) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Id) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Authority) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Origin) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Name) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Description) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Category) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if len(x.Tags) > 0 { - for _, s := range x.Tags { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if x.ExpiryHeight != 0 { - n += 1 + runtime.Sov(uint64(x.ExpiryHeight)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Service) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.ExpiryHeight != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryHeight)) - i-- - dAtA[i] = 0x40 - } - if len(x.Tags) > 0 { - for iNdEx := len(x.Tags) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.Tags[iNdEx]) - copy(dAtA[i:], x.Tags[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Tags[iNdEx]))) - i-- - dAtA[i] = 0x3a - } - } - if len(x.Category) > 0 { - i -= len(x.Category) - copy(dAtA[i:], x.Category) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Category))) - i-- - dAtA[i] = 0x32 - } - if len(x.Description) > 0 { - i -= len(x.Description) - copy(dAtA[i:], x.Description) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Description))) - i-- - dAtA[i] = 0x2a - } - if len(x.Name) > 0 { - i -= len(x.Name) - copy(dAtA[i:], x.Name) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) - i-- - dAtA[i] = 0x22 - } - if len(x.Origin) > 0 { - i -= len(x.Origin) - copy(dAtA[i:], x.Origin) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) - i-- - dAtA[i] = 0x1a - } - if len(x.Authority) > 0 { - i -= len(x.Authority) - copy(dAtA[i:], x.Authority) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) - i-- - dAtA[i] = 0x12 - } - if len(x.Id) > 0 { - i -= len(x.Id) - copy(dAtA[i:], x.Id) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Id))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Service) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Service: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Service: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Authority = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Category", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Category = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Tags = append(x.Tags, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 8: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) - } - x.ExpiryHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.ExpiryHeight |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: service/v1/genesis.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// GenesisState defines the module genesis state -type GenesisState struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Params defines all the parameters of the module. - Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` -} - -func (x *GenesisState) Reset() { - *x = GenesisState{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_genesis_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GenesisState) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GenesisState) ProtoMessage() {} - -// Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. -func (*GenesisState) Descriptor() ([]byte, []int) { - return file_service_v1_genesis_proto_rawDescGZIP(), []int{0} -} - -func (x *GenesisState) GetParams() *Params { - if x != nil { - return x.Params - } - return nil -} - -// Params defines the set of module parameters. -type Params struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Categories *ServiceCategories `protobuf:"bytes,1,opt,name=categories,proto3" json:"categories,omitempty"` - Types *ServiceTypes `protobuf:"bytes,2,opt,name=types,proto3" json:"types,omitempty"` -} - -func (x *Params) Reset() { - *x = Params{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_genesis_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Params) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Params) ProtoMessage() {} - -// Deprecated: Use Params.ProtoReflect.Descriptor instead. -func (*Params) Descriptor() ([]byte, []int) { - return file_service_v1_genesis_proto_rawDescGZIP(), []int{1} -} - -func (x *Params) GetCategories() *ServiceCategories { - if x != nil { - return x.Categories - } - return nil -} - -func (x *Params) GetTypes() *ServiceTypes { - if x != nil { - return x.Types - } - return nil -} - -type ServiceCategories struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Categories []string `protobuf:"bytes,1,rep,name=categories,proto3" json:"categories,omitempty"` -} - -func (x *ServiceCategories) Reset() { - *x = ServiceCategories{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_genesis_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServiceCategories) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServiceCategories) ProtoMessage() {} - -// Deprecated: Use ServiceCategories.ProtoReflect.Descriptor instead. -func (*ServiceCategories) Descriptor() ([]byte, []int) { - return file_service_v1_genesis_proto_rawDescGZIP(), []int{2} -} - -func (x *ServiceCategories) GetCategories() []string { - if x != nil { - return x.Categories - } - return nil -} - -type ServiceTypes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Types []string `protobuf:"bytes,1,rep,name=types,proto3" json:"types,omitempty"` -} - -func (x *ServiceTypes) Reset() { - *x = ServiceTypes{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_genesis_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServiceTypes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServiceTypes) ProtoMessage() {} - -// Deprecated: Use ServiceTypes.ProtoReflect.Descriptor instead. -func (*ServiceTypes) Descriptor() ([]byte, []int) { - return file_service_v1_genesis_proto_rawDescGZIP(), []int{3} -} - -func (x *ServiceTypes) GetTypes() []string { - if x != nil { - return x.Types - } - return nil -} - -// Service defines a Decentralized Service on the Sonr Blockchain -type Service struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Authority string `protobuf:"bytes,2,opt,name=authority,proto3" json:"authority,omitempty"` - Origin string `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` - Category string `protobuf:"bytes,6,opt,name=category,proto3" json:"category,omitempty"` - Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` - ExpiryHeight int64 `protobuf:"varint,8,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` -} - -func (x *Service) Reset() { - *x = Service{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_genesis_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Service) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Service) ProtoMessage() {} - -// Deprecated: Use Service.ProtoReflect.Descriptor instead. -func (*Service) Descriptor() ([]byte, []int) { - return file_service_v1_genesis_proto_rawDescGZIP(), []int{4} -} - -func (x *Service) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Service) GetAuthority() string { - if x != nil { - return x.Authority - } - return "" -} - -func (x *Service) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *Service) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Service) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Service) GetCategory() string { - if x != nil { - return x.Category - } - return "" -} - -func (x *Service) GetTags() []string { - if x != nil { - return x.Tags - } - return nil -} - -func (x *Service) GetExpiryHeight() int64 { - if x != nil { - return x.ExpiryHeight - } - return 0 -} - -var File_service_v1_genesis_proto protoreflect.FileDescriptor - -var file_service_v1_genesis_proto_rawDesc = []byte{ - 0x0a, 0x18, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, - 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, - 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x40, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x30, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x22, 0x94, 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x3d, 0x0a, 0x0a, - 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, - 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x05, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x1b, 0x98, 0xa0, 0x1f, - 0x00, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x50, 0x0a, 0x11, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1e, 0x0a, - 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x1b, 0xe8, - 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, - 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x0c, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x3a, 0x16, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0xda, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, - 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x42, 0x98, 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, - 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x3b, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, - 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x16, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_service_v1_genesis_proto_rawDescOnce sync.Once - file_service_v1_genesis_proto_rawDescData = file_service_v1_genesis_proto_rawDesc -) - -func file_service_v1_genesis_proto_rawDescGZIP() []byte { - file_service_v1_genesis_proto_rawDescOnce.Do(func() { - file_service_v1_genesis_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_v1_genesis_proto_rawDescData) - }) - return file_service_v1_genesis_proto_rawDescData -} - -var file_service_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_service_v1_genesis_proto_goTypes = []interface{}{ - (*GenesisState)(nil), // 0: service.v1.GenesisState - (*Params)(nil), // 1: service.v1.Params - (*ServiceCategories)(nil), // 2: service.v1.ServiceCategories - (*ServiceTypes)(nil), // 3: service.v1.ServiceTypes - (*Service)(nil), // 4: service.v1.Service -} -var file_service_v1_genesis_proto_depIdxs = []int32{ - 1, // 0: service.v1.GenesisState.params:type_name -> service.v1.Params - 2, // 1: service.v1.Params.categories:type_name -> service.v1.ServiceCategories - 3, // 2: service.v1.Params.types:type_name -> service.v1.ServiceTypes - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_service_v1_genesis_proto_init() } -func file_service_v1_genesis_proto_init() { - if File_service_v1_genesis_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_service_v1_genesis_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GenesisState); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_genesis_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Params); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_genesis_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServiceCategories); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_genesis_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServiceTypes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_genesis_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Service); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_service_v1_genesis_proto_rawDesc, - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_service_v1_genesis_proto_goTypes, - DependencyIndexes: file_service_v1_genesis_proto_depIdxs, - MessageInfos: file_service_v1_genesis_proto_msgTypes, - }.Build() - File_service_v1_genesis_proto = out.File - file_service_v1_genesis_proto_rawDesc = nil - file_service_v1_genesis_proto_goTypes = nil - file_service_v1_genesis_proto_depIdxs = nil -} diff --git a/api/service/v1/query.pulsar.go b/api/service/v1/query.pulsar.go deleted file mode 100644 index e2f65cead..000000000 --- a/api/service/v1/query.pulsar.go +++ /dev/null @@ -1,997 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package servicev1 - -import ( - fmt "fmt" - runtime "github.com/cosmos/cosmos-proto/runtime" - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_QueryParamsRequest protoreflect.MessageDescriptor -) - -func init() { - file_service_v1_query_proto_init() - md_QueryParamsRequest = File_service_v1_query_proto.Messages().ByName("QueryParamsRequest") -} - -var _ protoreflect.Message = (*fastReflection_QueryParamsRequest)(nil) - -type fastReflection_QueryParamsRequest QueryParamsRequest - -func (x *QueryParamsRequest) ProtoReflect() protoreflect.Message { - return (*fastReflection_QueryParamsRequest)(x) -} - -func (x *QueryParamsRequest) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_query_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QueryParamsRequest_messageType fastReflection_QueryParamsRequest_messageType -var _ protoreflect.MessageType = fastReflection_QueryParamsRequest_messageType{} - -type fastReflection_QueryParamsRequest_messageType struct{} - -func (x fastReflection_QueryParamsRequest_messageType) Zero() protoreflect.Message { - return (*fastReflection_QueryParamsRequest)(nil) -} -func (x fastReflection_QueryParamsRequest_messageType) New() protoreflect.Message { - return new(fastReflection_QueryParamsRequest) -} -func (x fastReflection_QueryParamsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QueryParamsRequest -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QueryParamsRequest) Descriptor() protoreflect.MessageDescriptor { - return md_QueryParamsRequest -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QueryParamsRequest) Type() protoreflect.MessageType { - return _fastReflection_QueryParamsRequest_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QueryParamsRequest) New() protoreflect.Message { - return new(fastReflection_QueryParamsRequest) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QueryParamsRequest) Interface() protoreflect.ProtoMessage { - return (*QueryParamsRequest)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QueryParamsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QueryParamsRequest) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message service.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsRequest) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message service.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QueryParamsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message service.v1.QueryParamsRequest does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message service.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message service.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QueryParamsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message service.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QueryParamsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.QueryParamsRequest", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QueryParamsRequest) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsRequest) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QueryParamsRequest) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QueryParamsRequest) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QueryParamsRequest) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QueryParamsRequest) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QueryParamsRequest) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_QueryParamsResponse protoreflect.MessageDescriptor - fd_QueryParamsResponse_params protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_query_proto_init() - md_QueryParamsResponse = File_service_v1_query_proto.Messages().ByName("QueryParamsResponse") - fd_QueryParamsResponse_params = md_QueryParamsResponse.Fields().ByName("params") -} - -var _ protoreflect.Message = (*fastReflection_QueryParamsResponse)(nil) - -type fastReflection_QueryParamsResponse QueryParamsResponse - -func (x *QueryParamsResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_QueryParamsResponse)(x) -} - -func (x *QueryParamsResponse) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_query_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QueryParamsResponse_messageType fastReflection_QueryParamsResponse_messageType -var _ protoreflect.MessageType = fastReflection_QueryParamsResponse_messageType{} - -type fastReflection_QueryParamsResponse_messageType struct{} - -func (x fastReflection_QueryParamsResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_QueryParamsResponse)(nil) -} -func (x fastReflection_QueryParamsResponse_messageType) New() protoreflect.Message { - return new(fastReflection_QueryParamsResponse) -} -func (x fastReflection_QueryParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QueryParamsResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QueryParamsResponse) Descriptor() protoreflect.MessageDescriptor { - return md_QueryParamsResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QueryParamsResponse) Type() protoreflect.MessageType { - return _fastReflection_QueryParamsResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QueryParamsResponse) New() protoreflect.Message { - return new(fastReflection_QueryParamsResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QueryParamsResponse) Interface() protoreflect.ProtoMessage { - return (*QueryParamsResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QueryParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Params != nil { - value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - if !f(fd_QueryParamsResponse_params, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QueryParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.QueryParamsResponse.params": - return x.Params != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message service.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.QueryParamsResponse.params": - x.Params = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message service.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QueryParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.QueryParamsResponse.params": - value := x.Params - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message service.v1.QueryParamsResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.QueryParamsResponse.params": - x.Params = value.Message().Interface().(*Params) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message service.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.QueryParamsResponse.params": - if x.Params == nil { - x.Params = new(Params) - } - return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message service.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QueryParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.QueryParamsResponse.params": - m := new(Params) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message service.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QueryParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.QueryParamsResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QueryParamsResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QueryParamsResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QueryParamsResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QueryParamsResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Params != nil { - l = options.Size(x.Params) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QueryParamsResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Params != nil { - encoded, err := options.Marshal(x.Params) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QueryParamsResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Params == nil { - x.Params = &Params{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: service/v1/query.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// QueryParamsRequest is the request type for the Query/Params RPC method. -type QueryParamsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *QueryParamsRequest) Reset() { - *x = QueryParamsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_query_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QueryParamsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryParamsRequest) ProtoMessage() {} - -// Deprecated: Use QueryParamsRequest.ProtoReflect.Descriptor instead. -func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return file_service_v1_query_proto_rawDescGZIP(), []int{0} -} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -type QueryParamsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // params defines the parameters of the module. - Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` -} - -func (x *QueryParamsResponse) Reset() { - *x = QueryParamsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_query_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QueryParamsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryParamsResponse) ProtoMessage() {} - -// Deprecated: Use QueryParamsResponse.ProtoReflect.Descriptor instead. -func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return file_service_v1_query_proto_rawDescGZIP(), []int{1} -} - -func (x *QueryParamsResponse) GetParams() *Params { - if x != nil { - return x.Params - } - return nil -} - -var File_service_v1_query_proto protoreflect.FileDescriptor - -var file_service_v1_query_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x18, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x67, - 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x14, 0x0a, 0x12, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x41, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x32, 0x6e, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x65, - 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x14, 0x12, 0x12, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x96, 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x0a, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_service_v1_query_proto_rawDescOnce sync.Once - file_service_v1_query_proto_rawDescData = file_service_v1_query_proto_rawDesc -) - -func file_service_v1_query_proto_rawDescGZIP() []byte { - file_service_v1_query_proto_rawDescOnce.Do(func() { - file_service_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_v1_query_proto_rawDescData) - }) - return file_service_v1_query_proto_rawDescData -} - -var file_service_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_service_v1_query_proto_goTypes = []interface{}{ - (*QueryParamsRequest)(nil), // 0: service.v1.QueryParamsRequest - (*QueryParamsResponse)(nil), // 1: service.v1.QueryParamsResponse - (*Params)(nil), // 2: service.v1.Params -} -var file_service_v1_query_proto_depIdxs = []int32{ - 2, // 0: service.v1.QueryParamsResponse.params:type_name -> service.v1.Params - 0, // 1: service.v1.Query.Params:input_type -> service.v1.QueryParamsRequest - 1, // 2: service.v1.Query.Params:output_type -> service.v1.QueryParamsResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_service_v1_query_proto_init() } -func file_service_v1_query_proto_init() { - if File_service_v1_query_proto != nil { - return - } - file_service_v1_genesis_proto_init() - if !protoimpl.UnsafeEnabled { - file_service_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryParamsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryParamsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_service_v1_query_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_service_v1_query_proto_goTypes, - DependencyIndexes: file_service_v1_query_proto_depIdxs, - MessageInfos: file_service_v1_query_proto_msgTypes, - }.Build() - File_service_v1_query_proto = out.File - file_service_v1_query_proto_rawDesc = nil - file_service_v1_query_proto_goTypes = nil - file_service_v1_query_proto_depIdxs = nil -} diff --git a/api/service/v1/query_grpc.pb.go b/api/service/v1/query_grpc.pb.go deleted file mode 100644 index ad87b4ab2..000000000 --- a/api/service/v1/query_grpc.pb.go +++ /dev/null @@ -1,127 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc (unknown) -// source: service/v1/query.proto - -package servicev1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - Query_Params_FullMethodName = "/service.v1.Query/Params" -) - -// QueryClient is the client API for Query service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -// -// Query provides defines the gRPC querier service. -type QueryClient interface { - // Params queries all parameters of the module. - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) -} - -type queryClient struct { - cc grpc.ClientConnInterface -} - -func NewQueryClient(cc grpc.ClientConnInterface) QueryClient { - return &queryClient{cc} -} - -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, Query_Params_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -// QueryServer is the server API for Query service. -// All implementations must embed UnimplementedQueryServer -// for forward compatibility. -// -// Query provides defines the gRPC querier service. -type QueryServer interface { - // Params queries all parameters of the module. - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) - mustEmbedUnimplementedQueryServer() -} - -// UnimplementedQueryServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedQueryServer struct{} - -func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") -} -func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {} -func (UnimplementedQueryServer) testEmbeddedByValue() {} - -// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to QueryServer will -// result in compilation errors. -type UnsafeQueryServer interface { - mustEmbedUnimplementedQueryServer() -} - -func RegisterQueryServer(s grpc.ServiceRegistrar, srv QueryServer) { - // If the following call pancis, it indicates UnimplementedQueryServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&Query_ServiceDesc, srv) -} - -func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryParamsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Params(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Query_Params_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// Query_ServiceDesc is the grpc.ServiceDesc for Query service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Query_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "service.v1.Query", - HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Params", - Handler: _Query_Params_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "service/v1/query.proto", -} diff --git a/api/service/v1/state.cosmos_orm.go b/api/service/v1/state.cosmos_orm.go deleted file mode 100644 index 2dfc0ecae..000000000 --- a/api/service/v1/state.cosmos_orm.go +++ /dev/null @@ -1,368 +0,0 @@ -// Code generated by protoc-gen-go-cosmos-orm. DO NOT EDIT. - -package servicev1 - -import ( - context "context" - ormlist "cosmossdk.io/orm/model/ormlist" - ormtable "cosmossdk.io/orm/model/ormtable" - ormerrors "cosmossdk.io/orm/types/ormerrors" -) - -type MetadataTable interface { - Insert(ctx context.Context, metadata *Metadata) error - InsertReturningId(ctx context.Context, metadata *Metadata) (uint64, error) - LastInsertedSequence(ctx context.Context) (uint64, error) - Update(ctx context.Context, metadata *Metadata) error - Save(ctx context.Context, metadata *Metadata) error - Delete(ctx context.Context, metadata *Metadata) error - Has(ctx context.Context, id uint64) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, id uint64) (*Metadata, error) - HasByOrigin(ctx context.Context, origin string) (found bool, err error) - // GetByOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByOrigin(ctx context.Context, origin string) (*Metadata, error) - List(ctx context.Context, prefixKey MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) - ListRange(ctx context.Context, from, to MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) - DeleteBy(ctx context.Context, prefixKey MetadataIndexKey) error - DeleteRange(ctx context.Context, from, to MetadataIndexKey) error - - doNotImplement() -} - -type MetadataIterator struct { - ormtable.Iterator -} - -func (i MetadataIterator) Value() (*Metadata, error) { - var metadata Metadata - err := i.UnmarshalMessage(&metadata) - return &metadata, err -} - -type MetadataIndexKey interface { - id() uint32 - values() []interface{} - metadataIndexKey() -} - -// primary key starting index.. -type MetadataPrimaryKey = MetadataIdIndexKey - -type MetadataIdIndexKey struct { - vs []interface{} -} - -func (x MetadataIdIndexKey) id() uint32 { return 0 } -func (x MetadataIdIndexKey) values() []interface{} { return x.vs } -func (x MetadataIdIndexKey) metadataIndexKey() {} - -func (this MetadataIdIndexKey) WithId(id uint64) MetadataIdIndexKey { - this.vs = []interface{}{id} - return this -} - -type MetadataOriginIndexKey struct { - vs []interface{} -} - -func (x MetadataOriginIndexKey) id() uint32 { return 1 } -func (x MetadataOriginIndexKey) values() []interface{} { return x.vs } -func (x MetadataOriginIndexKey) metadataIndexKey() {} - -func (this MetadataOriginIndexKey) WithOrigin(origin string) MetadataOriginIndexKey { - this.vs = []interface{}{origin} - return this -} - -type metadataTable struct { - table ormtable.AutoIncrementTable -} - -func (this metadataTable) Insert(ctx context.Context, metadata *Metadata) error { - return this.table.Insert(ctx, metadata) -} - -func (this metadataTable) Update(ctx context.Context, metadata *Metadata) error { - return this.table.Update(ctx, metadata) -} - -func (this metadataTable) Save(ctx context.Context, metadata *Metadata) error { - return this.table.Save(ctx, metadata) -} - -func (this metadataTable) Delete(ctx context.Context, metadata *Metadata) error { - return this.table.Delete(ctx, metadata) -} - -func (this metadataTable) InsertReturningId(ctx context.Context, metadata *Metadata) (uint64, error) { - return this.table.InsertReturningPKey(ctx, metadata) -} - -func (this metadataTable) LastInsertedSequence(ctx context.Context) (uint64, error) { - return this.table.LastInsertedSequence(ctx) -} - -func (this metadataTable) Has(ctx context.Context, id uint64) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, id) -} - -func (this metadataTable) Get(ctx context.Context, id uint64) (*Metadata, error) { - var metadata Metadata - found, err := this.table.PrimaryKey().Get(ctx, &metadata, id) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &metadata, nil -} - -func (this metadataTable) HasByOrigin(ctx context.Context, origin string) (found bool, err error) { - return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, - origin, - ) -} - -func (this metadataTable) GetByOrigin(ctx context.Context, origin string) (*Metadata, error) { - var metadata Metadata - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &metadata, - origin, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &metadata, nil -} - -func (this metadataTable) List(ctx context.Context, prefixKey MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return MetadataIterator{it}, err -} - -func (this metadataTable) ListRange(ctx context.Context, from, to MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return MetadataIterator{it}, err -} - -func (this metadataTable) DeleteBy(ctx context.Context, prefixKey MetadataIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this metadataTable) DeleteRange(ctx context.Context, from, to MetadataIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this metadataTable) doNotImplement() {} - -var _ MetadataTable = metadataTable{} - -func NewMetadataTable(db ormtable.Schema) (MetadataTable, error) { - table := db.GetTable(&Metadata{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Metadata{}).ProtoReflect().Descriptor().FullName())) - } - return metadataTable{table.(ormtable.AutoIncrementTable)}, nil -} - -type ProfileTable interface { - Insert(ctx context.Context, profile *Profile) error - Update(ctx context.Context, profile *Profile) error - Save(ctx context.Context, profile *Profile) error - Delete(ctx context.Context, profile *Profile) error - Has(ctx context.Context, id string) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, id string) (*Profile, error) - HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) - // GetBySubjectOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Profile, error) - List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) - ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) - DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error - DeleteRange(ctx context.Context, from, to ProfileIndexKey) error - - doNotImplement() -} - -type ProfileIterator struct { - ormtable.Iterator -} - -func (i ProfileIterator) Value() (*Profile, error) { - var profile Profile - err := i.UnmarshalMessage(&profile) - return &profile, err -} - -type ProfileIndexKey interface { - id() uint32 - values() []interface{} - profileIndexKey() -} - -// primary key starting index.. -type ProfilePrimaryKey = ProfileIdIndexKey - -type ProfileIdIndexKey struct { - vs []interface{} -} - -func (x ProfileIdIndexKey) id() uint32 { return 0 } -func (x ProfileIdIndexKey) values() []interface{} { return x.vs } -func (x ProfileIdIndexKey) profileIndexKey() {} - -func (this ProfileIdIndexKey) WithId(id string) ProfileIdIndexKey { - this.vs = []interface{}{id} - return this -} - -type ProfileSubjectOriginIndexKey struct { - vs []interface{} -} - -func (x ProfileSubjectOriginIndexKey) id() uint32 { return 1 } -func (x ProfileSubjectOriginIndexKey) values() []interface{} { return x.vs } -func (x ProfileSubjectOriginIndexKey) profileIndexKey() {} - -func (this ProfileSubjectOriginIndexKey) WithSubject(subject string) ProfileSubjectOriginIndexKey { - this.vs = []interface{}{subject} - return this -} - -func (this ProfileSubjectOriginIndexKey) WithSubjectOrigin(subject string, origin string) ProfileSubjectOriginIndexKey { - this.vs = []interface{}{subject, origin} - return this -} - -type profileTable struct { - table ormtable.Table -} - -func (this profileTable) Insert(ctx context.Context, profile *Profile) error { - return this.table.Insert(ctx, profile) -} - -func (this profileTable) Update(ctx context.Context, profile *Profile) error { - return this.table.Update(ctx, profile) -} - -func (this profileTable) Save(ctx context.Context, profile *Profile) error { - return this.table.Save(ctx, profile) -} - -func (this profileTable) Delete(ctx context.Context, profile *Profile) error { - return this.table.Delete(ctx, profile) -} - -func (this profileTable) Has(ctx context.Context, id string) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, id) -} - -func (this profileTable) Get(ctx context.Context, id string) (*Profile, error) { - var profile Profile - found, err := this.table.PrimaryKey().Get(ctx, &profile, id) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &profile, nil -} - -func (this profileTable) HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) { - return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, - subject, - origin, - ) -} - -func (this profileTable) GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Profile, error) { - var profile Profile - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &profile, - subject, - origin, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &profile, nil -} - -func (this profileTable) List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return ProfileIterator{it}, err -} - -func (this profileTable) ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return ProfileIterator{it}, err -} - -func (this profileTable) DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this profileTable) DeleteRange(ctx context.Context, from, to ProfileIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this profileTable) doNotImplement() {} - -var _ ProfileTable = profileTable{} - -func NewProfileTable(db ormtable.Schema) (ProfileTable, error) { - table := db.GetTable(&Profile{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Profile{}).ProtoReflect().Descriptor().FullName())) - } - return profileTable{table}, nil -} - -type StateStore interface { - MetadataTable() MetadataTable - ProfileTable() ProfileTable - - doNotImplement() -} - -type stateStore struct { - metadata MetadataTable - profile ProfileTable -} - -func (x stateStore) MetadataTable() MetadataTable { - return x.metadata -} - -func (x stateStore) ProfileTable() ProfileTable { - return x.profile -} - -func (stateStore) doNotImplement() {} - -var _ StateStore = stateStore{} - -func NewStateStore(db ormtable.Schema) (StateStore, error) { - metadataTable, err := NewMetadataTable(db) - if err != nil { - return nil, err - } - - profileTable, err := NewProfileTable(db) - if err != nil { - return nil, err - } - - return stateStore{ - metadataTable, - profileTable, - }, nil -} diff --git a/api/service/v1/state.pulsar.go b/api/service/v1/state.pulsar.go deleted file mode 100644 index c40f31343..000000000 --- a/api/service/v1/state.pulsar.go +++ /dev/null @@ -1,1752 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package servicev1 - -import ( - _ "cosmossdk.io/api/cosmos/orm/v1" - fmt "fmt" - runtime "github.com/cosmos/cosmos-proto/runtime" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var _ protoreflect.List = (*_Metadata_7_list)(nil) - -type _Metadata_7_list struct { - list *[]string -} - -func (x *_Metadata_7_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Metadata_7_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfString((*x.list)[i]) -} - -func (x *_Metadata_7_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - (*x.list)[i] = concreteValue -} - -func (x *_Metadata_7_list) Append(value protoreflect.Value) { - valueUnwrapped := value.String() - concreteValue := valueUnwrapped - *x.list = append(*x.list, concreteValue) -} - -func (x *_Metadata_7_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Metadata at list field Tags as it is not of Message kind")) -} - -func (x *_Metadata_7_list) Truncate(n int) { - *x.list = (*x.list)[:n] -} - -func (x *_Metadata_7_list) NewElement() protoreflect.Value { - v := "" - return protoreflect.ValueOfString(v) -} - -func (x *_Metadata_7_list) IsValid() bool { - return x.list != nil -} - -var ( - md_Metadata protoreflect.MessageDescriptor - fd_Metadata_id protoreflect.FieldDescriptor - fd_Metadata_origin protoreflect.FieldDescriptor - fd_Metadata_name protoreflect.FieldDescriptor - fd_Metadata_description protoreflect.FieldDescriptor - fd_Metadata_category protoreflect.FieldDescriptor - fd_Metadata_icon protoreflect.FieldDescriptor - fd_Metadata_tags protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_state_proto_init() - md_Metadata = File_service_v1_state_proto.Messages().ByName("Metadata") - fd_Metadata_id = md_Metadata.Fields().ByName("id") - fd_Metadata_origin = md_Metadata.Fields().ByName("origin") - fd_Metadata_name = md_Metadata.Fields().ByName("name") - fd_Metadata_description = md_Metadata.Fields().ByName("description") - fd_Metadata_category = md_Metadata.Fields().ByName("category") - fd_Metadata_icon = md_Metadata.Fields().ByName("icon") - fd_Metadata_tags = md_Metadata.Fields().ByName("tags") -} - -var _ protoreflect.Message = (*fastReflection_Metadata)(nil) - -type fastReflection_Metadata Metadata - -func (x *Metadata) ProtoReflect() protoreflect.Message { - return (*fastReflection_Metadata)(x) -} - -func (x *Metadata) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_state_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Metadata_messageType fastReflection_Metadata_messageType -var _ protoreflect.MessageType = fastReflection_Metadata_messageType{} - -type fastReflection_Metadata_messageType struct{} - -func (x fastReflection_Metadata_messageType) Zero() protoreflect.Message { - return (*fastReflection_Metadata)(nil) -} -func (x fastReflection_Metadata_messageType) New() protoreflect.Message { - return new(fastReflection_Metadata) -} -func (x fastReflection_Metadata_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Metadata -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Metadata) Descriptor() protoreflect.MessageDescriptor { - return md_Metadata -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Metadata) Type() protoreflect.MessageType { - return _fastReflection_Metadata_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Metadata) New() protoreflect.Message { - return new(fastReflection_Metadata) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Metadata) Interface() protoreflect.ProtoMessage { - return (*Metadata)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Metadata) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != uint64(0) { - value := protoreflect.ValueOfUint64(x.Id) - if !f(fd_Metadata_id, value) { - return - } - } - if x.Origin != "" { - value := protoreflect.ValueOfString(x.Origin) - if !f(fd_Metadata_origin, value) { - return - } - } - if x.Name != "" { - value := protoreflect.ValueOfString(x.Name) - if !f(fd_Metadata_name, value) { - return - } - } - if x.Description != "" { - value := protoreflect.ValueOfString(x.Description) - if !f(fd_Metadata_description, value) { - return - } - } - if x.Category != "" { - value := protoreflect.ValueOfString(x.Category) - if !f(fd_Metadata_category, value) { - return - } - } - if x.Icon != "" { - value := protoreflect.ValueOfString(x.Icon) - if !f(fd_Metadata_icon, value) { - return - } - } - if len(x.Tags) != 0 { - value := protoreflect.ValueOfList(&_Metadata_7_list{list: &x.Tags}) - if !f(fd_Metadata_tags, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Metadata) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.Metadata.id": - return x.Id != uint64(0) - case "service.v1.Metadata.origin": - return x.Origin != "" - case "service.v1.Metadata.name": - return x.Name != "" - case "service.v1.Metadata.description": - return x.Description != "" - case "service.v1.Metadata.category": - return x.Category != "" - case "service.v1.Metadata.icon": - return x.Icon != "" - case "service.v1.Metadata.tags": - return len(x.Tags) != 0 - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Metadata")) - } - panic(fmt.Errorf("message service.v1.Metadata does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Metadata) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.Metadata.id": - x.Id = uint64(0) - case "service.v1.Metadata.origin": - x.Origin = "" - case "service.v1.Metadata.name": - x.Name = "" - case "service.v1.Metadata.description": - x.Description = "" - case "service.v1.Metadata.category": - x.Category = "" - case "service.v1.Metadata.icon": - x.Icon = "" - case "service.v1.Metadata.tags": - x.Tags = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Metadata")) - } - panic(fmt.Errorf("message service.v1.Metadata does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Metadata) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.Metadata.id": - value := x.Id - return protoreflect.ValueOfUint64(value) - case "service.v1.Metadata.origin": - value := x.Origin - return protoreflect.ValueOfString(value) - case "service.v1.Metadata.name": - value := x.Name - return protoreflect.ValueOfString(value) - case "service.v1.Metadata.description": - value := x.Description - return protoreflect.ValueOfString(value) - case "service.v1.Metadata.category": - value := x.Category - return protoreflect.ValueOfString(value) - case "service.v1.Metadata.icon": - value := x.Icon - return protoreflect.ValueOfString(value) - case "service.v1.Metadata.tags": - if len(x.Tags) == 0 { - return protoreflect.ValueOfList(&_Metadata_7_list{}) - } - listValue := &_Metadata_7_list{list: &x.Tags} - return protoreflect.ValueOfList(listValue) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Metadata")) - } - panic(fmt.Errorf("message service.v1.Metadata does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.Metadata.id": - x.Id = value.Uint() - case "service.v1.Metadata.origin": - x.Origin = value.Interface().(string) - case "service.v1.Metadata.name": - x.Name = value.Interface().(string) - case "service.v1.Metadata.description": - x.Description = value.Interface().(string) - case "service.v1.Metadata.category": - x.Category = value.Interface().(string) - case "service.v1.Metadata.icon": - x.Icon = value.Interface().(string) - case "service.v1.Metadata.tags": - lv := value.List() - clv := lv.(*_Metadata_7_list) - x.Tags = *clv.list - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Metadata")) - } - panic(fmt.Errorf("message service.v1.Metadata does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Metadata) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.Metadata.tags": - if x.Tags == nil { - x.Tags = []string{} - } - value := &_Metadata_7_list{list: &x.Tags} - return protoreflect.ValueOfList(value) - case "service.v1.Metadata.id": - panic(fmt.Errorf("field id of message service.v1.Metadata is not mutable")) - case "service.v1.Metadata.origin": - panic(fmt.Errorf("field origin of message service.v1.Metadata is not mutable")) - case "service.v1.Metadata.name": - panic(fmt.Errorf("field name of message service.v1.Metadata is not mutable")) - case "service.v1.Metadata.description": - panic(fmt.Errorf("field description of message service.v1.Metadata is not mutable")) - case "service.v1.Metadata.category": - panic(fmt.Errorf("field category of message service.v1.Metadata is not mutable")) - case "service.v1.Metadata.icon": - panic(fmt.Errorf("field icon of message service.v1.Metadata is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Metadata")) - } - panic(fmt.Errorf("message service.v1.Metadata does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Metadata) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.Metadata.id": - return protoreflect.ValueOfUint64(uint64(0)) - case "service.v1.Metadata.origin": - return protoreflect.ValueOfString("") - case "service.v1.Metadata.name": - return protoreflect.ValueOfString("") - case "service.v1.Metadata.description": - return protoreflect.ValueOfString("") - case "service.v1.Metadata.category": - return protoreflect.ValueOfString("") - case "service.v1.Metadata.icon": - return protoreflect.ValueOfString("") - case "service.v1.Metadata.tags": - list := []string{} - return protoreflect.ValueOfList(&_Metadata_7_list{list: &list}) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Metadata")) - } - panic(fmt.Errorf("message service.v1.Metadata does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Metadata) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.Metadata", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Metadata) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Metadata) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Metadata) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Metadata) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Id != 0 { - n += 1 + runtime.Sov(uint64(x.Id)) - } - l = len(x.Origin) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Name) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Description) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Category) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Icon) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if len(x.Tags) > 0 { - for _, s := range x.Tags { - l = len(s) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Metadata) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Tags) > 0 { - for iNdEx := len(x.Tags) - 1; iNdEx >= 0; iNdEx-- { - i -= len(x.Tags[iNdEx]) - copy(dAtA[i:], x.Tags[iNdEx]) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Tags[iNdEx]))) - i-- - dAtA[i] = 0x3a - } - } - if len(x.Icon) > 0 { - i -= len(x.Icon) - copy(dAtA[i:], x.Icon) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Icon))) - i-- - dAtA[i] = 0x32 - } - if len(x.Category) > 0 { - i -= len(x.Category) - copy(dAtA[i:], x.Category) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Category))) - i-- - dAtA[i] = 0x2a - } - if len(x.Description) > 0 { - i -= len(x.Description) - copy(dAtA[i:], x.Description) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Description))) - i-- - dAtA[i] = 0x22 - } - if len(x.Name) > 0 { - i -= len(x.Name) - copy(dAtA[i:], x.Name) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) - i-- - dAtA[i] = 0x1a - } - if len(x.Origin) > 0 { - i -= len(x.Origin) - copy(dAtA[i:], x.Origin) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) - i-- - dAtA[i] = 0x12 - } - if x.Id != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Id)) - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Metadata) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - x.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Category", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Category = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Icon", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Icon = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Tags = append(x.Tags, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_Profile protoreflect.MessageDescriptor - fd_Profile_id protoreflect.FieldDescriptor - fd_Profile_subject protoreflect.FieldDescriptor - fd_Profile_origin protoreflect.FieldDescriptor - fd_Profile_controller protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_state_proto_init() - md_Profile = File_service_v1_state_proto.Messages().ByName("Profile") - fd_Profile_id = md_Profile.Fields().ByName("id") - fd_Profile_subject = md_Profile.Fields().ByName("subject") - fd_Profile_origin = md_Profile.Fields().ByName("origin") - fd_Profile_controller = md_Profile.Fields().ByName("controller") -} - -var _ protoreflect.Message = (*fastReflection_Profile)(nil) - -type fastReflection_Profile Profile - -func (x *Profile) ProtoReflect() protoreflect.Message { - return (*fastReflection_Profile)(x) -} - -func (x *Profile) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_state_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Profile_messageType fastReflection_Profile_messageType -var _ protoreflect.MessageType = fastReflection_Profile_messageType{} - -type fastReflection_Profile_messageType struct{} - -func (x fastReflection_Profile_messageType) Zero() protoreflect.Message { - return (*fastReflection_Profile)(nil) -} -func (x fastReflection_Profile_messageType) New() protoreflect.Message { - return new(fastReflection_Profile) -} -func (x fastReflection_Profile_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Profile -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Profile) Descriptor() protoreflect.MessageDescriptor { - return md_Profile -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Profile) Type() protoreflect.MessageType { - return _fastReflection_Profile_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Profile) New() protoreflect.Message { - return new(fastReflection_Profile) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Profile) Interface() protoreflect.ProtoMessage { - return (*Profile)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Profile) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != "" { - value := protoreflect.ValueOfString(x.Id) - if !f(fd_Profile_id, value) { - return - } - } - if x.Subject != "" { - value := protoreflect.ValueOfString(x.Subject) - if !f(fd_Profile_subject, value) { - return - } - } - if x.Origin != "" { - value := protoreflect.ValueOfString(x.Origin) - if !f(fd_Profile_origin, value) { - return - } - } - if x.Controller != "" { - value := protoreflect.ValueOfString(x.Controller) - if !f(fd_Profile_controller, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Profile) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.Profile.id": - return x.Id != "" - case "service.v1.Profile.subject": - return x.Subject != "" - case "service.v1.Profile.origin": - return x.Origin != "" - case "service.v1.Profile.controller": - return x.Controller != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Profile")) - } - panic(fmt.Errorf("message service.v1.Profile does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Profile) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.Profile.id": - x.Id = "" - case "service.v1.Profile.subject": - x.Subject = "" - case "service.v1.Profile.origin": - x.Origin = "" - case "service.v1.Profile.controller": - x.Controller = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Profile")) - } - panic(fmt.Errorf("message service.v1.Profile does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Profile) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.Profile.id": - value := x.Id - return protoreflect.ValueOfString(value) - case "service.v1.Profile.subject": - value := x.Subject - return protoreflect.ValueOfString(value) - case "service.v1.Profile.origin": - value := x.Origin - return protoreflect.ValueOfString(value) - case "service.v1.Profile.controller": - value := x.Controller - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Profile")) - } - panic(fmt.Errorf("message service.v1.Profile does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Profile) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.Profile.id": - x.Id = value.Interface().(string) - case "service.v1.Profile.subject": - x.Subject = value.Interface().(string) - case "service.v1.Profile.origin": - x.Origin = value.Interface().(string) - case "service.v1.Profile.controller": - x.Controller = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Profile")) - } - panic(fmt.Errorf("message service.v1.Profile does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Profile) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.Profile.id": - panic(fmt.Errorf("field id of message service.v1.Profile is not mutable")) - case "service.v1.Profile.subject": - panic(fmt.Errorf("field subject of message service.v1.Profile is not mutable")) - case "service.v1.Profile.origin": - panic(fmt.Errorf("field origin of message service.v1.Profile is not mutable")) - case "service.v1.Profile.controller": - panic(fmt.Errorf("field controller of message service.v1.Profile is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Profile")) - } - panic(fmt.Errorf("message service.v1.Profile does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Profile) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.Profile.id": - return protoreflect.ValueOfString("") - case "service.v1.Profile.subject": - return protoreflect.ValueOfString("") - case "service.v1.Profile.origin": - return protoreflect.ValueOfString("") - case "service.v1.Profile.controller": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.Profile")) - } - panic(fmt.Errorf("message service.v1.Profile does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Profile) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.Profile", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Profile) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Profile) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Profile) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Profile) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Profile) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Id) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Subject) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Origin) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Controller) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Profile) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Controller) > 0 { - i -= len(x.Controller) - copy(dAtA[i:], x.Controller) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) - i-- - dAtA[i] = 0x22 - } - if len(x.Origin) > 0 { - i -= len(x.Origin) - copy(dAtA[i:], x.Origin) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Origin))) - i-- - dAtA[i] = 0x1a - } - if len(x.Subject) > 0 { - i -= len(x.Subject) - copy(dAtA[i:], x.Subject) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Subject))) - i-- - dAtA[i] = 0x12 - } - if len(x.Id) > 0 { - i -= len(x.Id) - copy(dAtA[i:], x.Id) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Id))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Profile) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Profile: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Profile: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: service/v1/state.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Metadata struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` - Category string `protobuf:"bytes,5,opt,name=category,proto3" json:"category,omitempty"` - Icon string `protobuf:"bytes,6,opt,name=icon,proto3" json:"icon,omitempty"` - Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` -} - -func (x *Metadata) Reset() { - *x = Metadata{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_state_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Metadata) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Metadata) ProtoMessage() {} - -// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. -func (*Metadata) Descriptor() ([]byte, []int) { - return file_service_v1_state_proto_rawDescGZIP(), []int{0} -} - -func (x *Metadata) GetId() uint64 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *Metadata) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *Metadata) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Metadata) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Metadata) GetCategory() string { - if x != nil { - return x.Category - } - return "" -} - -func (x *Metadata) GetIcon() string { - if x != nil { - return x.Icon - } - return "" -} - -func (x *Metadata) GetTags() []string { - if x != nil { - return x.Tags - } - return nil -} - -// Profile represents a DID alias -type Profile struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The unique identifier of the alias - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // The alias of the DID - Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` - // Origin of the alias - Origin string `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` - // Controller of the alias - Controller string `protobuf:"bytes,4,opt,name=controller,proto3" json:"controller,omitempty"` -} - -func (x *Profile) Reset() { - *x = Profile{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_state_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Profile) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Profile) ProtoMessage() {} - -// Deprecated: Use Profile.ProtoReflect.Descriptor instead. -func (*Profile) Descriptor() ([]byte, []int) { - return file_service_v1_state_proto_rawDescGZIP(), []int{1} -} - -func (x *Profile) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Profile) GetSubject() string { - if x != nil { - return x.Subject - } - return "" -} - -func (x *Profile) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *Profile) GetController() string { - if x != nil { - return x.Controller - } - return "" -} - -var File_service_v1_state_proto protoreflect.FileDescriptor - -var file_service_v1_state_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, - 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcc, 0x01, - 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, - 0x67, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, - 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, - 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x3a, 0x1e, 0xf2, 0x9e, - 0xd3, 0x8e, 0x03, 0x18, 0x0a, 0x06, 0x0a, 0x02, 0x69, 0x64, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x06, - 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x01, 0x22, 0x91, 0x01, 0x0a, - 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x3a, 0x24, 0xf2, 0x9e, 0xd3, 0x8e, - 0x03, 0x1e, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x2c, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x02, - 0x42, 0x96, 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, - 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, - 0x56, 0x31, 0xe2, 0x02, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x56, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0b, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_service_v1_state_proto_rawDescOnce sync.Once - file_service_v1_state_proto_rawDescData = file_service_v1_state_proto_rawDesc -) - -func file_service_v1_state_proto_rawDescGZIP() []byte { - file_service_v1_state_proto_rawDescOnce.Do(func() { - file_service_v1_state_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_v1_state_proto_rawDescData) - }) - return file_service_v1_state_proto_rawDescData -} - -var file_service_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_service_v1_state_proto_goTypes = []interface{}{ - (*Metadata)(nil), // 0: service.v1.Metadata - (*Profile)(nil), // 1: service.v1.Profile -} -var file_service_v1_state_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_service_v1_state_proto_init() } -func file_service_v1_state_proto_init() { - if File_service_v1_state_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_service_v1_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metadata); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_state_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Profile); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_service_v1_state_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_service_v1_state_proto_goTypes, - DependencyIndexes: file_service_v1_state_proto_depIdxs, - MessageInfos: file_service_v1_state_proto_msgTypes, - }.Build() - File_service_v1_state_proto = out.File - file_service_v1_state_proto_rawDesc = nil - file_service_v1_state_proto_goTypes = nil - file_service_v1_state_proto_depIdxs = nil -} diff --git a/api/service/v1/tx.pulsar.go b/api/service/v1/tx.pulsar.go deleted file mode 100644 index feb847c60..000000000 --- a/api/service/v1/tx.pulsar.go +++ /dev/null @@ -1,2199 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package servicev1 - -import ( - _ "cosmossdk.io/api/cosmos/msg/v1" - fmt "fmt" - _ "github.com/cosmos/cosmos-proto" - runtime "github.com/cosmos/cosmos-proto/runtime" - _ "github.com/cosmos/gogoproto/gogoproto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_MsgUpdateParams protoreflect.MessageDescriptor - fd_MsgUpdateParams_authority protoreflect.FieldDescriptor - fd_MsgUpdateParams_params protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_tx_proto_init() - md_MsgUpdateParams = File_service_v1_tx_proto.Messages().ByName("MsgUpdateParams") - fd_MsgUpdateParams_authority = md_MsgUpdateParams.Fields().ByName("authority") - fd_MsgUpdateParams_params = md_MsgUpdateParams.Fields().ByName("params") -} - -var _ protoreflect.Message = (*fastReflection_MsgUpdateParams)(nil) - -type fastReflection_MsgUpdateParams MsgUpdateParams - -func (x *MsgUpdateParams) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgUpdateParams)(x) -} - -func (x *MsgUpdateParams) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_tx_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_MsgUpdateParams_messageType fastReflection_MsgUpdateParams_messageType -var _ protoreflect.MessageType = fastReflection_MsgUpdateParams_messageType{} - -type fastReflection_MsgUpdateParams_messageType struct{} - -func (x fastReflection_MsgUpdateParams_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgUpdateParams)(nil) -} -func (x fastReflection_MsgUpdateParams_messageType) New() protoreflect.Message { - return new(fastReflection_MsgUpdateParams) -} -func (x fastReflection_MsgUpdateParams_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgUpdateParams -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_MsgUpdateParams) Descriptor() protoreflect.MessageDescriptor { - return md_MsgUpdateParams -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgUpdateParams) Type() protoreflect.MessageType { - return _fastReflection_MsgUpdateParams_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgUpdateParams) New() protoreflect.Message { - return new(fastReflection_MsgUpdateParams) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgUpdateParams) Interface() protoreflect.ProtoMessage { - return (*MsgUpdateParams)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_MsgUpdateParams) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Authority != "" { - value := protoreflect.ValueOfString(x.Authority) - if !f(fd_MsgUpdateParams_authority, value) { - return - } - } - if x.Params != nil { - value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - if !f(fd_MsgUpdateParams_params, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.MsgUpdateParams.authority": - return x.Authority != "" - case "service.v1.MsgUpdateParams.params": - return x.Params != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.MsgUpdateParams.authority": - x.Authority = "" - case "service.v1.MsgUpdateParams.params": - x.Params = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgUpdateParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.MsgUpdateParams.authority": - value := x.Authority - return protoreflect.ValueOfString(value) - case "service.v1.MsgUpdateParams.params": - value := x.Params - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParams does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.MsgUpdateParams.authority": - x.Authority = value.Interface().(string) - case "service.v1.MsgUpdateParams.params": - x.Params = value.Message().Interface().(*Params) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.MsgUpdateParams.params": - if x.Params == nil { - x.Params = new(Params) - } - return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - case "service.v1.MsgUpdateParams.authority": - panic(fmt.Errorf("field authority of message service.v1.MsgUpdateParams is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgUpdateParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.MsgUpdateParams.authority": - return protoreflect.ValueOfString("") - case "service.v1.MsgUpdateParams.params": - m := new(Params) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgUpdateParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.MsgUpdateParams", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgUpdateParams) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParams) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_MsgUpdateParams) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_MsgUpdateParams) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgUpdateParams) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Authority) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.Params != nil { - l = options.Size(x.Params) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgUpdateParams) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Params != nil { - encoded, err := options.Marshal(x.Params) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x12 - } - if len(x.Authority) > 0 { - i -= len(x.Authority) - copy(dAtA[i:], x.Authority) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgUpdateParams) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Authority = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Params == nil { - x.Params = &Params{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_MsgUpdateParamsResponse protoreflect.MessageDescriptor -) - -func init() { - file_service_v1_tx_proto_init() - md_MsgUpdateParamsResponse = File_service_v1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") -} - -var _ protoreflect.Message = (*fastReflection_MsgUpdateParamsResponse)(nil) - -type fastReflection_MsgUpdateParamsResponse MsgUpdateParamsResponse - -func (x *MsgUpdateParamsResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgUpdateParamsResponse)(x) -} - -func (x *MsgUpdateParamsResponse) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_tx_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_MsgUpdateParamsResponse_messageType fastReflection_MsgUpdateParamsResponse_messageType -var _ protoreflect.MessageType = fastReflection_MsgUpdateParamsResponse_messageType{} - -type fastReflection_MsgUpdateParamsResponse_messageType struct{} - -func (x fastReflection_MsgUpdateParamsResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgUpdateParamsResponse)(nil) -} -func (x fastReflection_MsgUpdateParamsResponse_messageType) New() protoreflect.Message { - return new(fastReflection_MsgUpdateParamsResponse) -} -func (x fastReflection_MsgUpdateParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgUpdateParamsResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_MsgUpdateParamsResponse) Descriptor() protoreflect.MessageDescriptor { - return md_MsgUpdateParamsResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgUpdateParamsResponse) Type() protoreflect.MessageType { - return _fastReflection_MsgUpdateParamsResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgUpdateParamsResponse) New() protoreflect.Message { - return new(fastReflection_MsgUpdateParamsResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgUpdateParamsResponse) Interface() protoreflect.ProtoMessage { - return (*MsgUpdateParamsResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_MsgUpdateParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgUpdateParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParamsResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgUpdateParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParamsResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message service.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgUpdateParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.MsgUpdateParamsResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgUpdateParamsResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParamsResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_MsgUpdateParamsResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgUpdateParamsResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgUpdateParamsResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgUpdateParamsResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_MsgRegisterService protoreflect.MessageDescriptor - fd_MsgRegisterService_controller protoreflect.FieldDescriptor - fd_MsgRegisterService_service protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_tx_proto_init() - md_MsgRegisterService = File_service_v1_tx_proto.Messages().ByName("MsgRegisterService") - fd_MsgRegisterService_controller = md_MsgRegisterService.Fields().ByName("controller") - fd_MsgRegisterService_service = md_MsgRegisterService.Fields().ByName("service") -} - -var _ protoreflect.Message = (*fastReflection_MsgRegisterService)(nil) - -type fastReflection_MsgRegisterService MsgRegisterService - -func (x *MsgRegisterService) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgRegisterService)(x) -} - -func (x *MsgRegisterService) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_tx_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_MsgRegisterService_messageType fastReflection_MsgRegisterService_messageType -var _ protoreflect.MessageType = fastReflection_MsgRegisterService_messageType{} - -type fastReflection_MsgRegisterService_messageType struct{} - -func (x fastReflection_MsgRegisterService_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgRegisterService)(nil) -} -func (x fastReflection_MsgRegisterService_messageType) New() protoreflect.Message { - return new(fastReflection_MsgRegisterService) -} -func (x fastReflection_MsgRegisterService_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgRegisterService -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_MsgRegisterService) Descriptor() protoreflect.MessageDescriptor { - return md_MsgRegisterService -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgRegisterService) Type() protoreflect.MessageType { - return _fastReflection_MsgRegisterService_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgRegisterService) New() protoreflect.Message { - return new(fastReflection_MsgRegisterService) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgRegisterService) Interface() protoreflect.ProtoMessage { - return (*MsgRegisterService)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_MsgRegisterService) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Controller != "" { - value := protoreflect.ValueOfString(x.Controller) - if !f(fd_MsgRegisterService_controller, value) { - return - } - } - if x.Service != nil { - value := protoreflect.ValueOfMessage(x.Service.ProtoReflect()) - if !f(fd_MsgRegisterService_service, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgRegisterService) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.MsgRegisterService.controller": - return x.Controller != "" - case "service.v1.MsgRegisterService.service": - return x.Service != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterService")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterService does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgRegisterService) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.MsgRegisterService.controller": - x.Controller = "" - case "service.v1.MsgRegisterService.service": - x.Service = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterService")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterService does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgRegisterService) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.MsgRegisterService.controller": - value := x.Controller - return protoreflect.ValueOfString(value) - case "service.v1.MsgRegisterService.service": - value := x.Service - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterService")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterService does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgRegisterService) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.MsgRegisterService.controller": - x.Controller = value.Interface().(string) - case "service.v1.MsgRegisterService.service": - x.Service = value.Message().Interface().(*Service) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterService")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterService does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgRegisterService) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.MsgRegisterService.service": - if x.Service == nil { - x.Service = new(Service) - } - return protoreflect.ValueOfMessage(x.Service.ProtoReflect()) - case "service.v1.MsgRegisterService.controller": - panic(fmt.Errorf("field controller of message service.v1.MsgRegisterService is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterService")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterService does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgRegisterService) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.MsgRegisterService.controller": - return protoreflect.ValueOfString("") - case "service.v1.MsgRegisterService.service": - m := new(Service) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterService")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterService does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgRegisterService) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.MsgRegisterService", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgRegisterService) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgRegisterService) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_MsgRegisterService) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_MsgRegisterService) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgRegisterService) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Controller) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.Service != nil { - l = options.Size(x.Service) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgRegisterService) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Service != nil { - encoded, err := options.Marshal(x.Service) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x12 - } - if len(x.Controller) > 0 { - i -= len(x.Controller) - copy(dAtA[i:], x.Controller) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Controller))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgRegisterService) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgRegisterService: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgRegisterService: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Service == nil { - x.Service = &Service{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Service); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_MsgRegisterServiceResponse protoreflect.MessageDescriptor - fd_MsgRegisterServiceResponse_success protoreflect.FieldDescriptor - fd_MsgRegisterServiceResponse_did protoreflect.FieldDescriptor -) - -func init() { - file_service_v1_tx_proto_init() - md_MsgRegisterServiceResponse = File_service_v1_tx_proto.Messages().ByName("MsgRegisterServiceResponse") - fd_MsgRegisterServiceResponse_success = md_MsgRegisterServiceResponse.Fields().ByName("success") - fd_MsgRegisterServiceResponse_did = md_MsgRegisterServiceResponse.Fields().ByName("did") -} - -var _ protoreflect.Message = (*fastReflection_MsgRegisterServiceResponse)(nil) - -type fastReflection_MsgRegisterServiceResponse MsgRegisterServiceResponse - -func (x *MsgRegisterServiceResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgRegisterServiceResponse)(x) -} - -func (x *MsgRegisterServiceResponse) slowProtoReflect() protoreflect.Message { - mi := &file_service_v1_tx_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_MsgRegisterServiceResponse_messageType fastReflection_MsgRegisterServiceResponse_messageType -var _ protoreflect.MessageType = fastReflection_MsgRegisterServiceResponse_messageType{} - -type fastReflection_MsgRegisterServiceResponse_messageType struct{} - -func (x fastReflection_MsgRegisterServiceResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgRegisterServiceResponse)(nil) -} -func (x fastReflection_MsgRegisterServiceResponse_messageType) New() protoreflect.Message { - return new(fastReflection_MsgRegisterServiceResponse) -} -func (x fastReflection_MsgRegisterServiceResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgRegisterServiceResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_MsgRegisterServiceResponse) Descriptor() protoreflect.MessageDescriptor { - return md_MsgRegisterServiceResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgRegisterServiceResponse) Type() protoreflect.MessageType { - return _fastReflection_MsgRegisterServiceResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgRegisterServiceResponse) New() protoreflect.Message { - return new(fastReflection_MsgRegisterServiceResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgRegisterServiceResponse) Interface() protoreflect.ProtoMessage { - return (*MsgRegisterServiceResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_MsgRegisterServiceResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Success != false { - value := protoreflect.ValueOfBool(x.Success) - if !f(fd_MsgRegisterServiceResponse_success, value) { - return - } - } - if x.Did != "" { - value := protoreflect.ValueOfString(x.Did) - if !f(fd_MsgRegisterServiceResponse_did, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgRegisterServiceResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "service.v1.MsgRegisterServiceResponse.success": - return x.Success != false - case "service.v1.MsgRegisterServiceResponse.did": - return x.Did != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterServiceResponse")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgRegisterServiceResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "service.v1.MsgRegisterServiceResponse.success": - x.Success = false - case "service.v1.MsgRegisterServiceResponse.did": - x.Did = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterServiceResponse")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgRegisterServiceResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "service.v1.MsgRegisterServiceResponse.success": - value := x.Success - return protoreflect.ValueOfBool(value) - case "service.v1.MsgRegisterServiceResponse.did": - value := x.Did - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterServiceResponse")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterServiceResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgRegisterServiceResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "service.v1.MsgRegisterServiceResponse.success": - x.Success = value.Bool() - case "service.v1.MsgRegisterServiceResponse.did": - x.Did = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterServiceResponse")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgRegisterServiceResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.MsgRegisterServiceResponse.success": - panic(fmt.Errorf("field success of message service.v1.MsgRegisterServiceResponse is not mutable")) - case "service.v1.MsgRegisterServiceResponse.did": - panic(fmt.Errorf("field did of message service.v1.MsgRegisterServiceResponse is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterServiceResponse")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgRegisterServiceResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "service.v1.MsgRegisterServiceResponse.success": - return protoreflect.ValueOfBool(false) - case "service.v1.MsgRegisterServiceResponse.did": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: service.v1.MsgRegisterServiceResponse")) - } - panic(fmt.Errorf("message service.v1.MsgRegisterServiceResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgRegisterServiceResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in service.v1.MsgRegisterServiceResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgRegisterServiceResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgRegisterServiceResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_MsgRegisterServiceResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_MsgRegisterServiceResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgRegisterServiceResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Success { - n += 2 - } - l = len(x.Did) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgRegisterServiceResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Did) > 0 { - i -= len(x.Did) - copy(dAtA[i:], x.Did) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Did))) - i-- - dAtA[i] = 0x12 - } - if x.Success { - i-- - if x.Success { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgRegisterServiceResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgRegisterServiceResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgRegisterServiceResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - x.Success = bool(v != 0) - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Did", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Did = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: service/v1/tx.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// MsgUpdateParams is the Msg/UpdateParams request type. -// -// Since: cosmos-sdk 0.47 -type MsgUpdateParams struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // authority is the address of the governance account. - Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` - // params defines the parameters to update. - // - // NOTE: All parameters must be supplied. - Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` -} - -func (x *MsgUpdateParams) Reset() { - *x = MsgUpdateParams{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_tx_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MsgUpdateParams) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MsgUpdateParams) ProtoMessage() {} - -// Deprecated: Use MsgUpdateParams.ProtoReflect.Descriptor instead. -func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return file_service_v1_tx_proto_rawDescGZIP(), []int{0} -} - -func (x *MsgUpdateParams) GetAuthority() string { - if x != nil { - return x.Authority - } - return "" -} - -func (x *MsgUpdateParams) GetParams() *Params { - if x != nil { - return x.Params - } - return nil -} - -// MsgUpdateParamsResponse defines the response structure for executing a -// MsgUpdateParams message. -// -// Since: cosmos-sdk 0.47 -type MsgUpdateParamsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *MsgUpdateParamsResponse) Reset() { - *x = MsgUpdateParamsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_tx_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MsgUpdateParamsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MsgUpdateParamsResponse) ProtoMessage() {} - -// Deprecated: Use MsgUpdateParamsResponse.ProtoReflect.Descriptor instead. -func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return file_service_v1_tx_proto_rawDescGZIP(), []int{1} -} - -// MsgRegisterService is the message type for the RegisterService RPC. -type MsgRegisterService struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // authority is the address of the governance account. - Controller string `protobuf:"bytes,1,opt,name=controller,proto3" json:"controller,omitempty"` - // origin is the origin of the request in wildcard form. Requires valid TXT - // record in DNS. - Service *Service `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"` -} - -func (x *MsgRegisterService) Reset() { - *x = MsgRegisterService{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_tx_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MsgRegisterService) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MsgRegisterService) ProtoMessage() {} - -// Deprecated: Use MsgRegisterService.ProtoReflect.Descriptor instead. -func (*MsgRegisterService) Descriptor() ([]byte, []int) { - return file_service_v1_tx_proto_rawDescGZIP(), []int{2} -} - -func (x *MsgRegisterService) GetController() string { - if x != nil { - return x.Controller - } - return "" -} - -func (x *MsgRegisterService) GetService() *Service { - if x != nil { - return x.Service - } - return nil -} - -// MsgRegisterServiceResponse is the response type for the RegisterService RPC. -type MsgRegisterServiceResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - Did string `protobuf:"bytes,2,opt,name=did,proto3" json:"did,omitempty"` -} - -func (x *MsgRegisterServiceResponse) Reset() { - *x = MsgRegisterServiceResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_service_v1_tx_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MsgRegisterServiceResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MsgRegisterServiceResponse) ProtoMessage() {} - -// Deprecated: Use MsgRegisterServiceResponse.ProtoReflect.Descriptor instead. -func (*MsgRegisterServiceResponse) Descriptor() ([]byte, []int) { - return file_service_v1_tx_proto_rawDescGZIP(), []int{3} -} - -func (x *MsgRegisterServiceResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *MsgRegisterServiceResponse) GetDid() string { - if x != nil { - return x.Did - } - return "" -} - -var File_service_v1_tx_proto protoreflect.FileDescriptor - -var file_service_v1_tx_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x78, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, - 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, - 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8b, 0x01, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, - 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x12, 0x30, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8e, - 0x01, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, - 0x2d, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x0f, - 0x82, 0xe7, 0xb0, 0x2a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x22, - 0x48, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x32, 0xb9, 0x01, 0x0a, 0x03, 0x4d, 0x73, - 0x67, 0x12, 0x50, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x23, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x26, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, - 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x93, 0x01, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x0a, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x56, - 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0b, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var ( - file_service_v1_tx_proto_rawDescOnce sync.Once - file_service_v1_tx_proto_rawDescData = file_service_v1_tx_proto_rawDesc -) - -func file_service_v1_tx_proto_rawDescGZIP() []byte { - file_service_v1_tx_proto_rawDescOnce.Do(func() { - file_service_v1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_v1_tx_proto_rawDescData) - }) - return file_service_v1_tx_proto_rawDescData -} - -var file_service_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_service_v1_tx_proto_goTypes = []interface{}{ - (*MsgUpdateParams)(nil), // 0: service.v1.MsgUpdateParams - (*MsgUpdateParamsResponse)(nil), // 1: service.v1.MsgUpdateParamsResponse - (*MsgRegisterService)(nil), // 2: service.v1.MsgRegisterService - (*MsgRegisterServiceResponse)(nil), // 3: service.v1.MsgRegisterServiceResponse - (*Params)(nil), // 4: service.v1.Params - (*Service)(nil), // 5: service.v1.Service -} -var file_service_v1_tx_proto_depIdxs = []int32{ - 4, // 0: service.v1.MsgUpdateParams.params:type_name -> service.v1.Params - 5, // 1: service.v1.MsgRegisterService.service:type_name -> service.v1.Service - 0, // 2: service.v1.Msg.UpdateParams:input_type -> service.v1.MsgUpdateParams - 2, // 3: service.v1.Msg.RegisterService:input_type -> service.v1.MsgRegisterService - 1, // 4: service.v1.Msg.UpdateParams:output_type -> service.v1.MsgUpdateParamsResponse - 3, // 5: service.v1.Msg.RegisterService:output_type -> service.v1.MsgRegisterServiceResponse - 4, // [4:6] is the sub-list for method output_type - 2, // [2:4] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_service_v1_tx_proto_init() } -func file_service_v1_tx_proto_init() { - if File_service_v1_tx_proto != nil { - return - } - file_service_v1_genesis_proto_init() - if !protoimpl.UnsafeEnabled { - file_service_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgUpdateParams); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgUpdateParamsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_tx_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgRegisterService); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_service_v1_tx_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgRegisterServiceResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_service_v1_tx_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_service_v1_tx_proto_goTypes, - DependencyIndexes: file_service_v1_tx_proto_depIdxs, - MessageInfos: file_service_v1_tx_proto_msgTypes, - }.Build() - File_service_v1_tx_proto = out.File - file_service_v1_tx_proto_rawDesc = nil - file_service_v1_tx_proto_goTypes = nil - file_service_v1_tx_proto_depIdxs = nil -} diff --git a/api/service/v1/tx_grpc.pb.go b/api/service/v1/tx_grpc.pb.go deleted file mode 100644 index 0f5695081..000000000 --- a/api/service/v1/tx_grpc.pb.go +++ /dev/null @@ -1,173 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc (unknown) -// source: service/v1/tx.proto - -package servicev1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - Msg_UpdateParams_FullMethodName = "/service.v1.Msg/UpdateParams" - Msg_RegisterService_FullMethodName = "/service.v1.Msg/RegisterService" -) - -// MsgClient is the client API for Msg service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -// -// Msg defines the Msg service. -type MsgClient interface { - // UpdateParams defines a governance operation for updating the parameters. - // - // Since: cosmos-sdk 0.47 - UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) - // RegisterService initializes a Service with a given permission scope and - // URI. The domain must have a valid TXT record containing the public key. - RegisterService(ctx context.Context, in *MsgRegisterService, opts ...grpc.CallOption) (*MsgRegisterServiceResponse, error) -} - -type msgClient struct { - cc grpc.ClientConnInterface -} - -func NewMsgClient(cc grpc.ClientConnInterface) MsgClient { - return &msgClient{cc} -} - -func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(MsgUpdateParamsResponse) - err := c.cc.Invoke(ctx, Msg_UpdateParams_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *msgClient) RegisterService(ctx context.Context, in *MsgRegisterService, opts ...grpc.CallOption) (*MsgRegisterServiceResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(MsgRegisterServiceResponse) - err := c.cc.Invoke(ctx, Msg_RegisterService_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -// MsgServer is the server API for Msg service. -// All implementations must embed UnimplementedMsgServer -// for forward compatibility. -// -// Msg defines the Msg service. -type MsgServer interface { - // UpdateParams defines a governance operation for updating the parameters. - // - // Since: cosmos-sdk 0.47 - UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) - // RegisterService initializes a Service with a given permission scope and - // URI. The domain must have a valid TXT record containing the public key. - RegisterService(context.Context, *MsgRegisterService) (*MsgRegisterServiceResponse, error) - mustEmbedUnimplementedMsgServer() -} - -// UnimplementedMsgServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedMsgServer struct{} - -func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") -} -func (UnimplementedMsgServer) RegisterService(context.Context, *MsgRegisterService) (*MsgRegisterServiceResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RegisterService not implemented") -} -func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} -func (UnimplementedMsgServer) testEmbeddedByValue() {} - -// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to MsgServer will -// result in compilation errors. -type UnsafeMsgServer interface { - mustEmbedUnimplementedMsgServer() -} - -func RegisterMsgServer(s grpc.ServiceRegistrar, srv MsgServer) { - // If the following call pancis, it indicates UnimplementedMsgServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&Msg_ServiceDesc, srv) -} - -func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgUpdateParams) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).UpdateParams(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Msg_UpdateParams_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) - } - return interceptor(ctx, in, info, handler) -} - -func _Msg_RegisterService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgRegisterService) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).RegisterService(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Msg_RegisterService_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).RegisterService(ctx, req.(*MsgRegisterService)) - } - return interceptor(ctx, in, info, handler) -} - -// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Msg_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "service.v1.Msg", - HandlerType: (*MsgServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "UpdateParams", - Handler: _Msg_UpdateParams_Handler, - }, - { - MethodName: "RegisterService", - Handler: _Msg_RegisterService_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "service/v1/tx.proto", -} diff --git a/api/svc/v1/state.cosmos_orm.go b/api/svc/v1/state.cosmos_orm.go index 156ecf278..894502609 100644 --- a/api/svc/v1/state.cosmos_orm.go +++ b/api/svc/v1/state.cosmos_orm.go @@ -9,19 +9,177 @@ import ( ormerrors "cosmossdk.io/orm/types/ormerrors" ) +type DomainTable interface { + Insert(ctx context.Context, domain *Domain) error + InsertReturningId(ctx context.Context, domain *Domain) (uint64, error) + LastInsertedSequence(ctx context.Context) (uint64, error) + Update(ctx context.Context, domain *Domain) error + Save(ctx context.Context, domain *Domain) error + Delete(ctx context.Context, domain *Domain) error + Has(ctx context.Context, id uint64) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, id uint64) (*Domain, error) + HasByOrigin(ctx context.Context, origin string) (found bool, err error) + // GetByOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + GetByOrigin(ctx context.Context, origin string) (*Domain, error) + List(ctx context.Context, prefixKey DomainIndexKey, opts ...ormlist.Option) (DomainIterator, error) + ListRange(ctx context.Context, from, to DomainIndexKey, opts ...ormlist.Option) (DomainIterator, error) + DeleteBy(ctx context.Context, prefixKey DomainIndexKey) error + DeleteRange(ctx context.Context, from, to DomainIndexKey) error + + doNotImplement() +} + +type DomainIterator struct { + ormtable.Iterator +} + +func (i DomainIterator) Value() (*Domain, error) { + var domain Domain + err := i.UnmarshalMessage(&domain) + return &domain, err +} + +type DomainIndexKey interface { + id() uint32 + values() []interface{} + domainIndexKey() +} + +// primary key starting index.. +type DomainPrimaryKey = DomainIdIndexKey + +type DomainIdIndexKey struct { + vs []interface{} +} + +func (x DomainIdIndexKey) id() uint32 { return 0 } +func (x DomainIdIndexKey) values() []interface{} { return x.vs } +func (x DomainIdIndexKey) domainIndexKey() {} + +func (this DomainIdIndexKey) WithId(id uint64) DomainIdIndexKey { + this.vs = []interface{}{id} + return this +} + +type DomainOriginIndexKey struct { + vs []interface{} +} + +func (x DomainOriginIndexKey) id() uint32 { return 1 } +func (x DomainOriginIndexKey) values() []interface{} { return x.vs } +func (x DomainOriginIndexKey) domainIndexKey() {} + +func (this DomainOriginIndexKey) WithOrigin(origin string) DomainOriginIndexKey { + this.vs = []interface{}{origin} + return this +} + +type domainTable struct { + table ormtable.AutoIncrementTable +} + +func (this domainTable) Insert(ctx context.Context, domain *Domain) error { + return this.table.Insert(ctx, domain) +} + +func (this domainTable) Update(ctx context.Context, domain *Domain) error { + return this.table.Update(ctx, domain) +} + +func (this domainTable) Save(ctx context.Context, domain *Domain) error { + return this.table.Save(ctx, domain) +} + +func (this domainTable) Delete(ctx context.Context, domain *Domain) error { + return this.table.Delete(ctx, domain) +} + +func (this domainTable) InsertReturningId(ctx context.Context, domain *Domain) (uint64, error) { + return this.table.InsertReturningPKey(ctx, domain) +} + +func (this domainTable) LastInsertedSequence(ctx context.Context) (uint64, error) { + return this.table.LastInsertedSequence(ctx) +} + +func (this domainTable) Has(ctx context.Context, id uint64) (found bool, err error) { + return this.table.PrimaryKey().Has(ctx, id) +} + +func (this domainTable) Get(ctx context.Context, id uint64) (*Domain, error) { + var domain Domain + found, err := this.table.PrimaryKey().Get(ctx, &domain, id) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &domain, nil +} + +func (this domainTable) HasByOrigin(ctx context.Context, origin string) (found bool, err error) { + return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, + origin, + ) +} + +func (this domainTable) GetByOrigin(ctx context.Context, origin string) (*Domain, error) { + var domain Domain + found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &domain, + origin, + ) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &domain, nil +} + +func (this domainTable) List(ctx context.Context, prefixKey DomainIndexKey, opts ...ormlist.Option) (DomainIterator, error) { + it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) + return DomainIterator{it}, err +} + +func (this domainTable) ListRange(ctx context.Context, from, to DomainIndexKey, opts ...ormlist.Option) (DomainIterator, error) { + it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) + return DomainIterator{it}, err +} + +func (this domainTable) DeleteBy(ctx context.Context, prefixKey DomainIndexKey) error { + return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) +} + +func (this domainTable) DeleteRange(ctx context.Context, from, to DomainIndexKey) error { + return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) +} + +func (this domainTable) doNotImplement() {} + +var _ DomainTable = domainTable{} + +func NewDomainTable(db ormtable.Schema) (DomainTable, error) { + table := db.GetTable(&Domain{}) + if table == nil { + return nil, ormerrors.TableNotFound.Wrap(string((&Domain{}).ProtoReflect().Descriptor().FullName())) + } + return domainTable{table.(ormtable.AutoIncrementTable)}, nil +} + type MetadataTable interface { Insert(ctx context.Context, metadata *Metadata) error - InsertReturningId(ctx context.Context, metadata *Metadata) (uint64, error) - LastInsertedSequence(ctx context.Context) (uint64, error) Update(ctx context.Context, metadata *Metadata) error Save(ctx context.Context, metadata *Metadata) error Delete(ctx context.Context, metadata *Metadata) error - Has(ctx context.Context, id uint64) (found bool, err error) + Has(ctx context.Context, id string) (found bool, err error) // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, id uint64) (*Metadata, error) - HasByOrigin(ctx context.Context, origin string) (found bool, err error) - // GetByOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByOrigin(ctx context.Context, origin string) (*Metadata, error) + Get(ctx context.Context, id string) (*Metadata, error) + HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) + // GetBySubjectOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Metadata, error) List(ctx context.Context, prefixKey MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) ListRange(ctx context.Context, from, to MetadataIndexKey, opts ...ormlist.Option) (MetadataIterator, error) DeleteBy(ctx context.Context, prefixKey MetadataIndexKey) error @@ -57,26 +215,31 @@ func (x MetadataIdIndexKey) id() uint32 { return 0 } func (x MetadataIdIndexKey) values() []interface{} { return x.vs } func (x MetadataIdIndexKey) metadataIndexKey() {} -func (this MetadataIdIndexKey) WithId(id uint64) MetadataIdIndexKey { +func (this MetadataIdIndexKey) WithId(id string) MetadataIdIndexKey { this.vs = []interface{}{id} return this } -type MetadataOriginIndexKey struct { +type MetadataSubjectOriginIndexKey struct { vs []interface{} } -func (x MetadataOriginIndexKey) id() uint32 { return 1 } -func (x MetadataOriginIndexKey) values() []interface{} { return x.vs } -func (x MetadataOriginIndexKey) metadataIndexKey() {} +func (x MetadataSubjectOriginIndexKey) id() uint32 { return 1 } +func (x MetadataSubjectOriginIndexKey) values() []interface{} { return x.vs } +func (x MetadataSubjectOriginIndexKey) metadataIndexKey() {} -func (this MetadataOriginIndexKey) WithOrigin(origin string) MetadataOriginIndexKey { - this.vs = []interface{}{origin} +func (this MetadataSubjectOriginIndexKey) WithSubject(subject string) MetadataSubjectOriginIndexKey { + this.vs = []interface{}{subject} + return this +} + +func (this MetadataSubjectOriginIndexKey) WithSubjectOrigin(subject string, origin string) MetadataSubjectOriginIndexKey { + this.vs = []interface{}{subject, origin} return this } type metadataTable struct { - table ormtable.AutoIncrementTable + table ormtable.Table } func (this metadataTable) Insert(ctx context.Context, metadata *Metadata) error { @@ -95,19 +258,11 @@ func (this metadataTable) Delete(ctx context.Context, metadata *Metadata) error return this.table.Delete(ctx, metadata) } -func (this metadataTable) InsertReturningId(ctx context.Context, metadata *Metadata) (uint64, error) { - return this.table.InsertReturningPKey(ctx, metadata) -} - -func (this metadataTable) LastInsertedSequence(ctx context.Context) (uint64, error) { - return this.table.LastInsertedSequence(ctx) -} - -func (this metadataTable) Has(ctx context.Context, id uint64) (found bool, err error) { +func (this metadataTable) Has(ctx context.Context, id string) (found bool, err error) { return this.table.PrimaryKey().Has(ctx, id) } -func (this metadataTable) Get(ctx context.Context, id uint64) (*Metadata, error) { +func (this metadataTable) Get(ctx context.Context, id string) (*Metadata, error) { var metadata Metadata found, err := this.table.PrimaryKey().Get(ctx, &metadata, id) if err != nil { @@ -119,15 +274,17 @@ func (this metadataTable) Get(ctx context.Context, id uint64) (*Metadata, error) return &metadata, nil } -func (this metadataTable) HasByOrigin(ctx context.Context, origin string) (found bool, err error) { +func (this metadataTable) HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) { return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, + subject, origin, ) } -func (this metadataTable) GetByOrigin(ctx context.Context, origin string) (*Metadata, error) { +func (this metadataTable) GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Metadata, error) { var metadata Metadata found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &metadata, + subject, origin, ) if err != nil { @@ -166,203 +323,46 @@ func NewMetadataTable(db ormtable.Schema) (MetadataTable, error) { if table == nil { return nil, ormerrors.TableNotFound.Wrap(string((&Metadata{}).ProtoReflect().Descriptor().FullName())) } - return metadataTable{table.(ormtable.AutoIncrementTable)}, nil -} - -type ProfileTable interface { - Insert(ctx context.Context, profile *Profile) error - Update(ctx context.Context, profile *Profile) error - Save(ctx context.Context, profile *Profile) error - Delete(ctx context.Context, profile *Profile) error - Has(ctx context.Context, id string) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, id string) (*Profile, error) - HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) - // GetBySubjectOrigin returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Profile, error) - List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) - ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) - DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error - DeleteRange(ctx context.Context, from, to ProfileIndexKey) error - - doNotImplement() -} - -type ProfileIterator struct { - ormtable.Iterator -} - -func (i ProfileIterator) Value() (*Profile, error) { - var profile Profile - err := i.UnmarshalMessage(&profile) - return &profile, err -} - -type ProfileIndexKey interface { - id() uint32 - values() []interface{} - profileIndexKey() -} - -// primary key starting index.. -type ProfilePrimaryKey = ProfileIdIndexKey - -type ProfileIdIndexKey struct { - vs []interface{} -} - -func (x ProfileIdIndexKey) id() uint32 { return 0 } -func (x ProfileIdIndexKey) values() []interface{} { return x.vs } -func (x ProfileIdIndexKey) profileIndexKey() {} - -func (this ProfileIdIndexKey) WithId(id string) ProfileIdIndexKey { - this.vs = []interface{}{id} - return this -} - -type ProfileSubjectOriginIndexKey struct { - vs []interface{} -} - -func (x ProfileSubjectOriginIndexKey) id() uint32 { return 1 } -func (x ProfileSubjectOriginIndexKey) values() []interface{} { return x.vs } -func (x ProfileSubjectOriginIndexKey) profileIndexKey() {} - -func (this ProfileSubjectOriginIndexKey) WithSubject(subject string) ProfileSubjectOriginIndexKey { - this.vs = []interface{}{subject} - return this -} - -func (this ProfileSubjectOriginIndexKey) WithSubjectOrigin(subject string, origin string) ProfileSubjectOriginIndexKey { - this.vs = []interface{}{subject, origin} - return this -} - -type profileTable struct { - table ormtable.Table -} - -func (this profileTable) Insert(ctx context.Context, profile *Profile) error { - return this.table.Insert(ctx, profile) -} - -func (this profileTable) Update(ctx context.Context, profile *Profile) error { - return this.table.Update(ctx, profile) -} - -func (this profileTable) Save(ctx context.Context, profile *Profile) error { - return this.table.Save(ctx, profile) -} - -func (this profileTable) Delete(ctx context.Context, profile *Profile) error { - return this.table.Delete(ctx, profile) -} - -func (this profileTable) Has(ctx context.Context, id string) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, id) -} - -func (this profileTable) Get(ctx context.Context, id string) (*Profile, error) { - var profile Profile - found, err := this.table.PrimaryKey().Get(ctx, &profile, id) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &profile, nil -} - -func (this profileTable) HasBySubjectOrigin(ctx context.Context, subject string, origin string) (found bool, err error) { - return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, - subject, - origin, - ) -} - -func (this profileTable) GetBySubjectOrigin(ctx context.Context, subject string, origin string) (*Profile, error) { - var profile Profile - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &profile, - subject, - origin, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &profile, nil -} - -func (this profileTable) List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return ProfileIterator{it}, err -} - -func (this profileTable) ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return ProfileIterator{it}, err -} - -func (this profileTable) DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this profileTable) DeleteRange(ctx context.Context, from, to ProfileIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this profileTable) doNotImplement() {} - -var _ ProfileTable = profileTable{} - -func NewProfileTable(db ormtable.Schema) (ProfileTable, error) { - table := db.GetTable(&Profile{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Profile{}).ProtoReflect().Descriptor().FullName())) - } - return profileTable{table}, nil + return metadataTable{table}, nil } type StateStore interface { + DomainTable() DomainTable MetadataTable() MetadataTable - ProfileTable() ProfileTable doNotImplement() } type stateStore struct { + domain DomainTable metadata MetadataTable - profile ProfileTable +} + +func (x stateStore) DomainTable() DomainTable { + return x.domain } func (x stateStore) MetadataTable() MetadataTable { return x.metadata } -func (x stateStore) ProfileTable() ProfileTable { - return x.profile -} - func (stateStore) doNotImplement() {} var _ StateStore = stateStore{} func NewStateStore(db ormtable.Schema) (StateStore, error) { + domainTable, err := NewDomainTable(db) + if err != nil { + return nil, err + } + metadataTable, err := NewMetadataTable(db) if err != nil { return nil, err } - profileTable, err := NewProfileTable(db) - if err != nil { - return nil, err - } - return stateStore{ + domainTable, metadataTable, - profileTable, }, nil } diff --git a/api/svc/v1/state.pulsar.go b/api/svc/v1/state.pulsar.go index 0af9896b1..c42aa9514 100644 --- a/api/svc/v1/state.pulsar.go +++ b/api/svc/v1/state.pulsar.go @@ -13,84 +13,84 @@ import ( sync "sync" ) -var _ protoreflect.List = (*_Metadata_7_list)(nil) +var _ protoreflect.List = (*_Domain_7_list)(nil) -type _Metadata_7_list struct { +type _Domain_7_list struct { list *[]string } -func (x *_Metadata_7_list) Len() int { +func (x *_Domain_7_list) Len() int { if x.list == nil { return 0 } return len(*x.list) } -func (x *_Metadata_7_list) Get(i int) protoreflect.Value { +func (x *_Domain_7_list) Get(i int) protoreflect.Value { return protoreflect.ValueOfString((*x.list)[i]) } -func (x *_Metadata_7_list) Set(i int, value protoreflect.Value) { +func (x *_Domain_7_list) Set(i int, value protoreflect.Value) { valueUnwrapped := value.String() concreteValue := valueUnwrapped (*x.list)[i] = concreteValue } -func (x *_Metadata_7_list) Append(value protoreflect.Value) { +func (x *_Domain_7_list) Append(value protoreflect.Value) { valueUnwrapped := value.String() concreteValue := valueUnwrapped *x.list = append(*x.list, concreteValue) } -func (x *_Metadata_7_list) AppendMutable() protoreflect.Value { - panic(fmt.Errorf("AppendMutable can not be called on message Metadata at list field Tags as it is not of Message kind")) +func (x *_Domain_7_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Domain at list field Tags as it is not of Message kind")) } -func (x *_Metadata_7_list) Truncate(n int) { +func (x *_Domain_7_list) Truncate(n int) { *x.list = (*x.list)[:n] } -func (x *_Metadata_7_list) NewElement() protoreflect.Value { +func (x *_Domain_7_list) NewElement() protoreflect.Value { v := "" return protoreflect.ValueOfString(v) } -func (x *_Metadata_7_list) IsValid() bool { +func (x *_Domain_7_list) IsValid() bool { return x.list != nil } var ( - md_Metadata protoreflect.MessageDescriptor - fd_Metadata_id protoreflect.FieldDescriptor - fd_Metadata_origin protoreflect.FieldDescriptor - fd_Metadata_name protoreflect.FieldDescriptor - fd_Metadata_description protoreflect.FieldDescriptor - fd_Metadata_category protoreflect.FieldDescriptor - fd_Metadata_icon protoreflect.FieldDescriptor - fd_Metadata_tags protoreflect.FieldDescriptor + md_Domain protoreflect.MessageDescriptor + fd_Domain_id protoreflect.FieldDescriptor + fd_Domain_origin protoreflect.FieldDescriptor + fd_Domain_name protoreflect.FieldDescriptor + fd_Domain_description protoreflect.FieldDescriptor + fd_Domain_category protoreflect.FieldDescriptor + fd_Domain_icon protoreflect.FieldDescriptor + fd_Domain_tags protoreflect.FieldDescriptor ) func init() { file_svc_v1_state_proto_init() - md_Metadata = File_svc_v1_state_proto.Messages().ByName("Metadata") - fd_Metadata_id = md_Metadata.Fields().ByName("id") - fd_Metadata_origin = md_Metadata.Fields().ByName("origin") - fd_Metadata_name = md_Metadata.Fields().ByName("name") - fd_Metadata_description = md_Metadata.Fields().ByName("description") - fd_Metadata_category = md_Metadata.Fields().ByName("category") - fd_Metadata_icon = md_Metadata.Fields().ByName("icon") - fd_Metadata_tags = md_Metadata.Fields().ByName("tags") + md_Domain = File_svc_v1_state_proto.Messages().ByName("Domain") + fd_Domain_id = md_Domain.Fields().ByName("id") + fd_Domain_origin = md_Domain.Fields().ByName("origin") + fd_Domain_name = md_Domain.Fields().ByName("name") + fd_Domain_description = md_Domain.Fields().ByName("description") + fd_Domain_category = md_Domain.Fields().ByName("category") + fd_Domain_icon = md_Domain.Fields().ByName("icon") + fd_Domain_tags = md_Domain.Fields().ByName("tags") } -var _ protoreflect.Message = (*fastReflection_Metadata)(nil) +var _ protoreflect.Message = (*fastReflection_Domain)(nil) -type fastReflection_Metadata Metadata +type fastReflection_Domain Domain -func (x *Metadata) ProtoReflect() protoreflect.Message { - return (*fastReflection_Metadata)(x) +func (x *Domain) ProtoReflect() protoreflect.Message { + return (*fastReflection_Domain)(x) } -func (x *Metadata) slowProtoReflect() protoreflect.Message { +func (x *Domain) slowProtoReflect() protoreflect.Message { mi := &file_svc_v1_state_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -102,43 +102,43 @@ func (x *Metadata) slowProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -var _fastReflection_Metadata_messageType fastReflection_Metadata_messageType -var _ protoreflect.MessageType = fastReflection_Metadata_messageType{} +var _fastReflection_Domain_messageType fastReflection_Domain_messageType +var _ protoreflect.MessageType = fastReflection_Domain_messageType{} -type fastReflection_Metadata_messageType struct{} +type fastReflection_Domain_messageType struct{} -func (x fastReflection_Metadata_messageType) Zero() protoreflect.Message { - return (*fastReflection_Metadata)(nil) +func (x fastReflection_Domain_messageType) Zero() protoreflect.Message { + return (*fastReflection_Domain)(nil) } -func (x fastReflection_Metadata_messageType) New() protoreflect.Message { - return new(fastReflection_Metadata) +func (x fastReflection_Domain_messageType) New() protoreflect.Message { + return new(fastReflection_Domain) } -func (x fastReflection_Metadata_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Metadata +func (x fastReflection_Domain_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Domain } // Descriptor returns message descriptor, which contains only the protobuf // type information for the message. -func (x *fastReflection_Metadata) Descriptor() protoreflect.MessageDescriptor { - return md_Metadata +func (x *fastReflection_Domain) Descriptor() protoreflect.MessageDescriptor { + return md_Domain } // Type returns the message type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the message descriptor be used instead. -func (x *fastReflection_Metadata) Type() protoreflect.MessageType { - return _fastReflection_Metadata_messageType +func (x *fastReflection_Domain) Type() protoreflect.MessageType { + return _fastReflection_Domain_messageType } // New returns a newly allocated and mutable empty message. -func (x *fastReflection_Metadata) New() protoreflect.Message { - return new(fastReflection_Metadata) +func (x *fastReflection_Domain) New() protoreflect.Message { + return new(fastReflection_Domain) } // Interface unwraps the message reflection interface and // returns the underlying ProtoMessage interface. -func (x *fastReflection_Metadata) Interface() protoreflect.ProtoMessage { - return (*Metadata)(x) +func (x *fastReflection_Domain) Interface() protoreflect.ProtoMessage { + return (*Domain)(x) } // Range iterates over every populated field in an undefined order, @@ -146,46 +146,46 @@ func (x *fastReflection_Metadata) Interface() protoreflect.ProtoMessage { // Range returns immediately if f returns false. // While iterating, mutating operations may only be performed // on the current field descriptor. -func (x *fastReflection_Metadata) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +func (x *fastReflection_Domain) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { if x.Id != uint64(0) { value := protoreflect.ValueOfUint64(x.Id) - if !f(fd_Metadata_id, value) { + if !f(fd_Domain_id, value) { return } } if x.Origin != "" { value := protoreflect.ValueOfString(x.Origin) - if !f(fd_Metadata_origin, value) { + if !f(fd_Domain_origin, value) { return } } if x.Name != "" { value := protoreflect.ValueOfString(x.Name) - if !f(fd_Metadata_name, value) { + if !f(fd_Domain_name, value) { return } } if x.Description != "" { value := protoreflect.ValueOfString(x.Description) - if !f(fd_Metadata_description, value) { + if !f(fd_Domain_description, value) { return } } if x.Category != "" { value := protoreflect.ValueOfString(x.Category) - if !f(fd_Metadata_category, value) { + if !f(fd_Domain_category, value) { return } } if x.Icon != "" { value := protoreflect.ValueOfString(x.Icon) - if !f(fd_Metadata_icon, value) { + if !f(fd_Domain_icon, value) { return } } if len(x.Tags) != 0 { - value := protoreflect.ValueOfList(&_Metadata_7_list{list: &x.Tags}) - if !f(fd_Metadata_tags, value) { + value := protoreflect.ValueOfList(&_Domain_7_list{list: &x.Tags}) + if !f(fd_Domain_tags, value) { return } } @@ -202,27 +202,27 @@ func (x *fastReflection_Metadata) Range(f func(protoreflect.FieldDescriptor, pro // In other cases (aside from the nullable cases above), // a proto3 scalar field is populated if it contains a non-zero value, and // a repeated field is populated if it is non-empty. -func (x *fastReflection_Metadata) Has(fd protoreflect.FieldDescriptor) bool { +func (x *fastReflection_Domain) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "svc.v1.Metadata.id": + case "svc.v1.Domain.id": return x.Id != uint64(0) - case "svc.v1.Metadata.origin": + case "svc.v1.Domain.origin": return x.Origin != "" - case "svc.v1.Metadata.name": + case "svc.v1.Domain.name": return x.Name != "" - case "svc.v1.Metadata.description": + case "svc.v1.Domain.description": return x.Description != "" - case "svc.v1.Metadata.category": + case "svc.v1.Domain.category": return x.Category != "" - case "svc.v1.Metadata.icon": + case "svc.v1.Domain.icon": return x.Icon != "" - case "svc.v1.Metadata.tags": + case "svc.v1.Domain.tags": return len(x.Tags) != 0 default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Domain")) } - panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Domain does not contain field %s", fd.FullName())) } } @@ -232,27 +232,27 @@ func (x *fastReflection_Metadata) Has(fd protoreflect.FieldDescriptor) bool { // associated with the given field number. // // Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Metadata) Clear(fd protoreflect.FieldDescriptor) { +func (x *fastReflection_Domain) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "svc.v1.Metadata.id": + case "svc.v1.Domain.id": x.Id = uint64(0) - case "svc.v1.Metadata.origin": + case "svc.v1.Domain.origin": x.Origin = "" - case "svc.v1.Metadata.name": + case "svc.v1.Domain.name": x.Name = "" - case "svc.v1.Metadata.description": + case "svc.v1.Domain.description": x.Description = "" - case "svc.v1.Metadata.category": + case "svc.v1.Domain.category": x.Category = "" - case "svc.v1.Metadata.icon": + case "svc.v1.Domain.icon": x.Icon = "" - case "svc.v1.Metadata.tags": + case "svc.v1.Domain.tags": x.Tags = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Domain")) } - panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Domain does not contain field %s", fd.FullName())) } } @@ -262,37 +262,37 @@ func (x *fastReflection_Metadata) Clear(fd protoreflect.FieldDescriptor) { // the default value of a bytes scalar is guaranteed to be a copy. // For unpopulated composite types, it returns an empty, read-only view // of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Metadata) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Domain) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "svc.v1.Metadata.id": + case "svc.v1.Domain.id": value := x.Id return protoreflect.ValueOfUint64(value) - case "svc.v1.Metadata.origin": + case "svc.v1.Domain.origin": value := x.Origin return protoreflect.ValueOfString(value) - case "svc.v1.Metadata.name": + case "svc.v1.Domain.name": value := x.Name return protoreflect.ValueOfString(value) - case "svc.v1.Metadata.description": + case "svc.v1.Domain.description": value := x.Description return protoreflect.ValueOfString(value) - case "svc.v1.Metadata.category": + case "svc.v1.Domain.category": value := x.Category return protoreflect.ValueOfString(value) - case "svc.v1.Metadata.icon": + case "svc.v1.Domain.icon": value := x.Icon return protoreflect.ValueOfString(value) - case "svc.v1.Metadata.tags": + case "svc.v1.Domain.tags": if len(x.Tags) == 0 { - return protoreflect.ValueOfList(&_Metadata_7_list{}) + return protoreflect.ValueOfList(&_Domain_7_list{}) } - listValue := &_Metadata_7_list{list: &x.Tags} + listValue := &_Domain_7_list{list: &x.Tags} return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Domain")) } - panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message svc.v1.Domain does not contain field %s", descriptor.FullName())) } } @@ -306,29 +306,29 @@ func (x *fastReflection_Metadata) Get(descriptor protoreflect.FieldDescriptor) p // empty, read-only value, then it panics. // // Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { +func (x *fastReflection_Domain) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "svc.v1.Metadata.id": + case "svc.v1.Domain.id": x.Id = value.Uint() - case "svc.v1.Metadata.origin": + case "svc.v1.Domain.origin": x.Origin = value.Interface().(string) - case "svc.v1.Metadata.name": + case "svc.v1.Domain.name": x.Name = value.Interface().(string) - case "svc.v1.Metadata.description": + case "svc.v1.Domain.description": x.Description = value.Interface().(string) - case "svc.v1.Metadata.category": + case "svc.v1.Domain.category": x.Category = value.Interface().(string) - case "svc.v1.Metadata.icon": + case "svc.v1.Domain.icon": x.Icon = value.Interface().(string) - case "svc.v1.Metadata.tags": + case "svc.v1.Domain.tags": lv := value.List() - clv := lv.(*_Metadata_7_list) + clv := lv.(*_Domain_7_list) x.Tags = *clv.list default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Domain")) } - panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Domain does not contain field %s", fd.FullName())) } } @@ -342,69 +342,69 @@ func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value pro // It panics if the field does not contain a composite type. // // Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Metadata) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Domain) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "svc.v1.Metadata.tags": + case "svc.v1.Domain.tags": if x.Tags == nil { x.Tags = []string{} } - value := &_Metadata_7_list{list: &x.Tags} + value := &_Domain_7_list{list: &x.Tags} return protoreflect.ValueOfList(value) - case "svc.v1.Metadata.id": - panic(fmt.Errorf("field id of message svc.v1.Metadata is not mutable")) - case "svc.v1.Metadata.origin": - panic(fmt.Errorf("field origin of message svc.v1.Metadata is not mutable")) - case "svc.v1.Metadata.name": - panic(fmt.Errorf("field name of message svc.v1.Metadata is not mutable")) - case "svc.v1.Metadata.description": - panic(fmt.Errorf("field description of message svc.v1.Metadata is not mutable")) - case "svc.v1.Metadata.category": - panic(fmt.Errorf("field category of message svc.v1.Metadata is not mutable")) - case "svc.v1.Metadata.icon": - panic(fmt.Errorf("field icon of message svc.v1.Metadata is not mutable")) + case "svc.v1.Domain.id": + panic(fmt.Errorf("field id of message svc.v1.Domain is not mutable")) + case "svc.v1.Domain.origin": + panic(fmt.Errorf("field origin of message svc.v1.Domain is not mutable")) + case "svc.v1.Domain.name": + panic(fmt.Errorf("field name of message svc.v1.Domain is not mutable")) + case "svc.v1.Domain.description": + panic(fmt.Errorf("field description of message svc.v1.Domain is not mutable")) + case "svc.v1.Domain.category": + panic(fmt.Errorf("field category of message svc.v1.Domain is not mutable")) + case "svc.v1.Domain.icon": + panic(fmt.Errorf("field icon of message svc.v1.Domain is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Domain")) } - panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Domain does not contain field %s", fd.FullName())) } } // NewField returns a new value that is assignable to the field // for the given descriptor. For scalars, this returns the default value. // For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Metadata) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Domain) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "svc.v1.Metadata.id": + case "svc.v1.Domain.id": return protoreflect.ValueOfUint64(uint64(0)) - case "svc.v1.Metadata.origin": + case "svc.v1.Domain.origin": return protoreflect.ValueOfString("") - case "svc.v1.Metadata.name": + case "svc.v1.Domain.name": return protoreflect.ValueOfString("") - case "svc.v1.Metadata.description": + case "svc.v1.Domain.description": return protoreflect.ValueOfString("") - case "svc.v1.Metadata.category": + case "svc.v1.Domain.category": return protoreflect.ValueOfString("") - case "svc.v1.Metadata.icon": + case "svc.v1.Domain.icon": return protoreflect.ValueOfString("") - case "svc.v1.Metadata.tags": + case "svc.v1.Domain.tags": list := []string{} - return protoreflect.ValueOfList(&_Metadata_7_list{list: &list}) + return protoreflect.ValueOfList(&_Domain_7_list{list: &list}) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Domain")) } - panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Domain does not contain field %s", fd.FullName())) } } // WhichOneof reports which field within the oneof is populated, // returning nil if none are populated. // It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Metadata) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { +func (x *fastReflection_Domain) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in svc.v1.Metadata", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in svc.v1.Domain", d.FullName())) } panic("unreachable") } @@ -412,7 +412,7 @@ func (x *fastReflection_Metadata) WhichOneof(d protoreflect.OneofDescriptor) pro // GetUnknown retrieves the entire list of unknown fields. // The caller may only mutate the contents of the RawFields // if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Metadata) GetUnknown() protoreflect.RawFields { +func (x *fastReflection_Domain) GetUnknown() protoreflect.RawFields { return x.unknownFields } @@ -423,7 +423,7 @@ func (x *fastReflection_Metadata) GetUnknown() protoreflect.RawFields { // An empty RawFields may be passed to clear the fields. // // SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Metadata) SetUnknown(fields protoreflect.RawFields) { +func (x *fastReflection_Domain) SetUnknown(fields protoreflect.RawFields) { x.unknownFields = fields } @@ -435,7 +435,7 @@ func (x *fastReflection_Metadata) SetUnknown(fields protoreflect.RawFields) { // message type, but the details are implementation dependent. // Validity is not part of the protobuf data model, and may not // be preserved in marshaling or other operations. -func (x *fastReflection_Metadata) IsValid() bool { +func (x *fastReflection_Domain) IsValid() bool { return x != nil } @@ -445,9 +445,9 @@ func (x *fastReflection_Metadata) IsValid() bool { // The returned methods type is identical to // "google.golang.org/protobuf/runtime/protoiface".Methods. // Consult the protoiface package documentation for details. -func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { +func (x *fastReflection_Domain) ProtoMethods() *protoiface.Methods { size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Metadata) + x := input.Message.Interface().(*Domain) if x == nil { return protoiface.SizeOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -498,7 +498,7 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Metadata) + x := input.Message.Interface().(*Domain) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -577,7 +577,7 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Metadata) + x := input.Message.Interface().(*Domain) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -609,10 +609,10 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Domain: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Domain: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -862,31 +862,31 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { } var ( - md_Profile protoreflect.MessageDescriptor - fd_Profile_id protoreflect.FieldDescriptor - fd_Profile_subject protoreflect.FieldDescriptor - fd_Profile_origin protoreflect.FieldDescriptor - fd_Profile_controller protoreflect.FieldDescriptor + md_Metadata protoreflect.MessageDescriptor + fd_Metadata_id protoreflect.FieldDescriptor + fd_Metadata_subject protoreflect.FieldDescriptor + fd_Metadata_origin protoreflect.FieldDescriptor + fd_Metadata_controller protoreflect.FieldDescriptor ) func init() { file_svc_v1_state_proto_init() - md_Profile = File_svc_v1_state_proto.Messages().ByName("Profile") - fd_Profile_id = md_Profile.Fields().ByName("id") - fd_Profile_subject = md_Profile.Fields().ByName("subject") - fd_Profile_origin = md_Profile.Fields().ByName("origin") - fd_Profile_controller = md_Profile.Fields().ByName("controller") + md_Metadata = File_svc_v1_state_proto.Messages().ByName("Metadata") + fd_Metadata_id = md_Metadata.Fields().ByName("id") + fd_Metadata_subject = md_Metadata.Fields().ByName("subject") + fd_Metadata_origin = md_Metadata.Fields().ByName("origin") + fd_Metadata_controller = md_Metadata.Fields().ByName("controller") } -var _ protoreflect.Message = (*fastReflection_Profile)(nil) +var _ protoreflect.Message = (*fastReflection_Metadata)(nil) -type fastReflection_Profile Profile +type fastReflection_Metadata Metadata -func (x *Profile) ProtoReflect() protoreflect.Message { - return (*fastReflection_Profile)(x) +func (x *Metadata) ProtoReflect() protoreflect.Message { + return (*fastReflection_Metadata)(x) } -func (x *Profile) slowProtoReflect() protoreflect.Message { +func (x *Metadata) slowProtoReflect() protoreflect.Message { mi := &file_svc_v1_state_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -898,43 +898,43 @@ func (x *Profile) slowProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -var _fastReflection_Profile_messageType fastReflection_Profile_messageType -var _ protoreflect.MessageType = fastReflection_Profile_messageType{} +var _fastReflection_Metadata_messageType fastReflection_Metadata_messageType +var _ protoreflect.MessageType = fastReflection_Metadata_messageType{} -type fastReflection_Profile_messageType struct{} +type fastReflection_Metadata_messageType struct{} -func (x fastReflection_Profile_messageType) Zero() protoreflect.Message { - return (*fastReflection_Profile)(nil) +func (x fastReflection_Metadata_messageType) Zero() protoreflect.Message { + return (*fastReflection_Metadata)(nil) } -func (x fastReflection_Profile_messageType) New() protoreflect.Message { - return new(fastReflection_Profile) +func (x fastReflection_Metadata_messageType) New() protoreflect.Message { + return new(fastReflection_Metadata) } -func (x fastReflection_Profile_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Profile +func (x fastReflection_Metadata_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Metadata } // Descriptor returns message descriptor, which contains only the protobuf // type information for the message. -func (x *fastReflection_Profile) Descriptor() protoreflect.MessageDescriptor { - return md_Profile +func (x *fastReflection_Metadata) Descriptor() protoreflect.MessageDescriptor { + return md_Metadata } // Type returns the message type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the message descriptor be used instead. -func (x *fastReflection_Profile) Type() protoreflect.MessageType { - return _fastReflection_Profile_messageType +func (x *fastReflection_Metadata) Type() protoreflect.MessageType { + return _fastReflection_Metadata_messageType } // New returns a newly allocated and mutable empty message. -func (x *fastReflection_Profile) New() protoreflect.Message { - return new(fastReflection_Profile) +func (x *fastReflection_Metadata) New() protoreflect.Message { + return new(fastReflection_Metadata) } // Interface unwraps the message reflection interface and // returns the underlying ProtoMessage interface. -func (x *fastReflection_Profile) Interface() protoreflect.ProtoMessage { - return (*Profile)(x) +func (x *fastReflection_Metadata) Interface() protoreflect.ProtoMessage { + return (*Metadata)(x) } // Range iterates over every populated field in an undefined order, @@ -942,28 +942,28 @@ func (x *fastReflection_Profile) Interface() protoreflect.ProtoMessage { // Range returns immediately if f returns false. // While iterating, mutating operations may only be performed // on the current field descriptor. -func (x *fastReflection_Profile) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +func (x *fastReflection_Metadata) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { if x.Id != "" { value := protoreflect.ValueOfString(x.Id) - if !f(fd_Profile_id, value) { + if !f(fd_Metadata_id, value) { return } } if x.Subject != "" { value := protoreflect.ValueOfString(x.Subject) - if !f(fd_Profile_subject, value) { + if !f(fd_Metadata_subject, value) { return } } if x.Origin != "" { value := protoreflect.ValueOfString(x.Origin) - if !f(fd_Profile_origin, value) { + if !f(fd_Metadata_origin, value) { return } } if x.Controller != "" { value := protoreflect.ValueOfString(x.Controller) - if !f(fd_Profile_controller, value) { + if !f(fd_Metadata_controller, value) { return } } @@ -980,21 +980,21 @@ func (x *fastReflection_Profile) Range(f func(protoreflect.FieldDescriptor, prot // In other cases (aside from the nullable cases above), // a proto3 scalar field is populated if it contains a non-zero value, and // a repeated field is populated if it is non-empty. -func (x *fastReflection_Profile) Has(fd protoreflect.FieldDescriptor) bool { +func (x *fastReflection_Metadata) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "svc.v1.Profile.id": + case "svc.v1.Metadata.id": return x.Id != "" - case "svc.v1.Profile.subject": + case "svc.v1.Metadata.subject": return x.Subject != "" - case "svc.v1.Profile.origin": + case "svc.v1.Metadata.origin": return x.Origin != "" - case "svc.v1.Profile.controller": + case "svc.v1.Metadata.controller": return x.Controller != "" default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) } - panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) } } @@ -1004,21 +1004,21 @@ func (x *fastReflection_Profile) Has(fd protoreflect.FieldDescriptor) bool { // associated with the given field number. // // Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Profile) Clear(fd protoreflect.FieldDescriptor) { +func (x *fastReflection_Metadata) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "svc.v1.Profile.id": + case "svc.v1.Metadata.id": x.Id = "" - case "svc.v1.Profile.subject": + case "svc.v1.Metadata.subject": x.Subject = "" - case "svc.v1.Profile.origin": + case "svc.v1.Metadata.origin": x.Origin = "" - case "svc.v1.Profile.controller": + case "svc.v1.Metadata.controller": x.Controller = "" default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) } - panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) } } @@ -1028,25 +1028,25 @@ func (x *fastReflection_Profile) Clear(fd protoreflect.FieldDescriptor) { // the default value of a bytes scalar is guaranteed to be a copy. // For unpopulated composite types, it returns an empty, read-only view // of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Profile) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Metadata) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "svc.v1.Profile.id": + case "svc.v1.Metadata.id": value := x.Id return protoreflect.ValueOfString(value) - case "svc.v1.Profile.subject": + case "svc.v1.Metadata.subject": value := x.Subject return protoreflect.ValueOfString(value) - case "svc.v1.Profile.origin": + case "svc.v1.Metadata.origin": value := x.Origin return protoreflect.ValueOfString(value) - case "svc.v1.Profile.controller": + case "svc.v1.Metadata.controller": value := x.Controller return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) } - panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", descriptor.FullName())) } } @@ -1060,21 +1060,21 @@ func (x *fastReflection_Profile) Get(descriptor protoreflect.FieldDescriptor) pr // empty, read-only value, then it panics. // // Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Profile) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { +func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "svc.v1.Profile.id": + case "svc.v1.Metadata.id": x.Id = value.Interface().(string) - case "svc.v1.Profile.subject": + case "svc.v1.Metadata.subject": x.Subject = value.Interface().(string) - case "svc.v1.Profile.origin": + case "svc.v1.Metadata.origin": x.Origin = value.Interface().(string) - case "svc.v1.Profile.controller": + case "svc.v1.Metadata.controller": x.Controller = value.Interface().(string) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) } - panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) } } @@ -1088,52 +1088,52 @@ func (x *fastReflection_Profile) Set(fd protoreflect.FieldDescriptor, value prot // It panics if the field does not contain a composite type. // // Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Profile) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Metadata) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "svc.v1.Profile.id": - panic(fmt.Errorf("field id of message svc.v1.Profile is not mutable")) - case "svc.v1.Profile.subject": - panic(fmt.Errorf("field subject of message svc.v1.Profile is not mutable")) - case "svc.v1.Profile.origin": - panic(fmt.Errorf("field origin of message svc.v1.Profile is not mutable")) - case "svc.v1.Profile.controller": - panic(fmt.Errorf("field controller of message svc.v1.Profile is not mutable")) + case "svc.v1.Metadata.id": + panic(fmt.Errorf("field id of message svc.v1.Metadata is not mutable")) + case "svc.v1.Metadata.subject": + panic(fmt.Errorf("field subject of message svc.v1.Metadata is not mutable")) + case "svc.v1.Metadata.origin": + panic(fmt.Errorf("field origin of message svc.v1.Metadata is not mutable")) + case "svc.v1.Metadata.controller": + panic(fmt.Errorf("field controller of message svc.v1.Metadata is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) } - panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) } } // NewField returns a new value that is assignable to the field // for the given descriptor. For scalars, this returns the default value. // For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Profile) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { +func (x *fastReflection_Metadata) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "svc.v1.Profile.id": + case "svc.v1.Metadata.id": return protoreflect.ValueOfString("") - case "svc.v1.Profile.subject": + case "svc.v1.Metadata.subject": return protoreflect.ValueOfString("") - case "svc.v1.Profile.origin": + case "svc.v1.Metadata.origin": return protoreflect.ValueOfString("") - case "svc.v1.Profile.controller": + case "svc.v1.Metadata.controller": return protoreflect.ValueOfString("") default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Profile")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: svc.v1.Metadata")) } - panic(fmt.Errorf("message svc.v1.Profile does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message svc.v1.Metadata does not contain field %s", fd.FullName())) } } // WhichOneof reports which field within the oneof is populated, // returning nil if none are populated. // It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Profile) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { +func (x *fastReflection_Metadata) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in svc.v1.Profile", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in svc.v1.Metadata", d.FullName())) } panic("unreachable") } @@ -1141,7 +1141,7 @@ func (x *fastReflection_Profile) WhichOneof(d protoreflect.OneofDescriptor) prot // GetUnknown retrieves the entire list of unknown fields. // The caller may only mutate the contents of the RawFields // if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Profile) GetUnknown() protoreflect.RawFields { +func (x *fastReflection_Metadata) GetUnknown() protoreflect.RawFields { return x.unknownFields } @@ -1152,7 +1152,7 @@ func (x *fastReflection_Profile) GetUnknown() protoreflect.RawFields { // An empty RawFields may be passed to clear the fields. // // SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Profile) SetUnknown(fields protoreflect.RawFields) { +func (x *fastReflection_Metadata) SetUnknown(fields protoreflect.RawFields) { x.unknownFields = fields } @@ -1164,7 +1164,7 @@ func (x *fastReflection_Profile) SetUnknown(fields protoreflect.RawFields) { // message type, but the details are implementation dependent. // Validity is not part of the protobuf data model, and may not // be preserved in marshaling or other operations. -func (x *fastReflection_Profile) IsValid() bool { +func (x *fastReflection_Metadata) IsValid() bool { return x != nil } @@ -1174,9 +1174,9 @@ func (x *fastReflection_Profile) IsValid() bool { // The returned methods type is identical to // "google.golang.org/protobuf/runtime/protoiface".Methods. // Consult the protoiface package documentation for details. -func (x *fastReflection_Profile) ProtoMethods() *protoiface.Methods { +func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Profile) + x := input.Message.Interface().(*Metadata) if x == nil { return protoiface.SizeOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -1214,7 +1214,7 @@ func (x *fastReflection_Profile) ProtoMethods() *protoiface.Methods { } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Profile) + x := input.Message.Interface().(*Metadata) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -1272,7 +1272,7 @@ func (x *fastReflection_Profile) ProtoMethods() *protoiface.Methods { }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Profile) + x := input.Message.Interface().(*Metadata) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -1304,10 +1304,10 @@ func (x *fastReflection_Profile) ProtoMethods() *protoiface.Methods { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Profile: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Profile: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1486,7 +1486,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type Metadata struct { +type Domain struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -1500,8 +1500,8 @@ type Metadata struct { Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` } -func (x *Metadata) Reset() { - *x = Metadata{} +func (x *Domain) Reset() { + *x = Domain{} if protoimpl.UnsafeEnabled { mi := &file_svc_v1_state_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1509,68 +1509,68 @@ func (x *Metadata) Reset() { } } -func (x *Metadata) String() string { +func (x *Domain) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Metadata) ProtoMessage() {} +func (*Domain) ProtoMessage() {} -// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. -func (*Metadata) Descriptor() ([]byte, []int) { +// Deprecated: Use Domain.ProtoReflect.Descriptor instead. +func (*Domain) Descriptor() ([]byte, []int) { return file_svc_v1_state_proto_rawDescGZIP(), []int{0} } -func (x *Metadata) GetId() uint64 { +func (x *Domain) GetId() uint64 { if x != nil { return x.Id } return 0 } -func (x *Metadata) GetOrigin() string { +func (x *Domain) GetOrigin() string { if x != nil { return x.Origin } return "" } -func (x *Metadata) GetName() string { +func (x *Domain) GetName() string { if x != nil { return x.Name } return "" } -func (x *Metadata) GetDescription() string { +func (x *Domain) GetDescription() string { if x != nil { return x.Description } return "" } -func (x *Metadata) GetCategory() string { +func (x *Domain) GetCategory() string { if x != nil { return x.Category } return "" } -func (x *Metadata) GetIcon() string { +func (x *Domain) GetIcon() string { if x != nil { return x.Icon } return "" } -func (x *Metadata) GetTags() []string { +func (x *Domain) GetTags() []string { if x != nil { return x.Tags } return nil } -// Profile represents a DID alias -type Profile struct { +// Metadata represents a DID alias +type Metadata struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -1585,8 +1585,8 @@ type Profile struct { Controller string `protobuf:"bytes,4,opt,name=controller,proto3" json:"controller,omitempty"` } -func (x *Profile) Reset() { - *x = Profile{} +func (x *Metadata) Reset() { + *x = Metadata{} if protoimpl.UnsafeEnabled { mi := &file_svc_v1_state_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1594,39 +1594,39 @@ func (x *Profile) Reset() { } } -func (x *Profile) String() string { +func (x *Metadata) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Profile) ProtoMessage() {} +func (*Metadata) ProtoMessage() {} -// Deprecated: Use Profile.ProtoReflect.Descriptor instead. -func (*Profile) Descriptor() ([]byte, []int) { +// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. +func (*Metadata) Descriptor() ([]byte, []int) { return file_svc_v1_state_proto_rawDescGZIP(), []int{1} } -func (x *Profile) GetId() string { +func (x *Metadata) GetId() string { if x != nil { return x.Id } return "" } -func (x *Profile) GetSubject() string { +func (x *Metadata) GetSubject() string { if x != nil { return x.Subject } return "" } -func (x *Profile) GetOrigin() string { +func (x *Metadata) GetOrigin() string { if x != nil { return x.Origin } return "" } -func (x *Profile) GetController() string { +func (x *Metadata) GetController() string { if x != nil { return x.Controller } @@ -1639,37 +1639,37 @@ var file_svc_v1_state_proto_rawDesc = []byte{ 0x0a, 0x12, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcc, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, - 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, - 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, - 0x74, 0x61, 0x67, 0x73, 0x3a, 0x1e, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x18, 0x0a, 0x06, 0x0a, 0x02, - 0x69, 0x64, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, - 0x18, 0x01, 0x18, 0x01, 0x22, 0x91, 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x3a, 0x24, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x1e, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, - 0x12, 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x6f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x02, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, - 0x73, 0x76, 0x63, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x76, 0x63, 0x76, 0x31, 0xa2, 0x02, 0x03, - 0x53, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x53, 0x76, 0x63, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x53, - 0x76, 0x63, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x53, 0x76, 0x63, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x53, 0x76, 0x63, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xca, 0x01, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, + 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, + 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, + 0x67, 0x73, 0x3a, 0x1e, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x18, 0x0a, 0x06, 0x0a, 0x02, 0x69, 0x64, + 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x10, 0x01, 0x18, 0x01, + 0x18, 0x01, 0x22, 0x92, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, + 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x3a, 0x24, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x1e, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x12, + 0x14, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x6f, 0x72, 0x69, 0x67, 0x69, + 0x6e, 0x10, 0x01, 0x18, 0x01, 0x18, 0x02, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, + 0x76, 0x63, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x73, 0x76, 0x63, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x76, 0x63, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, + 0x58, 0x58, 0xaa, 0x02, 0x06, 0x53, 0x76, 0x63, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x53, 0x76, + 0x63, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x53, 0x76, 0x63, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x53, 0x76, 0x63, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1686,8 +1686,8 @@ func file_svc_v1_state_proto_rawDescGZIP() []byte { var file_svc_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_svc_v1_state_proto_goTypes = []interface{}{ - (*Metadata)(nil), // 0: svc.v1.Metadata - (*Profile)(nil), // 1: svc.v1.Profile + (*Domain)(nil), // 0: svc.v1.Domain + (*Metadata)(nil), // 1: svc.v1.Metadata } var file_svc_v1_state_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -1704,7 +1704,7 @@ func file_svc_v1_state_proto_init() { } if !protoimpl.UnsafeEnabled { file_svc_v1_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metadata); i { + switch v := v.(*Domain); i { case 0: return &v.state case 1: @@ -1716,7 +1716,7 @@ func file_svc_v1_state_proto_init() { } } file_svc_v1_state_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Profile); i { + switch v := v.(*Metadata); i { case 0: return &v.state case 1: diff --git a/api/vault/module/v1/module.pulsar.go b/api/vault/module/v1/module.pulsar.go deleted file mode 100644 index 1789eae62..000000000 --- a/api/vault/module/v1/module.pulsar.go +++ /dev/null @@ -1,499 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package modulev1 - -import ( - _ "cosmossdk.io/api/cosmos/app/v1alpha1" - fmt "fmt" - runtime "github.com/cosmos/cosmos-proto/runtime" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_Module protoreflect.MessageDescriptor -) - -func init() { - file_vault_module_v1_module_proto_init() - md_Module = File_vault_module_v1_module_proto.Messages().ByName("Module") -} - -var _ protoreflect.Message = (*fastReflection_Module)(nil) - -type fastReflection_Module Module - -func (x *Module) ProtoReflect() protoreflect.Message { - return (*fastReflection_Module)(x) -} - -func (x *Module) slowProtoReflect() protoreflect.Message { - mi := &file_vault_module_v1_module_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Module_messageType fastReflection_Module_messageType -var _ protoreflect.MessageType = fastReflection_Module_messageType{} - -type fastReflection_Module_messageType struct{} - -func (x fastReflection_Module_messageType) Zero() protoreflect.Message { - return (*fastReflection_Module)(nil) -} -func (x fastReflection_Module_messageType) New() protoreflect.Message { - return new(fastReflection_Module) -} -func (x fastReflection_Module_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Module -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Module) Descriptor() protoreflect.MessageDescriptor { - return md_Module -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Module) Type() protoreflect.MessageType { - return _fastReflection_Module_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Module) New() protoreflect.Message { - return new(fastReflection_Module) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage { - return (*Module)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) - } - panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) - } - panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) - } - panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) - } - panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) - } - panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.module.v1.Module")) - } - panic(fmt.Errorf("message vault.module.v1.Module does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.module.v1.Module", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Module) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Module) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Module) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Module) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Module) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Module) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: vault/module/v1/module.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Module is the app config object of the module. -// Learn more: https://docs.cosmos.network/main/building-modules/depinject -type Module struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Module) Reset() { - *x = Module{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_module_v1_module_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Module) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Module) ProtoMessage() {} - -// Deprecated: Use Module.ProtoReflect.Descriptor instead. -func (*Module) Descriptor() ([]byte, []int) { - return file_vault_module_v1_module_proto_rawDescGZIP(), []int{0} -} - -var File_vault_module_v1_module_proto protoreflect.FileDescriptor - -var file_vault_module_v1_module_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, - 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, - 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, - 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x1e, 0xba, 0xc0, 0x96, - 0xda, 0x01, 0x18, 0x0a, 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x42, 0xb5, 0x01, 0x0a, 0x13, - 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, - 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x56, 0x4d, 0x58, 0xaa, 0x02, 0x0f, - 0x56, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, - 0x02, 0x0f, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, - 0x31, 0xe2, 0x02, 0x1b, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x11, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, - 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_vault_module_v1_module_proto_rawDescOnce sync.Once - file_vault_module_v1_module_proto_rawDescData = file_vault_module_v1_module_proto_rawDesc -) - -func file_vault_module_v1_module_proto_rawDescGZIP() []byte { - file_vault_module_v1_module_proto_rawDescOnce.Do(func() { - file_vault_module_v1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_vault_module_v1_module_proto_rawDescData) - }) - return file_vault_module_v1_module_proto_rawDescData -} - -var file_vault_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_vault_module_v1_module_proto_goTypes = []interface{}{ - (*Module)(nil), // 0: vault.module.v1.Module -} -var file_vault_module_v1_module_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_vault_module_v1_module_proto_init() } -func file_vault_module_v1_module_proto_init() { - if File_vault_module_v1_module_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_vault_module_v1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Module); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_vault_module_v1_module_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_vault_module_v1_module_proto_goTypes, - DependencyIndexes: file_vault_module_v1_module_proto_depIdxs, - MessageInfos: file_vault_module_v1_module_proto_msgTypes, - }.Build() - File_vault_module_v1_module_proto = out.File - file_vault_module_v1_module_proto_rawDesc = nil - file_vault_module_v1_module_proto_goTypes = nil - file_vault_module_v1_module_proto_depIdxs = nil -} diff --git a/api/vault/v1/genesis.pulsar.go b/api/vault/v1/genesis.pulsar.go deleted file mode 100644 index 527134ec6..000000000 --- a/api/vault/v1/genesis.pulsar.go +++ /dev/null @@ -1,2323 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package vaultv1 - -import ( - _ "cosmossdk.io/api/amino" - fmt "fmt" - runtime "github.com/cosmos/cosmos-proto/runtime" - _ "github.com/cosmos/gogoproto/gogoproto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_GenesisState protoreflect.MessageDescriptor - fd_GenesisState_params protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_genesis_proto_init() - md_GenesisState = File_vault_v1_genesis_proto.Messages().ByName("GenesisState") - fd_GenesisState_params = md_GenesisState.Fields().ByName("params") -} - -var _ protoreflect.Message = (*fastReflection_GenesisState)(nil) - -type fastReflection_GenesisState GenesisState - -func (x *GenesisState) ProtoReflect() protoreflect.Message { - return (*fastReflection_GenesisState)(x) -} - -func (x *GenesisState) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_genesis_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_GenesisState_messageType fastReflection_GenesisState_messageType -var _ protoreflect.MessageType = fastReflection_GenesisState_messageType{} - -type fastReflection_GenesisState_messageType struct{} - -func (x fastReflection_GenesisState_messageType) Zero() protoreflect.Message { - return (*fastReflection_GenesisState)(nil) -} -func (x fastReflection_GenesisState_messageType) New() protoreflect.Message { - return new(fastReflection_GenesisState) -} -func (x fastReflection_GenesisState_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_GenesisState -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_GenesisState) Descriptor() protoreflect.MessageDescriptor { - return md_GenesisState -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_GenesisState) Type() protoreflect.MessageType { - return _fastReflection_GenesisState_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_GenesisState) New() protoreflect.Message { - return new(fastReflection_GenesisState) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_GenesisState) Interface() protoreflect.ProtoMessage { - return (*GenesisState)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Params != nil { - value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - if !f(fd_GenesisState_params, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.GenesisState.params": - return x.Params != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.GenesisState")) - } - panic(fmt.Errorf("message vault.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.GenesisState.params": - x.Params = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.GenesisState")) - } - panic(fmt.Errorf("message vault.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.GenesisState.params": - value := x.Params - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.GenesisState")) - } - panic(fmt.Errorf("message vault.v1.GenesisState does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.GenesisState.params": - x.Params = value.Message().Interface().(*Params) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.GenesisState")) - } - panic(fmt.Errorf("message vault.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.GenesisState.params": - if x.Params == nil { - x.Params = new(Params) - } - return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.GenesisState")) - } - panic(fmt.Errorf("message vault.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.GenesisState.params": - m := new(Params) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.GenesisState")) - } - panic(fmt.Errorf("message vault.v1.GenesisState does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_GenesisState) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.GenesisState", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_GenesisState) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_GenesisState) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_GenesisState) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*GenesisState) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Params != nil { - l = options.Size(x.Params) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*GenesisState) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Params != nil { - encoded, err := options.Marshal(x.Params) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*GenesisState) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Params == nil { - x.Params = &Params{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_Params protoreflect.MessageDescriptor - fd_Params_ipfs_active protoreflect.FieldDescriptor - fd_Params_local_registration_enabled protoreflect.FieldDescriptor - fd_Params_schema protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_genesis_proto_init() - md_Params = File_vault_v1_genesis_proto.Messages().ByName("Params") - fd_Params_ipfs_active = md_Params.Fields().ByName("ipfs_active") - fd_Params_local_registration_enabled = md_Params.Fields().ByName("local_registration_enabled") - fd_Params_schema = md_Params.Fields().ByName("schema") -} - -var _ protoreflect.Message = (*fastReflection_Params)(nil) - -type fastReflection_Params Params - -func (x *Params) ProtoReflect() protoreflect.Message { - return (*fastReflection_Params)(x) -} - -func (x *Params) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_genesis_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Params_messageType fastReflection_Params_messageType -var _ protoreflect.MessageType = fastReflection_Params_messageType{} - -type fastReflection_Params_messageType struct{} - -func (x fastReflection_Params_messageType) Zero() protoreflect.Message { - return (*fastReflection_Params)(nil) -} -func (x fastReflection_Params_messageType) New() protoreflect.Message { - return new(fastReflection_Params) -} -func (x fastReflection_Params_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Params -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Params) Descriptor() protoreflect.MessageDescriptor { - return md_Params -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Params) Type() protoreflect.MessageType { - return _fastReflection_Params_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Params) New() protoreflect.Message { - return new(fastReflection_Params) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { - return (*Params)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.IpfsActive != false { - value := protoreflect.ValueOfBool(x.IpfsActive) - if !f(fd_Params_ipfs_active, value) { - return - } - } - if x.LocalRegistrationEnabled != false { - value := protoreflect.ValueOfBool(x.LocalRegistrationEnabled) - if !f(fd_Params_local_registration_enabled, value) { - return - } - } - if x.Schema != nil { - value := protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) - if !f(fd_Params_schema, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.Params.ipfs_active": - return x.IpfsActive != false - case "vault.v1.Params.local_registration_enabled": - return x.LocalRegistrationEnabled != false - case "vault.v1.Params.schema": - return x.Schema != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Params")) - } - panic(fmt.Errorf("message vault.v1.Params does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.Params.ipfs_active": - x.IpfsActive = false - case "vault.v1.Params.local_registration_enabled": - x.LocalRegistrationEnabled = false - case "vault.v1.Params.schema": - x.Schema = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Params")) - } - panic(fmt.Errorf("message vault.v1.Params does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.Params.ipfs_active": - value := x.IpfsActive - return protoreflect.ValueOfBool(value) - case "vault.v1.Params.local_registration_enabled": - value := x.LocalRegistrationEnabled - return protoreflect.ValueOfBool(value) - case "vault.v1.Params.schema": - value := x.Schema - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Params")) - } - panic(fmt.Errorf("message vault.v1.Params does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.Params.ipfs_active": - x.IpfsActive = value.Bool() - case "vault.v1.Params.local_registration_enabled": - x.LocalRegistrationEnabled = value.Bool() - case "vault.v1.Params.schema": - x.Schema = value.Message().Interface().(*Schema) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Params")) - } - panic(fmt.Errorf("message vault.v1.Params does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.Params.schema": - if x.Schema == nil { - x.Schema = new(Schema) - } - return protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) - case "vault.v1.Params.ipfs_active": - panic(fmt.Errorf("field ipfs_active of message vault.v1.Params is not mutable")) - case "vault.v1.Params.local_registration_enabled": - panic(fmt.Errorf("field local_registration_enabled of message vault.v1.Params is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Params")) - } - panic(fmt.Errorf("message vault.v1.Params does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.Params.ipfs_active": - return protoreflect.ValueOfBool(false) - case "vault.v1.Params.local_registration_enabled": - return protoreflect.ValueOfBool(false) - case "vault.v1.Params.schema": - m := new(Schema) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Params")) - } - panic(fmt.Errorf("message vault.v1.Params does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.Params", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Params) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Params) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Params) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Params) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.IpfsActive { - n += 2 - } - if x.LocalRegistrationEnabled { - n += 2 - } - if x.Schema != nil { - l = options.Size(x.Schema) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Params) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Schema != nil { - encoded, err := options.Marshal(x.Schema) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x22 - } - if x.LocalRegistrationEnabled { - i-- - if x.LocalRegistrationEnabled { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 - } - if x.IpfsActive { - i-- - if x.IpfsActive { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Params) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field IpfsActive", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - x.IpfsActive = bool(v != 0) - case 2: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field LocalRegistrationEnabled", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - x.LocalRegistrationEnabled = bool(v != 0) - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Schema == nil { - x.Schema = &Schema{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Schema); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_Schema protoreflect.MessageDescriptor - fd_Schema_version protoreflect.FieldDescriptor - fd_Schema_account protoreflect.FieldDescriptor - fd_Schema_asset protoreflect.FieldDescriptor - fd_Schema_chain protoreflect.FieldDescriptor - fd_Schema_credential protoreflect.FieldDescriptor - fd_Schema_did protoreflect.FieldDescriptor - fd_Schema_jwk protoreflect.FieldDescriptor - fd_Schema_grant protoreflect.FieldDescriptor - fd_Schema_keyshare protoreflect.FieldDescriptor - fd_Schema_profile protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_genesis_proto_init() - md_Schema = File_vault_v1_genesis_proto.Messages().ByName("Schema") - fd_Schema_version = md_Schema.Fields().ByName("version") - fd_Schema_account = md_Schema.Fields().ByName("account") - fd_Schema_asset = md_Schema.Fields().ByName("asset") - fd_Schema_chain = md_Schema.Fields().ByName("chain") - fd_Schema_credential = md_Schema.Fields().ByName("credential") - fd_Schema_did = md_Schema.Fields().ByName("did") - fd_Schema_jwk = md_Schema.Fields().ByName("jwk") - fd_Schema_grant = md_Schema.Fields().ByName("grant") - fd_Schema_keyshare = md_Schema.Fields().ByName("keyshare") - fd_Schema_profile = md_Schema.Fields().ByName("profile") -} - -var _ protoreflect.Message = (*fastReflection_Schema)(nil) - -type fastReflection_Schema Schema - -func (x *Schema) ProtoReflect() protoreflect.Message { - return (*fastReflection_Schema)(x) -} - -func (x *Schema) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_genesis_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_Schema_messageType fastReflection_Schema_messageType -var _ protoreflect.MessageType = fastReflection_Schema_messageType{} - -type fastReflection_Schema_messageType struct{} - -func (x fastReflection_Schema_messageType) Zero() protoreflect.Message { - return (*fastReflection_Schema)(nil) -} -func (x fastReflection_Schema_messageType) New() protoreflect.Message { - return new(fastReflection_Schema) -} -func (x fastReflection_Schema_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_Schema -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_Schema) Descriptor() protoreflect.MessageDescriptor { - return md_Schema -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_Schema) Type() protoreflect.MessageType { - return _fastReflection_Schema_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_Schema) New() protoreflect.Message { - return new(fastReflection_Schema) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_Schema) Interface() protoreflect.ProtoMessage { - return (*Schema)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_Schema) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Version != int32(0) { - value := protoreflect.ValueOfInt32(x.Version) - if !f(fd_Schema_version, value) { - return - } - } - if x.Account != "" { - value := protoreflect.ValueOfString(x.Account) - if !f(fd_Schema_account, value) { - return - } - } - if x.Asset != "" { - value := protoreflect.ValueOfString(x.Asset) - if !f(fd_Schema_asset, value) { - return - } - } - if x.Chain != "" { - value := protoreflect.ValueOfString(x.Chain) - if !f(fd_Schema_chain, value) { - return - } - } - if x.Credential != "" { - value := protoreflect.ValueOfString(x.Credential) - if !f(fd_Schema_credential, value) { - return - } - } - if x.Did != "" { - value := protoreflect.ValueOfString(x.Did) - if !f(fd_Schema_did, value) { - return - } - } - if x.Jwk != "" { - value := protoreflect.ValueOfString(x.Jwk) - if !f(fd_Schema_jwk, value) { - return - } - } - if x.Grant != "" { - value := protoreflect.ValueOfString(x.Grant) - if !f(fd_Schema_grant, value) { - return - } - } - if x.Keyshare != "" { - value := protoreflect.ValueOfString(x.Keyshare) - if !f(fd_Schema_keyshare, value) { - return - } - } - if x.Profile != "" { - value := protoreflect.ValueOfString(x.Profile) - if !f(fd_Schema_profile, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_Schema) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.Schema.version": - return x.Version != int32(0) - case "vault.v1.Schema.account": - return x.Account != "" - case "vault.v1.Schema.asset": - return x.Asset != "" - case "vault.v1.Schema.chain": - return x.Chain != "" - case "vault.v1.Schema.credential": - return x.Credential != "" - case "vault.v1.Schema.did": - return x.Did != "" - case "vault.v1.Schema.jwk": - return x.Jwk != "" - case "vault.v1.Schema.grant": - return x.Grant != "" - case "vault.v1.Schema.keyshare": - return x.Keyshare != "" - case "vault.v1.Schema.profile": - return x.Profile != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Schema")) - } - panic(fmt.Errorf("message vault.v1.Schema does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Schema) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.Schema.version": - x.Version = int32(0) - case "vault.v1.Schema.account": - x.Account = "" - case "vault.v1.Schema.asset": - x.Asset = "" - case "vault.v1.Schema.chain": - x.Chain = "" - case "vault.v1.Schema.credential": - x.Credential = "" - case "vault.v1.Schema.did": - x.Did = "" - case "vault.v1.Schema.jwk": - x.Jwk = "" - case "vault.v1.Schema.grant": - x.Grant = "" - case "vault.v1.Schema.keyshare": - x.Keyshare = "" - case "vault.v1.Schema.profile": - x.Profile = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Schema")) - } - panic(fmt.Errorf("message vault.v1.Schema does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_Schema) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.Schema.version": - value := x.Version - return protoreflect.ValueOfInt32(value) - case "vault.v1.Schema.account": - value := x.Account - return protoreflect.ValueOfString(value) - case "vault.v1.Schema.asset": - value := x.Asset - return protoreflect.ValueOfString(value) - case "vault.v1.Schema.chain": - value := x.Chain - return protoreflect.ValueOfString(value) - case "vault.v1.Schema.credential": - value := x.Credential - return protoreflect.ValueOfString(value) - case "vault.v1.Schema.did": - value := x.Did - return protoreflect.ValueOfString(value) - case "vault.v1.Schema.jwk": - value := x.Jwk - return protoreflect.ValueOfString(value) - case "vault.v1.Schema.grant": - value := x.Grant - return protoreflect.ValueOfString(value) - case "vault.v1.Schema.keyshare": - value := x.Keyshare - return protoreflect.ValueOfString(value) - case "vault.v1.Schema.profile": - value := x.Profile - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Schema")) - } - panic(fmt.Errorf("message vault.v1.Schema does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Schema) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.Schema.version": - x.Version = int32(value.Int()) - case "vault.v1.Schema.account": - x.Account = value.Interface().(string) - case "vault.v1.Schema.asset": - x.Asset = value.Interface().(string) - case "vault.v1.Schema.chain": - x.Chain = value.Interface().(string) - case "vault.v1.Schema.credential": - x.Credential = value.Interface().(string) - case "vault.v1.Schema.did": - x.Did = value.Interface().(string) - case "vault.v1.Schema.jwk": - x.Jwk = value.Interface().(string) - case "vault.v1.Schema.grant": - x.Grant = value.Interface().(string) - case "vault.v1.Schema.keyshare": - x.Keyshare = value.Interface().(string) - case "vault.v1.Schema.profile": - x.Profile = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Schema")) - } - panic(fmt.Errorf("message vault.v1.Schema does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Schema) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.Schema.version": - panic(fmt.Errorf("field version of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.account": - panic(fmt.Errorf("field account of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.asset": - panic(fmt.Errorf("field asset of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.chain": - panic(fmt.Errorf("field chain of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.credential": - panic(fmt.Errorf("field credential of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.did": - panic(fmt.Errorf("field did of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.jwk": - panic(fmt.Errorf("field jwk of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.grant": - panic(fmt.Errorf("field grant of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.keyshare": - panic(fmt.Errorf("field keyshare of message vault.v1.Schema is not mutable")) - case "vault.v1.Schema.profile": - panic(fmt.Errorf("field profile of message vault.v1.Schema is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Schema")) - } - panic(fmt.Errorf("message vault.v1.Schema does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_Schema) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.Schema.version": - return protoreflect.ValueOfInt32(int32(0)) - case "vault.v1.Schema.account": - return protoreflect.ValueOfString("") - case "vault.v1.Schema.asset": - return protoreflect.ValueOfString("") - case "vault.v1.Schema.chain": - return protoreflect.ValueOfString("") - case "vault.v1.Schema.credential": - return protoreflect.ValueOfString("") - case "vault.v1.Schema.did": - return protoreflect.ValueOfString("") - case "vault.v1.Schema.jwk": - return protoreflect.ValueOfString("") - case "vault.v1.Schema.grant": - return protoreflect.ValueOfString("") - case "vault.v1.Schema.keyshare": - return protoreflect.ValueOfString("") - case "vault.v1.Schema.profile": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.Schema")) - } - panic(fmt.Errorf("message vault.v1.Schema does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_Schema) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.Schema", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_Schema) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_Schema) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_Schema) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_Schema) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*Schema) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Version != 0 { - n += 1 + runtime.Sov(uint64(x.Version)) - } - l = len(x.Account) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Asset) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Chain) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Credential) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Did) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Jwk) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Grant) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Keyshare) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Profile) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*Schema) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Profile) > 0 { - i -= len(x.Profile) - copy(dAtA[i:], x.Profile) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Profile))) - i-- - dAtA[i] = 0x52 - } - if len(x.Keyshare) > 0 { - i -= len(x.Keyshare) - copy(dAtA[i:], x.Keyshare) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Keyshare))) - i-- - dAtA[i] = 0x4a - } - if len(x.Grant) > 0 { - i -= len(x.Grant) - copy(dAtA[i:], x.Grant) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Grant))) - i-- - dAtA[i] = 0x42 - } - if len(x.Jwk) > 0 { - i -= len(x.Jwk) - copy(dAtA[i:], x.Jwk) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Jwk))) - i-- - dAtA[i] = 0x3a - } - if len(x.Did) > 0 { - i -= len(x.Did) - copy(dAtA[i:], x.Did) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Did))) - i-- - dAtA[i] = 0x32 - } - if len(x.Credential) > 0 { - i -= len(x.Credential) - copy(dAtA[i:], x.Credential) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Credential))) - i-- - dAtA[i] = 0x2a - } - if len(x.Chain) > 0 { - i -= len(x.Chain) - copy(dAtA[i:], x.Chain) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Chain))) - i-- - dAtA[i] = 0x22 - } - if len(x.Asset) > 0 { - i -= len(x.Asset) - copy(dAtA[i:], x.Asset) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Asset))) - i-- - dAtA[i] = 0x1a - } - if len(x.Account) > 0 { - i -= len(x.Account) - copy(dAtA[i:], x.Account) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Account))) - i-- - dAtA[i] = 0x12 - } - if x.Version != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Version)) - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*Schema) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Schema: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Schema: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - x.Version = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.Version |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Account = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Asset", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Asset = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Chain", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Chain = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Credential", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Credential = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Did", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Did = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Jwk", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Jwk = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 8: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Grant", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Grant = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 9: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Keyshare", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Keyshare = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 10: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Profile", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Profile = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: vault/v1/genesis.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// GenesisState defines the module genesis state -type GenesisState struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Params defines all the parameters of the module. - Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` -} - -func (x *GenesisState) Reset() { - *x = GenesisState{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_genesis_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GenesisState) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GenesisState) ProtoMessage() {} - -// Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. -func (*GenesisState) Descriptor() ([]byte, []int) { - return file_vault_v1_genesis_proto_rawDescGZIP(), []int{0} -} - -func (x *GenesisState) GetParams() *Params { - if x != nil { - return x.Params - } - return nil -} - -// Params defines the set of module parameters. -type Params struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IpfsActive bool `protobuf:"varint,1,opt,name=ipfs_active,json=ipfsActive,proto3" json:"ipfs_active,omitempty"` - LocalRegistrationEnabled bool `protobuf:"varint,2,opt,name=local_registration_enabled,json=localRegistrationEnabled,proto3" json:"local_registration_enabled,omitempty"` - Schema *Schema `protobuf:"bytes,4,opt,name=schema,proto3" json:"schema,omitempty"` -} - -func (x *Params) Reset() { - *x = Params{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_genesis_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Params) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Params) ProtoMessage() {} - -// Deprecated: Use Params.ProtoReflect.Descriptor instead. -func (*Params) Descriptor() ([]byte, []int) { - return file_vault_v1_genesis_proto_rawDescGZIP(), []int{1} -} - -func (x *Params) GetIpfsActive() bool { - if x != nil { - return x.IpfsActive - } - return false -} - -func (x *Params) GetLocalRegistrationEnabled() bool { - if x != nil { - return x.LocalRegistrationEnabled - } - return false -} - -func (x *Params) GetSchema() *Schema { - if x != nil { - return x.Schema - } - return nil -} - -type Schema struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Version int32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` - Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` - Asset string `protobuf:"bytes,3,opt,name=asset,proto3" json:"asset,omitempty"` - Chain string `protobuf:"bytes,4,opt,name=chain,proto3" json:"chain,omitempty"` - Credential string `protobuf:"bytes,5,opt,name=credential,proto3" json:"credential,omitempty"` - Did string `protobuf:"bytes,6,opt,name=did,proto3" json:"did,omitempty"` - Jwk string `protobuf:"bytes,7,opt,name=jwk,proto3" json:"jwk,omitempty"` - Grant string `protobuf:"bytes,8,opt,name=grant,proto3" json:"grant,omitempty"` - Keyshare string `protobuf:"bytes,9,opt,name=keyshare,proto3" json:"keyshare,omitempty"` - Profile string `protobuf:"bytes,10,opt,name=profile,proto3" json:"profile,omitempty"` -} - -func (x *Schema) Reset() { - *x = Schema{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_genesis_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Schema) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Schema) ProtoMessage() {} - -// Deprecated: Use Schema.ProtoReflect.Descriptor instead. -func (*Schema) Descriptor() ([]byte, []int) { - return file_vault_v1_genesis_proto_rawDescGZIP(), []int{2} -} - -func (x *Schema) GetVersion() int32 { - if x != nil { - return x.Version - } - return 0 -} - -func (x *Schema) GetAccount() string { - if x != nil { - return x.Account - } - return "" -} - -func (x *Schema) GetAsset() string { - if x != nil { - return x.Asset - } - return "" -} - -func (x *Schema) GetChain() string { - if x != nil { - return x.Chain - } - return "" -} - -func (x *Schema) GetCredential() string { - if x != nil { - return x.Credential - } - return "" -} - -func (x *Schema) GetDid() string { - if x != nil { - return x.Did - } - return "" -} - -func (x *Schema) GetJwk() string { - if x != nil { - return x.Jwk - } - return "" -} - -func (x *Schema) GetGrant() string { - if x != nil { - return x.Grant - } - return "" -} - -func (x *Schema) GetKeyshare() string { - if x != nil { - return x.Keyshare - } - return "" -} - -func (x *Schema) GetProfile() string { - if x != nil { - return x.Profile - } - return "" -} - -var File_vault_v1_genesis_proto protoreflect.FileDescriptor - -var file_vault_v1_genesis_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, - 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, - 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3e, 0x0a, 0x0c, 0x47, - 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x61, - 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, - 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xac, 0x01, 0x0a, 0x06, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x70, 0x66, 0x73, 0x5f, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x70, 0x66, - 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x1a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, - 0x19, 0x98, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0c, 0x76, 0x61, - 0x75, 0x6c, 0x74, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xf8, 0x01, 0x0a, 0x06, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, - 0x14, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x6b, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x61, - 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x68, 0x61, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x8a, 0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, - 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x61, 0x75, 0x6c, - 0x74, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x56, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x56, 0x61, 0x75, 0x6c, - 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, 0x31, 0xe2, - 0x02, 0x14, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x3a, - 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_vault_v1_genesis_proto_rawDescOnce sync.Once - file_vault_v1_genesis_proto_rawDescData = file_vault_v1_genesis_proto_rawDesc -) - -func file_vault_v1_genesis_proto_rawDescGZIP() []byte { - file_vault_v1_genesis_proto_rawDescOnce.Do(func() { - file_vault_v1_genesis_proto_rawDescData = protoimpl.X.CompressGZIP(file_vault_v1_genesis_proto_rawDescData) - }) - return file_vault_v1_genesis_proto_rawDescData -} - -var file_vault_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_vault_v1_genesis_proto_goTypes = []interface{}{ - (*GenesisState)(nil), // 0: vault.v1.GenesisState - (*Params)(nil), // 1: vault.v1.Params - (*Schema)(nil), // 2: vault.v1.Schema -} -var file_vault_v1_genesis_proto_depIdxs = []int32{ - 1, // 0: vault.v1.GenesisState.params:type_name -> vault.v1.Params - 2, // 1: vault.v1.Params.schema:type_name -> vault.v1.Schema - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_vault_v1_genesis_proto_init() } -func file_vault_v1_genesis_proto_init() { - if File_vault_v1_genesis_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_vault_v1_genesis_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GenesisState); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_genesis_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Params); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_genesis_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Schema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_vault_v1_genesis_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_vault_v1_genesis_proto_goTypes, - DependencyIndexes: file_vault_v1_genesis_proto_depIdxs, - MessageInfos: file_vault_v1_genesis_proto_msgTypes, - }.Build() - File_vault_v1_genesis_proto = out.File - file_vault_v1_genesis_proto_rawDesc = nil - file_vault_v1_genesis_proto_goTypes = nil - file_vault_v1_genesis_proto_depIdxs = nil -} diff --git a/api/vault/v1/query.pulsar.go b/api/vault/v1/query.pulsar.go deleted file mode 100644 index 78343f1a4..000000000 --- a/api/vault/v1/query.pulsar.go +++ /dev/null @@ -1,4221 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package vaultv1 - -import ( - fmt "fmt" - runtime "github.com/cosmos/cosmos-proto/runtime" - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_QueryParamsRequest protoreflect.MessageDescriptor -) - -func init() { - file_vault_v1_query_proto_init() - md_QueryParamsRequest = File_vault_v1_query_proto.Messages().ByName("QueryParamsRequest") -} - -var _ protoreflect.Message = (*fastReflection_QueryParamsRequest)(nil) - -type fastReflection_QueryParamsRequest QueryParamsRequest - -func (x *QueryParamsRequest) ProtoReflect() protoreflect.Message { - return (*fastReflection_QueryParamsRequest)(x) -} - -func (x *QueryParamsRequest) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_query_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QueryParamsRequest_messageType fastReflection_QueryParamsRequest_messageType -var _ protoreflect.MessageType = fastReflection_QueryParamsRequest_messageType{} - -type fastReflection_QueryParamsRequest_messageType struct{} - -func (x fastReflection_QueryParamsRequest_messageType) Zero() protoreflect.Message { - return (*fastReflection_QueryParamsRequest)(nil) -} -func (x fastReflection_QueryParamsRequest_messageType) New() protoreflect.Message { - return new(fastReflection_QueryParamsRequest) -} -func (x fastReflection_QueryParamsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QueryParamsRequest -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QueryParamsRequest) Descriptor() protoreflect.MessageDescriptor { - return md_QueryParamsRequest -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QueryParamsRequest) Type() protoreflect.MessageType { - return _fastReflection_QueryParamsRequest_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QueryParamsRequest) New() protoreflect.Message { - return new(fastReflection_QueryParamsRequest) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QueryParamsRequest) Interface() protoreflect.ProtoMessage { - return (*QueryParamsRequest)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QueryParamsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QueryParamsRequest) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsRequest) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QueryParamsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsRequest does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QueryParamsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsRequest does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QueryParamsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.QueryParamsRequest", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QueryParamsRequest) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsRequest) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QueryParamsRequest) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QueryParamsRequest) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QueryParamsRequest) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QueryParamsRequest) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QueryParamsRequest) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_QueryParamsResponse protoreflect.MessageDescriptor - fd_QueryParamsResponse_params protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_query_proto_init() - md_QueryParamsResponse = File_vault_v1_query_proto.Messages().ByName("QueryParamsResponse") - fd_QueryParamsResponse_params = md_QueryParamsResponse.Fields().ByName("params") -} - -var _ protoreflect.Message = (*fastReflection_QueryParamsResponse)(nil) - -type fastReflection_QueryParamsResponse QueryParamsResponse - -func (x *QueryParamsResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_QueryParamsResponse)(x) -} - -func (x *QueryParamsResponse) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_query_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QueryParamsResponse_messageType fastReflection_QueryParamsResponse_messageType -var _ protoreflect.MessageType = fastReflection_QueryParamsResponse_messageType{} - -type fastReflection_QueryParamsResponse_messageType struct{} - -func (x fastReflection_QueryParamsResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_QueryParamsResponse)(nil) -} -func (x fastReflection_QueryParamsResponse_messageType) New() protoreflect.Message { - return new(fastReflection_QueryParamsResponse) -} -func (x fastReflection_QueryParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QueryParamsResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QueryParamsResponse) Descriptor() protoreflect.MessageDescriptor { - return md_QueryParamsResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QueryParamsResponse) Type() protoreflect.MessageType { - return _fastReflection_QueryParamsResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QueryParamsResponse) New() protoreflect.Message { - return new(fastReflection_QueryParamsResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QueryParamsResponse) Interface() protoreflect.ProtoMessage { - return (*QueryParamsResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QueryParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Params != nil { - value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - if !f(fd_QueryParamsResponse_params, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QueryParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.QueryParamsResponse.params": - return x.Params != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.QueryParamsResponse.params": - x.Params = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QueryParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.QueryParamsResponse.params": - value := x.Params - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.QueryParamsResponse.params": - x.Params = value.Message().Interface().(*Params) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QueryParamsResponse.params": - if x.Params == nil { - x.Params = new(Params) - } - return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QueryParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QueryParamsResponse.params": - m := new(Params) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryParamsResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QueryParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.QueryParamsResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QueryParamsResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryParamsResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QueryParamsResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QueryParamsResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QueryParamsResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Params != nil { - l = options.Size(x.Params) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QueryParamsResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Params != nil { - encoded, err := options.Marshal(x.Params) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QueryParamsResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Params == nil { - x.Params = &Params{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_QuerySchemaRequest protoreflect.MessageDescriptor -) - -func init() { - file_vault_v1_query_proto_init() - md_QuerySchemaRequest = File_vault_v1_query_proto.Messages().ByName("QuerySchemaRequest") -} - -var _ protoreflect.Message = (*fastReflection_QuerySchemaRequest)(nil) - -type fastReflection_QuerySchemaRequest QuerySchemaRequest - -func (x *QuerySchemaRequest) ProtoReflect() protoreflect.Message { - return (*fastReflection_QuerySchemaRequest)(x) -} - -func (x *QuerySchemaRequest) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_query_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QuerySchemaRequest_messageType fastReflection_QuerySchemaRequest_messageType -var _ protoreflect.MessageType = fastReflection_QuerySchemaRequest_messageType{} - -type fastReflection_QuerySchemaRequest_messageType struct{} - -func (x fastReflection_QuerySchemaRequest_messageType) Zero() protoreflect.Message { - return (*fastReflection_QuerySchemaRequest)(nil) -} -func (x fastReflection_QuerySchemaRequest_messageType) New() protoreflect.Message { - return new(fastReflection_QuerySchemaRequest) -} -func (x fastReflection_QuerySchemaRequest_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QuerySchemaRequest -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QuerySchemaRequest) Descriptor() protoreflect.MessageDescriptor { - return md_QuerySchemaRequest -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QuerySchemaRequest) Type() protoreflect.MessageType { - return _fastReflection_QuerySchemaRequest_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QuerySchemaRequest) New() protoreflect.Message { - return new(fastReflection_QuerySchemaRequest) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QuerySchemaRequest) Interface() protoreflect.ProtoMessage { - return (*QuerySchemaRequest)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QuerySchemaRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QuerySchemaRequest) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySchemaRequest) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QuerySchemaRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaRequest does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySchemaRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySchemaRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QuerySchemaRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaRequest does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QuerySchemaRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.QuerySchemaRequest", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QuerySchemaRequest) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySchemaRequest) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QuerySchemaRequest) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QuerySchemaRequest) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QuerySchemaRequest) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QuerySchemaRequest) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QuerySchemaRequest) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySchemaRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySchemaRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_QuerySchemaResponse protoreflect.MessageDescriptor - fd_QuerySchemaResponse_schema protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_query_proto_init() - md_QuerySchemaResponse = File_vault_v1_query_proto.Messages().ByName("QuerySchemaResponse") - fd_QuerySchemaResponse_schema = md_QuerySchemaResponse.Fields().ByName("schema") -} - -var _ protoreflect.Message = (*fastReflection_QuerySchemaResponse)(nil) - -type fastReflection_QuerySchemaResponse QuerySchemaResponse - -func (x *QuerySchemaResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_QuerySchemaResponse)(x) -} - -func (x *QuerySchemaResponse) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_query_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QuerySchemaResponse_messageType fastReflection_QuerySchemaResponse_messageType -var _ protoreflect.MessageType = fastReflection_QuerySchemaResponse_messageType{} - -type fastReflection_QuerySchemaResponse_messageType struct{} - -func (x fastReflection_QuerySchemaResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_QuerySchemaResponse)(nil) -} -func (x fastReflection_QuerySchemaResponse_messageType) New() protoreflect.Message { - return new(fastReflection_QuerySchemaResponse) -} -func (x fastReflection_QuerySchemaResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QuerySchemaResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QuerySchemaResponse) Descriptor() protoreflect.MessageDescriptor { - return md_QuerySchemaResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QuerySchemaResponse) Type() protoreflect.MessageType { - return _fastReflection_QuerySchemaResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QuerySchemaResponse) New() protoreflect.Message { - return new(fastReflection_QuerySchemaResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QuerySchemaResponse) Interface() protoreflect.ProtoMessage { - return (*QuerySchemaResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QuerySchemaResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Schema != nil { - value := protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) - if !f(fd_QuerySchemaResponse_schema, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QuerySchemaResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.QuerySchemaResponse.schema": - return x.Schema != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySchemaResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.QuerySchemaResponse.schema": - x.Schema = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QuerySchemaResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.QuerySchemaResponse.schema": - value := x.Schema - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySchemaResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.QuerySchemaResponse.schema": - x.Schema = value.Message().Interface().(*Schema) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySchemaResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QuerySchemaResponse.schema": - if x.Schema == nil { - x.Schema = new(Schema) - } - return protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QuerySchemaResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QuerySchemaResponse.schema": - m := new(Schema) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySchemaResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySchemaResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QuerySchemaResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.QuerySchemaResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QuerySchemaResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySchemaResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QuerySchemaResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QuerySchemaResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QuerySchemaResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Schema != nil { - l = options.Size(x.Schema) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QuerySchemaResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Schema != nil { - encoded, err := options.Marshal(x.Schema) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QuerySchemaResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySchemaResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySchemaResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Schema == nil { - x.Schema = &Schema{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Schema); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_QueryAllocateRequest protoreflect.MessageDescriptor -) - -func init() { - file_vault_v1_query_proto_init() - md_QueryAllocateRequest = File_vault_v1_query_proto.Messages().ByName("QueryAllocateRequest") -} - -var _ protoreflect.Message = (*fastReflection_QueryAllocateRequest)(nil) - -type fastReflection_QueryAllocateRequest QueryAllocateRequest - -func (x *QueryAllocateRequest) ProtoReflect() protoreflect.Message { - return (*fastReflection_QueryAllocateRequest)(x) -} - -func (x *QueryAllocateRequest) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_query_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QueryAllocateRequest_messageType fastReflection_QueryAllocateRequest_messageType -var _ protoreflect.MessageType = fastReflection_QueryAllocateRequest_messageType{} - -type fastReflection_QueryAllocateRequest_messageType struct{} - -func (x fastReflection_QueryAllocateRequest_messageType) Zero() protoreflect.Message { - return (*fastReflection_QueryAllocateRequest)(nil) -} -func (x fastReflection_QueryAllocateRequest_messageType) New() protoreflect.Message { - return new(fastReflection_QueryAllocateRequest) -} -func (x fastReflection_QueryAllocateRequest_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QueryAllocateRequest -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QueryAllocateRequest) Descriptor() protoreflect.MessageDescriptor { - return md_QueryAllocateRequest -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QueryAllocateRequest) Type() protoreflect.MessageType { - return _fastReflection_QueryAllocateRequest_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QueryAllocateRequest) New() protoreflect.Message { - return new(fastReflection_QueryAllocateRequest) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QueryAllocateRequest) Interface() protoreflect.ProtoMessage { - return (*QueryAllocateRequest)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QueryAllocateRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QueryAllocateRequest) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryAllocateRequest) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QueryAllocateRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateRequest does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryAllocateRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryAllocateRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QueryAllocateRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateRequest")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateRequest does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QueryAllocateRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.QueryAllocateRequest", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QueryAllocateRequest) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryAllocateRequest) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QueryAllocateRequest) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QueryAllocateRequest) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QueryAllocateRequest) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QueryAllocateRequest) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QueryAllocateRequest) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllocateRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllocateRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_QueryAllocateResponse protoreflect.MessageDescriptor - fd_QueryAllocateResponse_success protoreflect.FieldDescriptor - fd_QueryAllocateResponse_cid protoreflect.FieldDescriptor - fd_QueryAllocateResponse_macaroon protoreflect.FieldDescriptor - fd_QueryAllocateResponse_public_uri protoreflect.FieldDescriptor - fd_QueryAllocateResponse_expiry_block protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_query_proto_init() - md_QueryAllocateResponse = File_vault_v1_query_proto.Messages().ByName("QueryAllocateResponse") - fd_QueryAllocateResponse_success = md_QueryAllocateResponse.Fields().ByName("success") - fd_QueryAllocateResponse_cid = md_QueryAllocateResponse.Fields().ByName("cid") - fd_QueryAllocateResponse_macaroon = md_QueryAllocateResponse.Fields().ByName("macaroon") - fd_QueryAllocateResponse_public_uri = md_QueryAllocateResponse.Fields().ByName("public_uri") - fd_QueryAllocateResponse_expiry_block = md_QueryAllocateResponse.Fields().ByName("expiry_block") -} - -var _ protoreflect.Message = (*fastReflection_QueryAllocateResponse)(nil) - -type fastReflection_QueryAllocateResponse QueryAllocateResponse - -func (x *QueryAllocateResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_QueryAllocateResponse)(x) -} - -func (x *QueryAllocateResponse) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_query_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QueryAllocateResponse_messageType fastReflection_QueryAllocateResponse_messageType -var _ protoreflect.MessageType = fastReflection_QueryAllocateResponse_messageType{} - -type fastReflection_QueryAllocateResponse_messageType struct{} - -func (x fastReflection_QueryAllocateResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_QueryAllocateResponse)(nil) -} -func (x fastReflection_QueryAllocateResponse_messageType) New() protoreflect.Message { - return new(fastReflection_QueryAllocateResponse) -} -func (x fastReflection_QueryAllocateResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QueryAllocateResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QueryAllocateResponse) Descriptor() protoreflect.MessageDescriptor { - return md_QueryAllocateResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QueryAllocateResponse) Type() protoreflect.MessageType { - return _fastReflection_QueryAllocateResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QueryAllocateResponse) New() protoreflect.Message { - return new(fastReflection_QueryAllocateResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QueryAllocateResponse) Interface() protoreflect.ProtoMessage { - return (*QueryAllocateResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QueryAllocateResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Success != false { - value := protoreflect.ValueOfBool(x.Success) - if !f(fd_QueryAllocateResponse_success, value) { - return - } - } - if x.Cid != "" { - value := protoreflect.ValueOfString(x.Cid) - if !f(fd_QueryAllocateResponse_cid, value) { - return - } - } - if x.Macaroon != "" { - value := protoreflect.ValueOfString(x.Macaroon) - if !f(fd_QueryAllocateResponse_macaroon, value) { - return - } - } - if x.PublicUri != "" { - value := protoreflect.ValueOfString(x.PublicUri) - if !f(fd_QueryAllocateResponse_public_uri, value) { - return - } - } - if x.ExpiryBlock != int64(0) { - value := protoreflect.ValueOfInt64(x.ExpiryBlock) - if !f(fd_QueryAllocateResponse_expiry_block, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QueryAllocateResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.QueryAllocateResponse.success": - return x.Success != false - case "vault.v1.QueryAllocateResponse.cid": - return x.Cid != "" - case "vault.v1.QueryAllocateResponse.macaroon": - return x.Macaroon != "" - case "vault.v1.QueryAllocateResponse.public_uri": - return x.PublicUri != "" - case "vault.v1.QueryAllocateResponse.expiry_block": - return x.ExpiryBlock != int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryAllocateResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.QueryAllocateResponse.success": - x.Success = false - case "vault.v1.QueryAllocateResponse.cid": - x.Cid = "" - case "vault.v1.QueryAllocateResponse.macaroon": - x.Macaroon = "" - case "vault.v1.QueryAllocateResponse.public_uri": - x.PublicUri = "" - case "vault.v1.QueryAllocateResponse.expiry_block": - x.ExpiryBlock = int64(0) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QueryAllocateResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.QueryAllocateResponse.success": - value := x.Success - return protoreflect.ValueOfBool(value) - case "vault.v1.QueryAllocateResponse.cid": - value := x.Cid - return protoreflect.ValueOfString(value) - case "vault.v1.QueryAllocateResponse.macaroon": - value := x.Macaroon - return protoreflect.ValueOfString(value) - case "vault.v1.QueryAllocateResponse.public_uri": - value := x.PublicUri - return protoreflect.ValueOfString(value) - case "vault.v1.QueryAllocateResponse.expiry_block": - value := x.ExpiryBlock - return protoreflect.ValueOfInt64(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryAllocateResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.QueryAllocateResponse.success": - x.Success = value.Bool() - case "vault.v1.QueryAllocateResponse.cid": - x.Cid = value.Interface().(string) - case "vault.v1.QueryAllocateResponse.macaroon": - x.Macaroon = value.Interface().(string) - case "vault.v1.QueryAllocateResponse.public_uri": - x.PublicUri = value.Interface().(string) - case "vault.v1.QueryAllocateResponse.expiry_block": - x.ExpiryBlock = value.Int() - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryAllocateResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QueryAllocateResponse.success": - panic(fmt.Errorf("field success of message vault.v1.QueryAllocateResponse is not mutable")) - case "vault.v1.QueryAllocateResponse.cid": - panic(fmt.Errorf("field cid of message vault.v1.QueryAllocateResponse is not mutable")) - case "vault.v1.QueryAllocateResponse.macaroon": - panic(fmt.Errorf("field macaroon of message vault.v1.QueryAllocateResponse is not mutable")) - case "vault.v1.QueryAllocateResponse.public_uri": - panic(fmt.Errorf("field public_uri of message vault.v1.QueryAllocateResponse is not mutable")) - case "vault.v1.QueryAllocateResponse.expiry_block": - panic(fmt.Errorf("field expiry_block of message vault.v1.QueryAllocateResponse is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QueryAllocateResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QueryAllocateResponse.success": - return protoreflect.ValueOfBool(false) - case "vault.v1.QueryAllocateResponse.cid": - return protoreflect.ValueOfString("") - case "vault.v1.QueryAllocateResponse.macaroon": - return protoreflect.ValueOfString("") - case "vault.v1.QueryAllocateResponse.public_uri": - return protoreflect.ValueOfString("") - case "vault.v1.QueryAllocateResponse.expiry_block": - return protoreflect.ValueOfInt64(int64(0)) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QueryAllocateResponse")) - } - panic(fmt.Errorf("message vault.v1.QueryAllocateResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QueryAllocateResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.QueryAllocateResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QueryAllocateResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QueryAllocateResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QueryAllocateResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QueryAllocateResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QueryAllocateResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Success { - n += 2 - } - l = len(x.Cid) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Macaroon) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.PublicUri) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.ExpiryBlock != 0 { - n += 1 + runtime.Sov(uint64(x.ExpiryBlock)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QueryAllocateResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.ExpiryBlock != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryBlock)) - i-- - dAtA[i] = 0x28 - } - if len(x.PublicUri) > 0 { - i -= len(x.PublicUri) - copy(dAtA[i:], x.PublicUri) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicUri))) - i-- - dAtA[i] = 0x22 - } - if len(x.Macaroon) > 0 { - i -= len(x.Macaroon) - copy(dAtA[i:], x.Macaroon) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Macaroon))) - i-- - dAtA[i] = 0x1a - } - if len(x.Cid) > 0 { - i -= len(x.Cid) - copy(dAtA[i:], x.Cid) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Cid))) - i-- - dAtA[i] = 0x12 - } - if x.Success { - i-- - if x.Success { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QueryAllocateResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllocateResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllocateResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - x.Success = bool(v != 0) - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Cid", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Cid = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Macaroon", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Macaroon = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicUri", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.PublicUri = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryBlock", wireType) - } - x.ExpiryBlock = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.ExpiryBlock |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_QuerySyncRequest protoreflect.MessageDescriptor - fd_QuerySyncRequest_did protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_query_proto_init() - md_QuerySyncRequest = File_vault_v1_query_proto.Messages().ByName("QuerySyncRequest") - fd_QuerySyncRequest_did = md_QuerySyncRequest.Fields().ByName("did") -} - -var _ protoreflect.Message = (*fastReflection_QuerySyncRequest)(nil) - -type fastReflection_QuerySyncRequest QuerySyncRequest - -func (x *QuerySyncRequest) ProtoReflect() protoreflect.Message { - return (*fastReflection_QuerySyncRequest)(x) -} - -func (x *QuerySyncRequest) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_query_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QuerySyncRequest_messageType fastReflection_QuerySyncRequest_messageType -var _ protoreflect.MessageType = fastReflection_QuerySyncRequest_messageType{} - -type fastReflection_QuerySyncRequest_messageType struct{} - -func (x fastReflection_QuerySyncRequest_messageType) Zero() protoreflect.Message { - return (*fastReflection_QuerySyncRequest)(nil) -} -func (x fastReflection_QuerySyncRequest_messageType) New() protoreflect.Message { - return new(fastReflection_QuerySyncRequest) -} -func (x fastReflection_QuerySyncRequest_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QuerySyncRequest -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QuerySyncRequest) Descriptor() protoreflect.MessageDescriptor { - return md_QuerySyncRequest -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QuerySyncRequest) Type() protoreflect.MessageType { - return _fastReflection_QuerySyncRequest_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QuerySyncRequest) New() protoreflect.Message { - return new(fastReflection_QuerySyncRequest) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QuerySyncRequest) Interface() protoreflect.ProtoMessage { - return (*QuerySyncRequest)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QuerySyncRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Did != "" { - value := protoreflect.ValueOfString(x.Did) - if !f(fd_QuerySyncRequest_did, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QuerySyncRequest) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.QuerySyncRequest.did": - return x.Did != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncRequest does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySyncRequest) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.QuerySyncRequest.did": - x.Did = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncRequest does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QuerySyncRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.QuerySyncRequest.did": - value := x.Did - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncRequest does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySyncRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.QuerySyncRequest.did": - x.Did = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncRequest does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySyncRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QuerySyncRequest.did": - panic(fmt.Errorf("field did of message vault.v1.QuerySyncRequest is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncRequest does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QuerySyncRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QuerySyncRequest.did": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncRequest")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncRequest does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QuerySyncRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.QuerySyncRequest", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QuerySyncRequest) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySyncRequest) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QuerySyncRequest) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QuerySyncRequest) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QuerySyncRequest) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Did) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QuerySyncRequest) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Did) > 0 { - i -= len(x.Did) - copy(dAtA[i:], x.Did) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Did))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QuerySyncRequest) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySyncRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySyncRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Did", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Did = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_QuerySyncResponse protoreflect.MessageDescriptor - fd_QuerySyncResponse_success protoreflect.FieldDescriptor - fd_QuerySyncResponse_schema protoreflect.FieldDescriptor - fd_QuerySyncResponse_address protoreflect.FieldDescriptor - fd_QuerySyncResponse_chainID protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_query_proto_init() - md_QuerySyncResponse = File_vault_v1_query_proto.Messages().ByName("QuerySyncResponse") - fd_QuerySyncResponse_success = md_QuerySyncResponse.Fields().ByName("success") - fd_QuerySyncResponse_schema = md_QuerySyncResponse.Fields().ByName("schema") - fd_QuerySyncResponse_address = md_QuerySyncResponse.Fields().ByName("address") - fd_QuerySyncResponse_chainID = md_QuerySyncResponse.Fields().ByName("chainID") -} - -var _ protoreflect.Message = (*fastReflection_QuerySyncResponse)(nil) - -type fastReflection_QuerySyncResponse QuerySyncResponse - -func (x *QuerySyncResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_QuerySyncResponse)(x) -} - -func (x *QuerySyncResponse) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_query_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_QuerySyncResponse_messageType fastReflection_QuerySyncResponse_messageType -var _ protoreflect.MessageType = fastReflection_QuerySyncResponse_messageType{} - -type fastReflection_QuerySyncResponse_messageType struct{} - -func (x fastReflection_QuerySyncResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_QuerySyncResponse)(nil) -} -func (x fastReflection_QuerySyncResponse_messageType) New() protoreflect.Message { - return new(fastReflection_QuerySyncResponse) -} -func (x fastReflection_QuerySyncResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_QuerySyncResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_QuerySyncResponse) Descriptor() protoreflect.MessageDescriptor { - return md_QuerySyncResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_QuerySyncResponse) Type() protoreflect.MessageType { - return _fastReflection_QuerySyncResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_QuerySyncResponse) New() protoreflect.Message { - return new(fastReflection_QuerySyncResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_QuerySyncResponse) Interface() protoreflect.ProtoMessage { - return (*QuerySyncResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_QuerySyncResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Success != false { - value := protoreflect.ValueOfBool(x.Success) - if !f(fd_QuerySyncResponse_success, value) { - return - } - } - if x.Schema != nil { - value := protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) - if !f(fd_QuerySyncResponse_schema, value) { - return - } - } - if x.Address != "" { - value := protoreflect.ValueOfString(x.Address) - if !f(fd_QuerySyncResponse_address, value) { - return - } - } - if x.ChainID != "" { - value := protoreflect.ValueOfString(x.ChainID) - if !f(fd_QuerySyncResponse_chainID, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_QuerySyncResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.QuerySyncResponse.success": - return x.Success != false - case "vault.v1.QuerySyncResponse.schema": - return x.Schema != nil - case "vault.v1.QuerySyncResponse.address": - return x.Address != "" - case "vault.v1.QuerySyncResponse.chainID": - return x.ChainID != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySyncResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.QuerySyncResponse.success": - x.Success = false - case "vault.v1.QuerySyncResponse.schema": - x.Schema = nil - case "vault.v1.QuerySyncResponse.address": - x.Address = "" - case "vault.v1.QuerySyncResponse.chainID": - x.ChainID = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_QuerySyncResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.QuerySyncResponse.success": - value := x.Success - return protoreflect.ValueOfBool(value) - case "vault.v1.QuerySyncResponse.schema": - value := x.Schema - return protoreflect.ValueOfMessage(value.ProtoReflect()) - case "vault.v1.QuerySyncResponse.address": - value := x.Address - return protoreflect.ValueOfString(value) - case "vault.v1.QuerySyncResponse.chainID": - value := x.ChainID - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySyncResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.QuerySyncResponse.success": - x.Success = value.Bool() - case "vault.v1.QuerySyncResponse.schema": - x.Schema = value.Message().Interface().(*Schema) - case "vault.v1.QuerySyncResponse.address": - x.Address = value.Interface().(string) - case "vault.v1.QuerySyncResponse.chainID": - x.ChainID = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySyncResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QuerySyncResponse.schema": - if x.Schema == nil { - x.Schema = new(Schema) - } - return protoreflect.ValueOfMessage(x.Schema.ProtoReflect()) - case "vault.v1.QuerySyncResponse.success": - panic(fmt.Errorf("field success of message vault.v1.QuerySyncResponse is not mutable")) - case "vault.v1.QuerySyncResponse.address": - panic(fmt.Errorf("field address of message vault.v1.QuerySyncResponse is not mutable")) - case "vault.v1.QuerySyncResponse.chainID": - panic(fmt.Errorf("field chainID of message vault.v1.QuerySyncResponse is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_QuerySyncResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.QuerySyncResponse.success": - return protoreflect.ValueOfBool(false) - case "vault.v1.QuerySyncResponse.schema": - m := new(Schema) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - case "vault.v1.QuerySyncResponse.address": - return protoreflect.ValueOfString("") - case "vault.v1.QuerySyncResponse.chainID": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.QuerySyncResponse")) - } - panic(fmt.Errorf("message vault.v1.QuerySyncResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_QuerySyncResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.QuerySyncResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_QuerySyncResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_QuerySyncResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_QuerySyncResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_QuerySyncResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*QuerySyncResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Success { - n += 2 - } - if x.Schema != nil { - l = options.Size(x.Schema) - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Address) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.ChainID) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*QuerySyncResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.ChainID) > 0 { - i -= len(x.ChainID) - copy(dAtA[i:], x.ChainID) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ChainID))) - i-- - dAtA[i] = 0x22 - } - if len(x.Address) > 0 { - i -= len(x.Address) - copy(dAtA[i:], x.Address) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Address))) - i-- - dAtA[i] = 0x1a - } - if x.Schema != nil { - encoded, err := options.Marshal(x.Schema) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x12 - } - if x.Success { - i-- - if x.Success { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*QuerySyncResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySyncResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QuerySyncResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - x.Success = bool(v != 0) - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Schema", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Schema == nil { - x.Schema = &Schema{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Schema); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Address = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ChainID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.ChainID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: vault/v1/query.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// QueryParamsRequest is the request type for the Query/Params RPC method. -type QueryParamsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *QueryParamsRequest) Reset() { - *x = QueryParamsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_query_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QueryParamsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryParamsRequest) ProtoMessage() {} - -// Deprecated: Use QueryParamsRequest.ProtoReflect.Descriptor instead. -func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return file_vault_v1_query_proto_rawDescGZIP(), []int{0} -} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -type QueryParamsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // params defines the parameters of the module. - Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` -} - -func (x *QueryParamsResponse) Reset() { - *x = QueryParamsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_query_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QueryParamsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryParamsResponse) ProtoMessage() {} - -// Deprecated: Use QueryParamsResponse.ProtoReflect.Descriptor instead. -func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return file_vault_v1_query_proto_rawDescGZIP(), []int{1} -} - -func (x *QueryParamsResponse) GetParams() *Params { - if x != nil { - return x.Params - } - return nil -} - -// QuerySchemaRequest is the request type for the Query/Schema RPC method. -type QuerySchemaRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *QuerySchemaRequest) Reset() { - *x = QuerySchemaRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_query_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QuerySchemaRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QuerySchemaRequest) ProtoMessage() {} - -// Deprecated: Use QuerySchemaRequest.ProtoReflect.Descriptor instead. -func (*QuerySchemaRequest) Descriptor() ([]byte, []int) { - return file_vault_v1_query_proto_rawDescGZIP(), []int{2} -} - -// QuerySchemaResponse is the response type for the Query/Schema RPC method. -type QuerySchemaResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Schema is the DID document. - Schema *Schema `protobuf:"bytes,1,opt,name=schema,proto3" json:"schema,omitempty"` -} - -func (x *QuerySchemaResponse) Reset() { - *x = QuerySchemaResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_query_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QuerySchemaResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QuerySchemaResponse) ProtoMessage() {} - -// Deprecated: Use QuerySchemaResponse.ProtoReflect.Descriptor instead. -func (*QuerySchemaResponse) Descriptor() ([]byte, []int) { - return file_vault_v1_query_proto_rawDescGZIP(), []int{3} -} - -func (x *QuerySchemaResponse) GetSchema() *Schema { - if x != nil { - return x.Schema - } - return nil -} - -// QueryAllocateRequest is the request type for the Allocate RPC method. -type QueryAllocateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *QueryAllocateRequest) Reset() { - *x = QueryAllocateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_query_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QueryAllocateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryAllocateRequest) ProtoMessage() {} - -// Deprecated: Use QueryAllocateRequest.ProtoReflect.Descriptor instead. -func (*QueryAllocateRequest) Descriptor() ([]byte, []int) { - return file_vault_v1_query_proto_rawDescGZIP(), []int{4} -} - -// AllocateResponse is the response type for the Allocate RPC method. -type QueryAllocateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - Cid string `protobuf:"bytes,2,opt,name=cid,proto3" json:"cid,omitempty"` - Macaroon string `protobuf:"bytes,3,opt,name=macaroon,proto3" json:"macaroon,omitempty"` - PublicUri string `protobuf:"bytes,4,opt,name=public_uri,json=publicUri,proto3" json:"public_uri,omitempty"` - ExpiryBlock int64 `protobuf:"varint,5,opt,name=expiry_block,json=expiryBlock,proto3" json:"expiry_block,omitempty"` -} - -func (x *QueryAllocateResponse) Reset() { - *x = QueryAllocateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_query_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QueryAllocateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryAllocateResponse) ProtoMessage() {} - -// Deprecated: Use QueryAllocateResponse.ProtoReflect.Descriptor instead. -func (*QueryAllocateResponse) Descriptor() ([]byte, []int) { - return file_vault_v1_query_proto_rawDescGZIP(), []int{5} -} - -func (x *QueryAllocateResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *QueryAllocateResponse) GetCid() string { - if x != nil { - return x.Cid - } - return "" -} - -func (x *QueryAllocateResponse) GetMacaroon() string { - if x != nil { - return x.Macaroon - } - return "" -} - -func (x *QueryAllocateResponse) GetPublicUri() string { - if x != nil { - return x.PublicUri - } - return "" -} - -func (x *QueryAllocateResponse) GetExpiryBlock() int64 { - if x != nil { - return x.ExpiryBlock - } - return 0 -} - -// SyncRequest is the request type for the Sync RPC method. -type QuerySyncRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Did string `protobuf:"bytes,1,opt,name=did,proto3" json:"did,omitempty"` -} - -func (x *QuerySyncRequest) Reset() { - *x = QuerySyncRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_query_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QuerySyncRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QuerySyncRequest) ProtoMessage() {} - -// Deprecated: Use QuerySyncRequest.ProtoReflect.Descriptor instead. -func (*QuerySyncRequest) Descriptor() ([]byte, []int) { - return file_vault_v1_query_proto_rawDescGZIP(), []int{6} -} - -func (x *QuerySyncRequest) GetDid() string { - if x != nil { - return x.Did - } - return "" -} - -// SyncResponse is the response type for the Sync RPC method. -type QuerySyncResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - // Schema is the DID document. - Schema *Schema `protobuf:"bytes,2,opt,name=schema,proto3" json:"schema,omitempty"` - // Address is the address of the calling DID. - Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` - // ChainID is the chain ID of the current network. - ChainID string `protobuf:"bytes,4,opt,name=chainID,proto3" json:"chainID,omitempty"` -} - -func (x *QuerySyncResponse) Reset() { - *x = QuerySyncResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_query_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QuerySyncResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QuerySyncResponse) ProtoMessage() {} - -// Deprecated: Use QuerySyncResponse.ProtoReflect.Descriptor instead. -func (*QuerySyncResponse) Descriptor() ([]byte, []int) { - return file_vault_v1_query_proto_rawDescGZIP(), []int{7} -} - -func (x *QuerySyncResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *QuerySyncResponse) GetSchema() *Schema { - if x != nil { - return x.Schema - } - return nil -} - -func (x *QuerySyncResponse) GetAddress() string { - if x != nil { - return x.Address - } - return "" -} - -func (x *QuerySyncResponse) GetChainID() string { - if x != nil { - return x.ChainID - } - return "" -} - -var File_vault_v1_query_proto protoreflect.FileDescriptor - -var file_vault_v1_query_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, - 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, - 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x14, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3f, 0x0a, 0x13, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x14, 0x0a, - 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x3f, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x61, 0x75, - 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x22, 0x16, 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, - 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, - 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x12, 0x1d, - 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x55, 0x72, 0x69, 0x12, 0x21, 0x0a, - 0x0c, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x22, 0x24, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x22, 0x8b, 0x01, 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x44, 0x32, 0x8b, 0x03, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x5f, - 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1c, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, - 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, - 0x5f, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1c, 0x2e, 0x76, 0x61, 0x75, 0x6c, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, - 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x12, 0x67, 0x0a, 0x08, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x2e, 0x76, - 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x76, - 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, - 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x04, 0x53, 0x79, 0x6e, - 0x63, 0x12, 0x1a, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, - 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x79, - 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x79, - 0x6e, 0x63, 0x42, 0x88, 0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, - 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, - 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x61, - 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x76, 0x31, 0xa2, 0x02, - 0x03, 0x56, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x56, 0x31, 0xca, - 0x02, 0x08, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14, 0x56, 0x61, 0x75, - 0x6c, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x09, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_vault_v1_query_proto_rawDescOnce sync.Once - file_vault_v1_query_proto_rawDescData = file_vault_v1_query_proto_rawDesc -) - -func file_vault_v1_query_proto_rawDescGZIP() []byte { - file_vault_v1_query_proto_rawDescOnce.Do(func() { - file_vault_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_vault_v1_query_proto_rawDescData) - }) - return file_vault_v1_query_proto_rawDescData -} - -var file_vault_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_vault_v1_query_proto_goTypes = []interface{}{ - (*QueryParamsRequest)(nil), // 0: vault.v1.QueryParamsRequest - (*QueryParamsResponse)(nil), // 1: vault.v1.QueryParamsResponse - (*QuerySchemaRequest)(nil), // 2: vault.v1.QuerySchemaRequest - (*QuerySchemaResponse)(nil), // 3: vault.v1.QuerySchemaResponse - (*QueryAllocateRequest)(nil), // 4: vault.v1.QueryAllocateRequest - (*QueryAllocateResponse)(nil), // 5: vault.v1.QueryAllocateResponse - (*QuerySyncRequest)(nil), // 6: vault.v1.QuerySyncRequest - (*QuerySyncResponse)(nil), // 7: vault.v1.QuerySyncResponse - (*Params)(nil), // 8: vault.v1.Params - (*Schema)(nil), // 9: vault.v1.Schema -} -var file_vault_v1_query_proto_depIdxs = []int32{ - 8, // 0: vault.v1.QueryParamsResponse.params:type_name -> vault.v1.Params - 9, // 1: vault.v1.QuerySchemaResponse.schema:type_name -> vault.v1.Schema - 9, // 2: vault.v1.QuerySyncResponse.schema:type_name -> vault.v1.Schema - 0, // 3: vault.v1.Query.Params:input_type -> vault.v1.QueryParamsRequest - 2, // 4: vault.v1.Query.Schema:input_type -> vault.v1.QuerySchemaRequest - 4, // 5: vault.v1.Query.Allocate:input_type -> vault.v1.QueryAllocateRequest - 6, // 6: vault.v1.Query.Sync:input_type -> vault.v1.QuerySyncRequest - 1, // 7: vault.v1.Query.Params:output_type -> vault.v1.QueryParamsResponse - 3, // 8: vault.v1.Query.Schema:output_type -> vault.v1.QuerySchemaResponse - 5, // 9: vault.v1.Query.Allocate:output_type -> vault.v1.QueryAllocateResponse - 7, // 10: vault.v1.Query.Sync:output_type -> vault.v1.QuerySyncResponse - 7, // [7:11] is the sub-list for method output_type - 3, // [3:7] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_vault_v1_query_proto_init() } -func file_vault_v1_query_proto_init() { - if File_vault_v1_query_proto != nil { - return - } - file_vault_v1_genesis_proto_init() - if !protoimpl.UnsafeEnabled { - file_vault_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryParamsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryParamsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QuerySchemaRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QuerySchemaResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryAllocateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryAllocateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_query_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QuerySyncRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_query_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QuerySyncResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_vault_v1_query_proto_rawDesc, - NumEnums: 0, - NumMessages: 8, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_vault_v1_query_proto_goTypes, - DependencyIndexes: file_vault_v1_query_proto_depIdxs, - MessageInfos: file_vault_v1_query_proto_msgTypes, - }.Build() - File_vault_v1_query_proto = out.File - file_vault_v1_query_proto_rawDesc = nil - file_vault_v1_query_proto_goTypes = nil - file_vault_v1_query_proto_depIdxs = nil -} diff --git a/api/vault/v1/query_grpc.pb.go b/api/vault/v1/query_grpc.pb.go deleted file mode 100644 index 1730f75cf..000000000 --- a/api/vault/v1/query_grpc.pb.go +++ /dev/null @@ -1,253 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc (unknown) -// source: vault/v1/query.proto - -package vaultv1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - Query_Params_FullMethodName = "/vault.v1.Query/Params" - Query_Schema_FullMethodName = "/vault.v1.Query/Schema" - Query_Allocate_FullMethodName = "/vault.v1.Query/Allocate" - Query_Sync_FullMethodName = "/vault.v1.Query/Sync" -) - -// QueryClient is the client API for Query service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -// -// Query provides defines the gRPC querier service. -type QueryClient interface { - // Params queries all parameters of the module. - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) - // Schema queries the DID document by its id. And returns the required PKL - // information - Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error) - // Allocate initializes a Target Vault available for claims with a compatible - // Authentication mechanism. The default authentication mechanism is WebAuthn. - Allocate(ctx context.Context, in *QueryAllocateRequest, opts ...grpc.CallOption) (*QueryAllocateResponse, error) - // Sync queries the DID document by its id. And returns the required PKL - // information - Sync(ctx context.Context, in *QuerySyncRequest, opts ...grpc.CallOption) (*QuerySyncResponse, error) -} - -type queryClient struct { - cc grpc.ClientConnInterface -} - -func NewQueryClient(cc grpc.ClientConnInterface) QueryClient { - return &queryClient{cc} -} - -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, Query_Params_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *queryClient) Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QuerySchemaResponse) - err := c.cc.Invoke(ctx, Query_Schema_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *queryClient) Allocate(ctx context.Context, in *QueryAllocateRequest, opts ...grpc.CallOption) (*QueryAllocateResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryAllocateResponse) - err := c.cc.Invoke(ctx, Query_Allocate_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *queryClient) Sync(ctx context.Context, in *QuerySyncRequest, opts ...grpc.CallOption) (*QuerySyncResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QuerySyncResponse) - err := c.cc.Invoke(ctx, Query_Sync_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -// QueryServer is the server API for Query service. -// All implementations must embed UnimplementedQueryServer -// for forward compatibility. -// -// Query provides defines the gRPC querier service. -type QueryServer interface { - // Params queries all parameters of the module. - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) - // Schema queries the DID document by its id. And returns the required PKL - // information - Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) - // Allocate initializes a Target Vault available for claims with a compatible - // Authentication mechanism. The default authentication mechanism is WebAuthn. - Allocate(context.Context, *QueryAllocateRequest) (*QueryAllocateResponse, error) - // Sync queries the DID document by its id. And returns the required PKL - // information - Sync(context.Context, *QuerySyncRequest) (*QuerySyncResponse, error) - mustEmbedUnimplementedQueryServer() -} - -// UnimplementedQueryServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedQueryServer struct{} - -func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") -} -func (UnimplementedQueryServer) Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Schema not implemented") -} -func (UnimplementedQueryServer) Allocate(context.Context, *QueryAllocateRequest) (*QueryAllocateResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Allocate not implemented") -} -func (UnimplementedQueryServer) Sync(context.Context, *QuerySyncRequest) (*QuerySyncResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Sync not implemented") -} -func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {} -func (UnimplementedQueryServer) testEmbeddedByValue() {} - -// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to QueryServer will -// result in compilation errors. -type UnsafeQueryServer interface { - mustEmbedUnimplementedQueryServer() -} - -func RegisterQueryServer(s grpc.ServiceRegistrar, srv QueryServer) { - // If the following call pancis, it indicates UnimplementedQueryServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&Query_ServiceDesc, srv) -} - -func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryParamsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Params(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Query_Params_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Query_Schema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QuerySchemaRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Schema(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Query_Schema_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Schema(ctx, req.(*QuerySchemaRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Query_Allocate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryAllocateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Allocate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Query_Allocate_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Allocate(ctx, req.(*QueryAllocateRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Query_Sync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QuerySyncRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Sync(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Query_Sync_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Sync(ctx, req.(*QuerySyncRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// Query_ServiceDesc is the grpc.ServiceDesc for Query service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Query_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "vault.v1.Query", - HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Params", - Handler: _Query_Params_Handler, - }, - { - MethodName: "Schema", - Handler: _Query_Schema_Handler, - }, - { - MethodName: "Allocate", - Handler: _Query_Allocate_Handler, - }, - { - MethodName: "Sync", - Handler: _Query_Sync_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "vault/v1/query.proto", -} diff --git a/api/vault/v1/state.cosmos_orm.go b/api/vault/v1/state.cosmos_orm.go deleted file mode 100644 index c4d222026..000000000 --- a/api/vault/v1/state.cosmos_orm.go +++ /dev/null @@ -1,235 +0,0 @@ -// Code generated by protoc-gen-go-cosmos-orm. DO NOT EDIT. - -package vaultv1 - -import ( - context "context" - ormlist "cosmossdk.io/orm/model/ormlist" - ormtable "cosmossdk.io/orm/model/ormtable" - ormerrors "cosmossdk.io/orm/types/ormerrors" -) - -type DWNTable interface { - Insert(ctx context.Context, dWN *DWN) error - InsertReturningId(ctx context.Context, dWN *DWN) (uint64, error) - LastInsertedSequence(ctx context.Context) (uint64, error) - Update(ctx context.Context, dWN *DWN) error - Save(ctx context.Context, dWN *DWN) error - Delete(ctx context.Context, dWN *DWN) error - Has(ctx context.Context, id uint64) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, id uint64) (*DWN, error) - HasByAlias(ctx context.Context, alias string) (found bool, err error) - // GetByAlias returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByAlias(ctx context.Context, alias string) (*DWN, error) - HasByCid(ctx context.Context, cid string) (found bool, err error) - // GetByCid returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - GetByCid(ctx context.Context, cid string) (*DWN, error) - List(ctx context.Context, prefixKey DWNIndexKey, opts ...ormlist.Option) (DWNIterator, error) - ListRange(ctx context.Context, from, to DWNIndexKey, opts ...ormlist.Option) (DWNIterator, error) - DeleteBy(ctx context.Context, prefixKey DWNIndexKey) error - DeleteRange(ctx context.Context, from, to DWNIndexKey) error - - doNotImplement() -} - -type DWNIterator struct { - ormtable.Iterator -} - -func (i DWNIterator) Value() (*DWN, error) { - var dWN DWN - err := i.UnmarshalMessage(&dWN) - return &dWN, err -} - -type DWNIndexKey interface { - id() uint32 - values() []interface{} - dWNIndexKey() -} - -// primary key starting index.. -type DWNPrimaryKey = DWNIdIndexKey - -type DWNIdIndexKey struct { - vs []interface{} -} - -func (x DWNIdIndexKey) id() uint32 { return 0 } -func (x DWNIdIndexKey) values() []interface{} { return x.vs } -func (x DWNIdIndexKey) dWNIndexKey() {} - -func (this DWNIdIndexKey) WithId(id uint64) DWNIdIndexKey { - this.vs = []interface{}{id} - return this -} - -type DWNAliasIndexKey struct { - vs []interface{} -} - -func (x DWNAliasIndexKey) id() uint32 { return 1 } -func (x DWNAliasIndexKey) values() []interface{} { return x.vs } -func (x DWNAliasIndexKey) dWNIndexKey() {} - -func (this DWNAliasIndexKey) WithAlias(alias string) DWNAliasIndexKey { - this.vs = []interface{}{alias} - return this -} - -type DWNCidIndexKey struct { - vs []interface{} -} - -func (x DWNCidIndexKey) id() uint32 { return 2 } -func (x DWNCidIndexKey) values() []interface{} { return x.vs } -func (x DWNCidIndexKey) dWNIndexKey() {} - -func (this DWNCidIndexKey) WithCid(cid string) DWNCidIndexKey { - this.vs = []interface{}{cid} - return this -} - -type dWNTable struct { - table ormtable.AutoIncrementTable -} - -func (this dWNTable) Insert(ctx context.Context, dWN *DWN) error { - return this.table.Insert(ctx, dWN) -} - -func (this dWNTable) Update(ctx context.Context, dWN *DWN) error { - return this.table.Update(ctx, dWN) -} - -func (this dWNTable) Save(ctx context.Context, dWN *DWN) error { - return this.table.Save(ctx, dWN) -} - -func (this dWNTable) Delete(ctx context.Context, dWN *DWN) error { - return this.table.Delete(ctx, dWN) -} - -func (this dWNTable) InsertReturningId(ctx context.Context, dWN *DWN) (uint64, error) { - return this.table.InsertReturningPKey(ctx, dWN) -} - -func (this dWNTable) LastInsertedSequence(ctx context.Context) (uint64, error) { - return this.table.LastInsertedSequence(ctx) -} - -func (this dWNTable) Has(ctx context.Context, id uint64) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, id) -} - -func (this dWNTable) Get(ctx context.Context, id uint64) (*DWN, error) { - var dWN DWN - found, err := this.table.PrimaryKey().Get(ctx, &dWN, id) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &dWN, nil -} - -func (this dWNTable) HasByAlias(ctx context.Context, alias string) (found bool, err error) { - return this.table.GetIndexByID(1).(ormtable.UniqueIndex).Has(ctx, - alias, - ) -} - -func (this dWNTable) GetByAlias(ctx context.Context, alias string) (*DWN, error) { - var dWN DWN - found, err := this.table.GetIndexByID(1).(ormtable.UniqueIndex).Get(ctx, &dWN, - alias, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &dWN, nil -} - -func (this dWNTable) HasByCid(ctx context.Context, cid string) (found bool, err error) { - return this.table.GetIndexByID(2).(ormtable.UniqueIndex).Has(ctx, - cid, - ) -} - -func (this dWNTable) GetByCid(ctx context.Context, cid string) (*DWN, error) { - var dWN DWN - found, err := this.table.GetIndexByID(2).(ormtable.UniqueIndex).Get(ctx, &dWN, - cid, - ) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &dWN, nil -} - -func (this dWNTable) List(ctx context.Context, prefixKey DWNIndexKey, opts ...ormlist.Option) (DWNIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return DWNIterator{it}, err -} - -func (this dWNTable) ListRange(ctx context.Context, from, to DWNIndexKey, opts ...ormlist.Option) (DWNIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return DWNIterator{it}, err -} - -func (this dWNTable) DeleteBy(ctx context.Context, prefixKey DWNIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this dWNTable) DeleteRange(ctx context.Context, from, to DWNIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this dWNTable) doNotImplement() {} - -var _ DWNTable = dWNTable{} - -func NewDWNTable(db ormtable.Schema) (DWNTable, error) { - table := db.GetTable(&DWN{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&DWN{}).ProtoReflect().Descriptor().FullName())) - } - return dWNTable{table.(ormtable.AutoIncrementTable)}, nil -} - -type StateStore interface { - DWNTable() DWNTable - - doNotImplement() -} - -type stateStore struct { - dWN DWNTable -} - -func (x stateStore) DWNTable() DWNTable { - return x.dWN -} - -func (stateStore) doNotImplement() {} - -var _ StateStore = stateStore{} - -func NewStateStore(db ormtable.Schema) (StateStore, error) { - dWNTable, err := NewDWNTable(db) - if err != nil { - return nil, err - } - - return stateStore{ - dWNTable, - }, nil -} diff --git a/api/vault/v1/state.pulsar.go b/api/vault/v1/state.pulsar.go deleted file mode 100644 index b72016bc9..000000000 --- a/api/vault/v1/state.pulsar.go +++ /dev/null @@ -1,772 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package vaultv1 - -import ( - _ "cosmossdk.io/api/cosmos/orm/v1" - fmt "fmt" - runtime "github.com/cosmos/cosmos-proto/runtime" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_DWN protoreflect.MessageDescriptor - fd_DWN_id protoreflect.FieldDescriptor - fd_DWN_alias protoreflect.FieldDescriptor - fd_DWN_cid protoreflect.FieldDescriptor - fd_DWN_resolver protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_state_proto_init() - md_DWN = File_vault_v1_state_proto.Messages().ByName("DWN") - fd_DWN_id = md_DWN.Fields().ByName("id") - fd_DWN_alias = md_DWN.Fields().ByName("alias") - fd_DWN_cid = md_DWN.Fields().ByName("cid") - fd_DWN_resolver = md_DWN.Fields().ByName("resolver") -} - -var _ protoreflect.Message = (*fastReflection_DWN)(nil) - -type fastReflection_DWN DWN - -func (x *DWN) ProtoReflect() protoreflect.Message { - return (*fastReflection_DWN)(x) -} - -func (x *DWN) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_state_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_DWN_messageType fastReflection_DWN_messageType -var _ protoreflect.MessageType = fastReflection_DWN_messageType{} - -type fastReflection_DWN_messageType struct{} - -func (x fastReflection_DWN_messageType) Zero() protoreflect.Message { - return (*fastReflection_DWN)(nil) -} -func (x fastReflection_DWN_messageType) New() protoreflect.Message { - return new(fastReflection_DWN) -} -func (x fastReflection_DWN_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_DWN -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_DWN) Descriptor() protoreflect.MessageDescriptor { - return md_DWN -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_DWN) Type() protoreflect.MessageType { - return _fastReflection_DWN_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_DWN) New() protoreflect.Message { - return new(fastReflection_DWN) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_DWN) Interface() protoreflect.ProtoMessage { - return (*DWN)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_DWN) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Id != uint64(0) { - value := protoreflect.ValueOfUint64(x.Id) - if !f(fd_DWN_id, value) { - return - } - } - if x.Alias != "" { - value := protoreflect.ValueOfString(x.Alias) - if !f(fd_DWN_alias, value) { - return - } - } - if x.Cid != "" { - value := protoreflect.ValueOfString(x.Cid) - if !f(fd_DWN_cid, value) { - return - } - } - if x.Resolver != "" { - value := protoreflect.ValueOfString(x.Resolver) - if !f(fd_DWN_resolver, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_DWN) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.DWN.id": - return x.Id != uint64(0) - case "vault.v1.DWN.alias": - return x.Alias != "" - case "vault.v1.DWN.cid": - return x.Cid != "" - case "vault.v1.DWN.resolver": - return x.Resolver != "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.DWN")) - } - panic(fmt.Errorf("message vault.v1.DWN does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_DWN) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.DWN.id": - x.Id = uint64(0) - case "vault.v1.DWN.alias": - x.Alias = "" - case "vault.v1.DWN.cid": - x.Cid = "" - case "vault.v1.DWN.resolver": - x.Resolver = "" - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.DWN")) - } - panic(fmt.Errorf("message vault.v1.DWN does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_DWN) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.DWN.id": - value := x.Id - return protoreflect.ValueOfUint64(value) - case "vault.v1.DWN.alias": - value := x.Alias - return protoreflect.ValueOfString(value) - case "vault.v1.DWN.cid": - value := x.Cid - return protoreflect.ValueOfString(value) - case "vault.v1.DWN.resolver": - value := x.Resolver - return protoreflect.ValueOfString(value) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.DWN")) - } - panic(fmt.Errorf("message vault.v1.DWN does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_DWN) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.DWN.id": - x.Id = value.Uint() - case "vault.v1.DWN.alias": - x.Alias = value.Interface().(string) - case "vault.v1.DWN.cid": - x.Cid = value.Interface().(string) - case "vault.v1.DWN.resolver": - x.Resolver = value.Interface().(string) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.DWN")) - } - panic(fmt.Errorf("message vault.v1.DWN does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_DWN) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.DWN.id": - panic(fmt.Errorf("field id of message vault.v1.DWN is not mutable")) - case "vault.v1.DWN.alias": - panic(fmt.Errorf("field alias of message vault.v1.DWN is not mutable")) - case "vault.v1.DWN.cid": - panic(fmt.Errorf("field cid of message vault.v1.DWN is not mutable")) - case "vault.v1.DWN.resolver": - panic(fmt.Errorf("field resolver of message vault.v1.DWN is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.DWN")) - } - panic(fmt.Errorf("message vault.v1.DWN does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_DWN) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.DWN.id": - return protoreflect.ValueOfUint64(uint64(0)) - case "vault.v1.DWN.alias": - return protoreflect.ValueOfString("") - case "vault.v1.DWN.cid": - return protoreflect.ValueOfString("") - case "vault.v1.DWN.resolver": - return protoreflect.ValueOfString("") - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.DWN")) - } - panic(fmt.Errorf("message vault.v1.DWN does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_DWN) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.DWN", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_DWN) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_DWN) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_DWN) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_DWN) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*DWN) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.Id != 0 { - n += 1 + runtime.Sov(uint64(x.Id)) - } - l = len(x.Alias) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Cid) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - l = len(x.Resolver) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*DWN) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if len(x.Resolver) > 0 { - i -= len(x.Resolver) - copy(dAtA[i:], x.Resolver) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Resolver))) - i-- - dAtA[i] = 0x22 - } - if len(x.Cid) > 0 { - i -= len(x.Cid) - copy(dAtA[i:], x.Cid) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Cid))) - i-- - dAtA[i] = 0x1a - } - if len(x.Alias) > 0 { - i -= len(x.Alias) - copy(dAtA[i:], x.Alias) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Alias))) - i-- - dAtA[i] = 0x12 - } - if x.Id != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Id)) - i-- - dAtA[i] = 0x8 - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*DWN) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: DWN: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: DWN: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - x.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - x.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Alias", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Alias = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Cid", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Cid = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Resolver", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Resolver = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: vault/v1/state.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type DWN struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Alias string `protobuf:"bytes,2,opt,name=alias,proto3" json:"alias,omitempty"` - Cid string `protobuf:"bytes,3,opt,name=cid,proto3" json:"cid,omitempty"` - Resolver string `protobuf:"bytes,4,opt,name=resolver,proto3" json:"resolver,omitempty"` -} - -func (x *DWN) Reset() { - *x = DWN{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_state_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DWN) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DWN) ProtoMessage() {} - -// Deprecated: Use DWN.ProtoReflect.Descriptor instead. -func (*DWN) Descriptor() ([]byte, []int) { - return file_vault_v1_state_proto_rawDescGZIP(), []int{0} -} - -func (x *DWN) GetId() uint64 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *DWN) GetAlias() string { - if x != nil { - return x.Alias - } - return "" -} - -func (x *DWN) GetCid() string { - if x != nil { - return x.Cid - } - return "" -} - -func (x *DWN) GetResolver() string { - if x != nil { - return x.Resolver - } - return "" -} - -var File_vault_v1_state_proto protoreflect.FileDescriptor - -var file_vault_v1_state_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, - 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, - 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x01, 0x0a, 0x03, 0x44, 0x57, - 0x4e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, - 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, - 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x3a, 0x28, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x22, 0x0a, 0x06, 0x0a, - 0x02, 0x69, 0x64, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x10, 0x01, - 0x18, 0x01, 0x12, 0x09, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x10, 0x02, 0x18, 0x01, 0x18, 0x01, 0x42, - 0x88, 0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, - 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, - 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, - 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x56, 0x58, - 0x58, 0xaa, 0x02, 0x08, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x56, - 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, - 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x09, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_vault_v1_state_proto_rawDescOnce sync.Once - file_vault_v1_state_proto_rawDescData = file_vault_v1_state_proto_rawDesc -) - -func file_vault_v1_state_proto_rawDescGZIP() []byte { - file_vault_v1_state_proto_rawDescOnce.Do(func() { - file_vault_v1_state_proto_rawDescData = protoimpl.X.CompressGZIP(file_vault_v1_state_proto_rawDescData) - }) - return file_vault_v1_state_proto_rawDescData -} - -var file_vault_v1_state_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_vault_v1_state_proto_goTypes = []interface{}{ - (*DWN)(nil), // 0: vault.v1.DWN -} -var file_vault_v1_state_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_vault_v1_state_proto_init() } -func file_vault_v1_state_proto_init() { - if File_vault_v1_state_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_vault_v1_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DWN); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_vault_v1_state_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_vault_v1_state_proto_goTypes, - DependencyIndexes: file_vault_v1_state_proto_depIdxs, - MessageInfos: file_vault_v1_state_proto_msgTypes, - }.Build() - File_vault_v1_state_proto = out.File - file_vault_v1_state_proto_rawDesc = nil - file_vault_v1_state_proto_goTypes = nil - file_vault_v1_state_proto_depIdxs = nil -} diff --git a/api/vault/v1/tx.pulsar.go b/api/vault/v1/tx.pulsar.go deleted file mode 100644 index 56a4ef6b0..000000000 --- a/api/vault/v1/tx.pulsar.go +++ /dev/null @@ -1,2066 +0,0 @@ -// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. -package vaultv1 - -import ( - _ "cosmossdk.io/api/cosmos/msg/v1" - fmt "fmt" - _ "github.com/cosmos/cosmos-proto" - runtime "github.com/cosmos/cosmos-proto/runtime" - _ "github.com/cosmos/gogoproto/gogoproto" - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoiface "google.golang.org/protobuf/runtime/protoiface" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - reflect "reflect" - sync "sync" -) - -var ( - md_MsgUpdateParams protoreflect.MessageDescriptor - fd_MsgUpdateParams_authority protoreflect.FieldDescriptor - fd_MsgUpdateParams_params protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_tx_proto_init() - md_MsgUpdateParams = File_vault_v1_tx_proto.Messages().ByName("MsgUpdateParams") - fd_MsgUpdateParams_authority = md_MsgUpdateParams.Fields().ByName("authority") - fd_MsgUpdateParams_params = md_MsgUpdateParams.Fields().ByName("params") -} - -var _ protoreflect.Message = (*fastReflection_MsgUpdateParams)(nil) - -type fastReflection_MsgUpdateParams MsgUpdateParams - -func (x *MsgUpdateParams) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgUpdateParams)(x) -} - -func (x *MsgUpdateParams) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_tx_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_MsgUpdateParams_messageType fastReflection_MsgUpdateParams_messageType -var _ protoreflect.MessageType = fastReflection_MsgUpdateParams_messageType{} - -type fastReflection_MsgUpdateParams_messageType struct{} - -func (x fastReflection_MsgUpdateParams_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgUpdateParams)(nil) -} -func (x fastReflection_MsgUpdateParams_messageType) New() protoreflect.Message { - return new(fastReflection_MsgUpdateParams) -} -func (x fastReflection_MsgUpdateParams_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgUpdateParams -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_MsgUpdateParams) Descriptor() protoreflect.MessageDescriptor { - return md_MsgUpdateParams -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgUpdateParams) Type() protoreflect.MessageType { - return _fastReflection_MsgUpdateParams_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgUpdateParams) New() protoreflect.Message { - return new(fastReflection_MsgUpdateParams) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgUpdateParams) Interface() protoreflect.ProtoMessage { - return (*MsgUpdateParams)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_MsgUpdateParams) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Authority != "" { - value := protoreflect.ValueOfString(x.Authority) - if !f(fd_MsgUpdateParams_authority, value) { - return - } - } - if x.Params != nil { - value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - if !f(fd_MsgUpdateParams_params, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.MsgUpdateParams.authority": - return x.Authority != "" - case "vault.v1.MsgUpdateParams.params": - return x.Params != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.MsgUpdateParams.authority": - x.Authority = "" - case "vault.v1.MsgUpdateParams.params": - x.Params = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgUpdateParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.MsgUpdateParams.authority": - value := x.Authority - return protoreflect.ValueOfString(value) - case "vault.v1.MsgUpdateParams.params": - value := x.Params - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParams does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.MsgUpdateParams.authority": - x.Authority = value.Interface().(string) - case "vault.v1.MsgUpdateParams.params": - x.Params = value.Message().Interface().(*Params) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.MsgUpdateParams.params": - if x.Params == nil { - x.Params = new(Params) - } - return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - case "vault.v1.MsgUpdateParams.authority": - panic(fmt.Errorf("field authority of message vault.v1.MsgUpdateParams is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgUpdateParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.MsgUpdateParams.authority": - return protoreflect.ValueOfString("") - case "vault.v1.MsgUpdateParams.params": - m := new(Params) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParams")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParams does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgUpdateParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.MsgUpdateParams", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgUpdateParams) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParams) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_MsgUpdateParams) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_MsgUpdateParams) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgUpdateParams) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Authority) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.Params != nil { - l = options.Size(x.Params) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgUpdateParams) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Params != nil { - encoded, err := options.Marshal(x.Params) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x12 - } - if len(x.Authority) > 0 { - i -= len(x.Authority) - copy(dAtA[i:], x.Authority) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgUpdateParams) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Authority = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Params == nil { - x.Params = &Params{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_MsgUpdateParamsResponse protoreflect.MessageDescriptor -) - -func init() { - file_vault_v1_tx_proto_init() - md_MsgUpdateParamsResponse = File_vault_v1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") -} - -var _ protoreflect.Message = (*fastReflection_MsgUpdateParamsResponse)(nil) - -type fastReflection_MsgUpdateParamsResponse MsgUpdateParamsResponse - -func (x *MsgUpdateParamsResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgUpdateParamsResponse)(x) -} - -func (x *MsgUpdateParamsResponse) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_tx_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_MsgUpdateParamsResponse_messageType fastReflection_MsgUpdateParamsResponse_messageType -var _ protoreflect.MessageType = fastReflection_MsgUpdateParamsResponse_messageType{} - -type fastReflection_MsgUpdateParamsResponse_messageType struct{} - -func (x fastReflection_MsgUpdateParamsResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgUpdateParamsResponse)(nil) -} -func (x fastReflection_MsgUpdateParamsResponse_messageType) New() protoreflect.Message { - return new(fastReflection_MsgUpdateParamsResponse) -} -func (x fastReflection_MsgUpdateParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgUpdateParamsResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_MsgUpdateParamsResponse) Descriptor() protoreflect.MessageDescriptor { - return md_MsgUpdateParamsResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgUpdateParamsResponse) Type() protoreflect.MessageType { - return _fastReflection_MsgUpdateParamsResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgUpdateParamsResponse) New() protoreflect.Message { - return new(fastReflection_MsgUpdateParamsResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgUpdateParamsResponse) Interface() protoreflect.ProtoMessage { - return (*MsgUpdateParamsResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_MsgUpdateParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgUpdateParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParamsResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgUpdateParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParamsResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgUpdateParamsResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgUpdateParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.MsgUpdateParamsResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgUpdateParamsResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgUpdateParamsResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_MsgUpdateParamsResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgUpdateParamsResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgUpdateParamsResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgUpdateParamsResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_MsgInitialize protoreflect.MessageDescriptor - fd_MsgInitialize_authority protoreflect.FieldDescriptor - fd_MsgInitialize_params protoreflect.FieldDescriptor -) - -func init() { - file_vault_v1_tx_proto_init() - md_MsgInitialize = File_vault_v1_tx_proto.Messages().ByName("MsgInitialize") - fd_MsgInitialize_authority = md_MsgInitialize.Fields().ByName("authority") - fd_MsgInitialize_params = md_MsgInitialize.Fields().ByName("params") -} - -var _ protoreflect.Message = (*fastReflection_MsgInitialize)(nil) - -type fastReflection_MsgInitialize MsgInitialize - -func (x *MsgInitialize) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgInitialize)(x) -} - -func (x *MsgInitialize) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_tx_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_MsgInitialize_messageType fastReflection_MsgInitialize_messageType -var _ protoreflect.MessageType = fastReflection_MsgInitialize_messageType{} - -type fastReflection_MsgInitialize_messageType struct{} - -func (x fastReflection_MsgInitialize_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgInitialize)(nil) -} -func (x fastReflection_MsgInitialize_messageType) New() protoreflect.Message { - return new(fastReflection_MsgInitialize) -} -func (x fastReflection_MsgInitialize_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgInitialize -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_MsgInitialize) Descriptor() protoreflect.MessageDescriptor { - return md_MsgInitialize -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgInitialize) Type() protoreflect.MessageType { - return _fastReflection_MsgInitialize_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgInitialize) New() protoreflect.Message { - return new(fastReflection_MsgInitialize) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgInitialize) Interface() protoreflect.ProtoMessage { - return (*MsgInitialize)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_MsgInitialize) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Authority != "" { - value := protoreflect.ValueOfString(x.Authority) - if !f(fd_MsgInitialize_authority, value) { - return - } - } - if x.Params != nil { - value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - if !f(fd_MsgInitialize_params, value) { - return - } - } -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgInitialize) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - case "vault.v1.MsgInitialize.authority": - return x.Authority != "" - case "vault.v1.MsgInitialize.params": - return x.Params != nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) - } - panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgInitialize) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - case "vault.v1.MsgInitialize.authority": - x.Authority = "" - case "vault.v1.MsgInitialize.params": - x.Params = nil - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) - } - panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgInitialize) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - case "vault.v1.MsgInitialize.authority": - value := x.Authority - return protoreflect.ValueOfString(value) - case "vault.v1.MsgInitialize.params": - value := x.Params - return protoreflect.ValueOfMessage(value.ProtoReflect()) - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) - } - panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgInitialize) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - case "vault.v1.MsgInitialize.authority": - x.Authority = value.Interface().(string) - case "vault.v1.MsgInitialize.params": - x.Params = value.Message().Interface().(*Params) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) - } - panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgInitialize) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.MsgInitialize.params": - if x.Params == nil { - x.Params = new(Params) - } - return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - case "vault.v1.MsgInitialize.authority": - panic(fmt.Errorf("field authority of message vault.v1.MsgInitialize is not mutable")) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) - } - panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgInitialize) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - case "vault.v1.MsgInitialize.authority": - return protoreflect.ValueOfString("") - case "vault.v1.MsgInitialize.params": - m := new(Params) - return protoreflect.ValueOfMessage(m.ProtoReflect()) - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitialize")) - } - panic(fmt.Errorf("message vault.v1.MsgInitialize does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgInitialize) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.MsgInitialize", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgInitialize) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgInitialize) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_MsgInitialize) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_MsgInitialize) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgInitialize) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - l = len(x.Authority) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.Params != nil { - l = options.Size(x.Params) - n += 1 + l + runtime.Sov(uint64(l)) - } - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgInitialize) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if x.Params != nil { - encoded, err := options.Marshal(x.Params) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x12 - } - if len(x.Authority) > 0 { - i -= len(x.Authority) - copy(dAtA[i:], x.Authority) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) - i-- - dAtA[i] = 0xa - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgInitialize) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitialize: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitialize: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Authority = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.Params == nil { - x.Params = &Params{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -var ( - md_MsgInitializeResponse protoreflect.MessageDescriptor -) - -func init() { - file_vault_v1_tx_proto_init() - md_MsgInitializeResponse = File_vault_v1_tx_proto.Messages().ByName("MsgInitializeResponse") -} - -var _ protoreflect.Message = (*fastReflection_MsgInitializeResponse)(nil) - -type fastReflection_MsgInitializeResponse MsgInitializeResponse - -func (x *MsgInitializeResponse) ProtoReflect() protoreflect.Message { - return (*fastReflection_MsgInitializeResponse)(x) -} - -func (x *MsgInitializeResponse) slowProtoReflect() protoreflect.Message { - mi := &file_vault_v1_tx_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -var _fastReflection_MsgInitializeResponse_messageType fastReflection_MsgInitializeResponse_messageType -var _ protoreflect.MessageType = fastReflection_MsgInitializeResponse_messageType{} - -type fastReflection_MsgInitializeResponse_messageType struct{} - -func (x fastReflection_MsgInitializeResponse_messageType) Zero() protoreflect.Message { - return (*fastReflection_MsgInitializeResponse)(nil) -} -func (x fastReflection_MsgInitializeResponse_messageType) New() protoreflect.Message { - return new(fastReflection_MsgInitializeResponse) -} -func (x fastReflection_MsgInitializeResponse_messageType) Descriptor() protoreflect.MessageDescriptor { - return md_MsgInitializeResponse -} - -// Descriptor returns message descriptor, which contains only the protobuf -// type information for the message. -func (x *fastReflection_MsgInitializeResponse) Descriptor() protoreflect.MessageDescriptor { - return md_MsgInitializeResponse -} - -// Type returns the message type, which encapsulates both Go and protobuf -// type information. If the Go type information is not needed, -// it is recommended that the message descriptor be used instead. -func (x *fastReflection_MsgInitializeResponse) Type() protoreflect.MessageType { - return _fastReflection_MsgInitializeResponse_messageType -} - -// New returns a newly allocated and mutable empty message. -func (x *fastReflection_MsgInitializeResponse) New() protoreflect.Message { - return new(fastReflection_MsgInitializeResponse) -} - -// Interface unwraps the message reflection interface and -// returns the underlying ProtoMessage interface. -func (x *fastReflection_MsgInitializeResponse) Interface() protoreflect.ProtoMessage { - return (*MsgInitializeResponse)(x) -} - -// Range iterates over every populated field in an undefined order, -// calling f for each field descriptor and value encountered. -// Range returns immediately if f returns false. -// While iterating, mutating operations may only be performed -// on the current field descriptor. -func (x *fastReflection_MsgInitializeResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { -} - -// Has reports whether a field is populated. -// -// Some fields have the property of nullability where it is possible to -// distinguish between the default value of a field and whether the field -// was explicitly populated with the default value. Singular message fields, -// member fields of a oneof, and proto2 scalar fields are nullable. Such -// fields are populated only if explicitly set. -// -// In other cases (aside from the nullable cases above), -// a proto3 scalar field is populated if it contains a non-zero value, and -// a repeated field is populated if it is non-empty. -func (x *fastReflection_MsgInitializeResponse) Has(fd protoreflect.FieldDescriptor) bool { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) - } -} - -// Clear clears the field such that a subsequent Has call reports false. -// -// Clearing an extension field clears both the extension type and value -// associated with the given field number. -// -// Clear is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgInitializeResponse) Clear(fd protoreflect.FieldDescriptor) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) - } -} - -// Get retrieves the value for a field. -// -// For unpopulated scalars, it returns the default value, where -// the default value of a bytes scalar is guaranteed to be a copy. -// For unpopulated composite types, it returns an empty, read-only view -// of the value; to obtain a mutable reference, use Mutable. -func (x *fastReflection_MsgInitializeResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { - switch descriptor.FullName() { - default: - if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", descriptor.FullName())) - } -} - -// Set stores the value for a field. -// -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType. -// When setting a composite type, it is unspecified whether the stored value -// aliases the source's memory in any way. If the composite value is an -// empty, read-only value, then it panics. -// -// Set is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgInitializeResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) - } -} - -// Mutable returns a mutable reference to a composite type. -// -// If the field is unpopulated, it may allocate a composite value. -// For a field belonging to a oneof, it implicitly clears any other field -// that may be currently set within the same oneof. -// For extension fields, it implicitly stores the provided ExtensionType -// if not already stored. -// It panics if the field does not contain a composite type. -// -// Mutable is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgInitializeResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) - } -} - -// NewField returns a new value that is assignable to the field -// for the given descriptor. For scalars, this returns the default value. -// For lists, maps, and messages, this returns a new, empty, mutable value. -func (x *fastReflection_MsgInitializeResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { - switch fd.FullName() { - default: - if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: vault.v1.MsgInitializeResponse")) - } - panic(fmt.Errorf("message vault.v1.MsgInitializeResponse does not contain field %s", fd.FullName())) - } -} - -// WhichOneof reports which field within the oneof is populated, -// returning nil if none are populated. -// It panics if the oneof descriptor does not belong to this message. -func (x *fastReflection_MsgInitializeResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { - switch d.FullName() { - default: - panic(fmt.Errorf("%s is not a oneof field in vault.v1.MsgInitializeResponse", d.FullName())) - } - panic("unreachable") -} - -// GetUnknown retrieves the entire list of unknown fields. -// The caller may only mutate the contents of the RawFields -// if the mutated bytes are stored back into the message with SetUnknown. -func (x *fastReflection_MsgInitializeResponse) GetUnknown() protoreflect.RawFields { - return x.unknownFields -} - -// SetUnknown stores an entire list of unknown fields. -// The raw fields must be syntactically valid according to the wire format. -// An implementation may panic if this is not the case. -// Once stored, the caller must not mutate the content of the RawFields. -// An empty RawFields may be passed to clear the fields. -// -// SetUnknown is a mutating operation and unsafe for concurrent use. -func (x *fastReflection_MsgInitializeResponse) SetUnknown(fields protoreflect.RawFields) { - x.unknownFields = fields -} - -// IsValid reports whether the message is valid. -// -// An invalid message is an empty, read-only value. -// -// An invalid message often corresponds to a nil pointer of the concrete -// message type, but the details are implementation dependent. -// Validity is not part of the protobuf data model, and may not -// be preserved in marshaling or other operations. -func (x *fastReflection_MsgInitializeResponse) IsValid() bool { - return x != nil -} - -// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. -// This method may return nil. -// -// The returned methods type is identical to -// "google.golang.org/protobuf/runtime/protoiface".Methods. -// Consult the protoiface package documentation for details. -func (x *fastReflection_MsgInitializeResponse) ProtoMethods() *protoiface.Methods { - size := func(input protoiface.SizeInput) protoiface.SizeOutput { - x := input.Message.Interface().(*MsgInitializeResponse) - if x == nil { - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: 0, - } - } - options := runtime.SizeInputToOptions(input) - _ = options - var n int - var l int - _ = l - if x.unknownFields != nil { - n += len(x.unknownFields) - } - return protoiface.SizeOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Size: n, - } - } - - marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*MsgInitializeResponse) - if x == nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - options := runtime.MarshalInputToOptions(input) - _ = options - size := options.Size(x) - dAtA := make([]byte, size) - i := len(dAtA) - _ = i - var l int - _ = l - if x.unknownFields != nil { - i -= len(x.unknownFields) - copy(dAtA[i:], x.unknownFields) - } - if input.Buf != nil { - input.Buf = append(input.Buf, dAtA...) - } else { - input.Buf = dAtA - } - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, nil - } - unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*MsgInitializeResponse) - if x == nil { - return protoiface.UnmarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Flags: input.Flags, - }, nil - } - options := runtime.UnmarshalInputToOptions(input) - _ = options - dAtA := input.Buf - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitializeResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgInitializeResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := runtime.Skip(dAtA[iNdEx:]) - if err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if (iNdEx + skippy) > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if !options.DiscardUnknown { - x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - } - iNdEx += skippy - } - } - - if iNdEx > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil - } - return &protoiface.Methods{ - NoUnkeyedLiterals: struct{}{}, - Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, - Size: size, - Marshal: marshal, - Unmarshal: unmarshal, - Merge: nil, - CheckInitialized: nil, - } -} - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.0 -// protoc (unknown) -// source: vault/v1/tx.proto - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// MsgUpdateParams is the Msg/UpdateParams request type. -// -// Since: cosmos-sdk 0.47 -type MsgUpdateParams struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // authority is the address of the governance account. - Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` - // params defines the parameters to update. - // - // NOTE: All parameters must be supplied. - Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` -} - -func (x *MsgUpdateParams) Reset() { - *x = MsgUpdateParams{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_tx_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MsgUpdateParams) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MsgUpdateParams) ProtoMessage() {} - -// Deprecated: Use MsgUpdateParams.ProtoReflect.Descriptor instead. -func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return file_vault_v1_tx_proto_rawDescGZIP(), []int{0} -} - -func (x *MsgUpdateParams) GetAuthority() string { - if x != nil { - return x.Authority - } - return "" -} - -func (x *MsgUpdateParams) GetParams() *Params { - if x != nil { - return x.Params - } - return nil -} - -// MsgUpdateParamsResponse defines the response structure for executing a -// MsgUpdateParams message. -// -// Since: cosmos-sdk 0.47 -type MsgUpdateParamsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *MsgUpdateParamsResponse) Reset() { - *x = MsgUpdateParamsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_tx_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MsgUpdateParamsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MsgUpdateParamsResponse) ProtoMessage() {} - -// Deprecated: Use MsgUpdateParamsResponse.ProtoReflect.Descriptor instead. -func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return file_vault_v1_tx_proto_rawDescGZIP(), []int{1} -} - -// MsgInitialize spawns a New Vault with Unclaimed State. This is a one-time -// operation that must be performed interacting with the Vault. -// -// Since: cosmos-sdk 0.47 -type MsgInitialize struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // authority is the address of the governance account. - Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` - // params defines the parameters to update. - // - // NOTE: All parameters must be supplied. - Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` -} - -func (x *MsgInitialize) Reset() { - *x = MsgInitialize{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_tx_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MsgInitialize) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MsgInitialize) ProtoMessage() {} - -// Deprecated: Use MsgInitialize.ProtoReflect.Descriptor instead. -func (*MsgInitialize) Descriptor() ([]byte, []int) { - return file_vault_v1_tx_proto_rawDescGZIP(), []int{2} -} - -func (x *MsgInitialize) GetAuthority() string { - if x != nil { - return x.Authority - } - return "" -} - -func (x *MsgInitialize) GetParams() *Params { - if x != nil { - return x.Params - } - return nil -} - -// MsgInitializeResponse defines the response structure for executing a -// MsgInitialize message. -// -// Since: cosmos-sdk 0.47 -type MsgInitializeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *MsgInitializeResponse) Reset() { - *x = MsgInitializeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_vault_v1_tx_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MsgInitializeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MsgInitializeResponse) ProtoMessage() {} - -// Deprecated: Use MsgInitializeResponse.ProtoReflect.Descriptor instead. -func (*MsgInitializeResponse) Descriptor() ([]byte, []int) { - return file_vault_v1_tx_proto_rawDescGZIP(), []int{3} -} - -var File_vault_v1_tx_proto protoreflect.FileDescriptor - -var file_vault_v1_tx_proto_rawDesc = []byte{ - 0x0a, 0x11, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x78, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, - 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x2f, - 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x89, 0x01, - 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, - 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2e, 0x0a, 0x06, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x61, 0x75, 0x6c, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, - 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, - 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, - 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2e, - 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x0e, - 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x17, - 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa2, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, - 0x4c, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, - 0x19, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x21, 0x2e, 0x76, 0x61, 0x75, - 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, - 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x17, 0x2e, 0x76, 0x61, - 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x1a, 0x1f, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x73, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0x85, 0x01, 0x0a, - 0x0c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, - 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x61, - 0x75, 0x6c, 0x74, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x56, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x56, 0x61, - 0x75, 0x6c, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, - 0x31, 0xe2, 0x02, 0x14, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x56, 0x61, 0x75, 0x6c, 0x74, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_vault_v1_tx_proto_rawDescOnce sync.Once - file_vault_v1_tx_proto_rawDescData = file_vault_v1_tx_proto_rawDesc -) - -func file_vault_v1_tx_proto_rawDescGZIP() []byte { - file_vault_v1_tx_proto_rawDescOnce.Do(func() { - file_vault_v1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_vault_v1_tx_proto_rawDescData) - }) - return file_vault_v1_tx_proto_rawDescData -} - -var file_vault_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_vault_v1_tx_proto_goTypes = []interface{}{ - (*MsgUpdateParams)(nil), // 0: vault.v1.MsgUpdateParams - (*MsgUpdateParamsResponse)(nil), // 1: vault.v1.MsgUpdateParamsResponse - (*MsgInitialize)(nil), // 2: vault.v1.MsgInitialize - (*MsgInitializeResponse)(nil), // 3: vault.v1.MsgInitializeResponse - (*Params)(nil), // 4: vault.v1.Params -} -var file_vault_v1_tx_proto_depIdxs = []int32{ - 4, // 0: vault.v1.MsgUpdateParams.params:type_name -> vault.v1.Params - 4, // 1: vault.v1.MsgInitialize.params:type_name -> vault.v1.Params - 0, // 2: vault.v1.Msg.UpdateParams:input_type -> vault.v1.MsgUpdateParams - 2, // 3: vault.v1.Msg.Initialize:input_type -> vault.v1.MsgInitialize - 1, // 4: vault.v1.Msg.UpdateParams:output_type -> vault.v1.MsgUpdateParamsResponse - 3, // 5: vault.v1.Msg.Initialize:output_type -> vault.v1.MsgInitializeResponse - 4, // [4:6] is the sub-list for method output_type - 2, // [2:4] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_vault_v1_tx_proto_init() } -func file_vault_v1_tx_proto_init() { - if File_vault_v1_tx_proto != nil { - return - } - file_vault_v1_genesis_proto_init() - if !protoimpl.UnsafeEnabled { - file_vault_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgUpdateParams); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgUpdateParamsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_tx_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgInitialize); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vault_v1_tx_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MsgInitializeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_vault_v1_tx_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_vault_v1_tx_proto_goTypes, - DependencyIndexes: file_vault_v1_tx_proto_depIdxs, - MessageInfos: file_vault_v1_tx_proto_msgTypes, - }.Build() - File_vault_v1_tx_proto = out.File - file_vault_v1_tx_proto_rawDesc = nil - file_vault_v1_tx_proto_goTypes = nil - file_vault_v1_tx_proto_depIdxs = nil -} diff --git a/api/vault/v1/tx_grpc.pb.go b/api/vault/v1/tx_grpc.pb.go deleted file mode 100644 index 958bd6cd2..000000000 --- a/api/vault/v1/tx_grpc.pb.go +++ /dev/null @@ -1,171 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc (unknown) -// source: vault/v1/tx.proto - -package vaultv1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - Msg_UpdateParams_FullMethodName = "/vault.v1.Msg/UpdateParams" - Msg_Initialize_FullMethodName = "/vault.v1.Msg/Initialize" -) - -// MsgClient is the client API for Msg service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -// -// Msg defines the Msg service. -type MsgClient interface { - // UpdateParams defines a governance operation for updating the parameters. - // - // Since: cosmos-sdk 0.47 - UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) - // Initialize spawns a new Vault - Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error) -} - -type msgClient struct { - cc grpc.ClientConnInterface -} - -func NewMsgClient(cc grpc.ClientConnInterface) MsgClient { - return &msgClient{cc} -} - -func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(MsgUpdateParamsResponse) - err := c.cc.Invoke(ctx, Msg_UpdateParams_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *msgClient) Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(MsgInitializeResponse) - err := c.cc.Invoke(ctx, Msg_Initialize_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -// MsgServer is the server API for Msg service. -// All implementations must embed UnimplementedMsgServer -// for forward compatibility. -// -// Msg defines the Msg service. -type MsgServer interface { - // UpdateParams defines a governance operation for updating the parameters. - // - // Since: cosmos-sdk 0.47 - UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) - // Initialize spawns a new Vault - Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error) - mustEmbedUnimplementedMsgServer() -} - -// UnimplementedMsgServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedMsgServer struct{} - -func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") -} -func (UnimplementedMsgServer) Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Initialize not implemented") -} -func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} -func (UnimplementedMsgServer) testEmbeddedByValue() {} - -// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to MsgServer will -// result in compilation errors. -type UnsafeMsgServer interface { - mustEmbedUnimplementedMsgServer() -} - -func RegisterMsgServer(s grpc.ServiceRegistrar, srv MsgServer) { - // If the following call pancis, it indicates UnimplementedMsgServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&Msg_ServiceDesc, srv) -} - -func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgUpdateParams) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).UpdateParams(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Msg_UpdateParams_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) - } - return interceptor(ctx, in, info, handler) -} - -func _Msg_Initialize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgInitialize) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).Initialize(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Msg_Initialize_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).Initialize(ctx, req.(*MsgInitialize)) - } - return interceptor(ctx, in, info, handler) -} - -// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Msg_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "vault.v1.Msg", - HandlerType: (*MsgServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "UpdateParams", - Handler: _Msg_UpdateParams_Handler, - }, - { - MethodName: "Initialize", - Handler: _Msg_Initialize_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "vault/v1/tx.proto", -} diff --git a/pkg/webapp/components/auth/create_credential.templ b/pkg/webapp/components/auth/create_credential.templ deleted file mode 100644 index 65f99c078..000000000 --- a/pkg/webapp/components/auth/create_credential.templ +++ /dev/null @@ -1,49 +0,0 @@ -package auth - -import "github.com/labstack/echo/v4" - -templ RegisterCredentialForm() { -
    -
    -
    -
    -
    -
    -
    -} - -templ NavigatorCredentialsCreate(c echo.Context) { - -} diff --git a/pkg/webapp/components/auth/create_credential_templ.go b/pkg/webapp/components/auth/create_credential_templ.go deleted file mode 100644 index 11f0103ea..000000000 --- a/pkg/webapp/components/auth/create_credential_templ.go +++ /dev/null @@ -1,71 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.793 -package auth - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "github.com/labstack/echo/v4" - -func RegisterCredentialForm() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func NavigatorCredentialsCreate(c echo.Context) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/webapp/components/auth/current.templ b/pkg/webapp/components/auth/current.templ new file mode 100644 index 000000000..f8a8fb931 --- /dev/null +++ b/pkg/webapp/components/auth/current.templ @@ -0,0 +1,30 @@ +package auth + +import "github.com/onsonr/sonr/pkg/webapp/components/ui" + +// RedirectModal returns the Modal with a QR code to scan. +templ RedirectModal() { + @ui.FullScreenModal() { +
    +
    +
    + + + +

    Continue with your phone

    +

    Creating a Sonr Vault requires a smartphone with W3C compliant biometrics enabled.

    +
    + @ui.Separator("Or Reserve Handle") +
    + + + +
    +
    +

    Already have an account? Login here

    +

    By continuing, you agree to our Terms and Policy.

    +
    + } +} diff --git a/pkg/webapp/components/auth/current_templ.go b/pkg/webapp/components/auth/current_templ.go new file mode 100644 index 000000000..9caad89f3 --- /dev/null +++ b/pkg/webapp/components/auth/current_templ.go @@ -0,0 +1,69 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package auth + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "github.com/onsonr/sonr/pkg/webapp/components/ui" + +// RedirectModal returns the Modal with a QR code to scan. +func RedirectModal() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    Continue with your phone

    Creating a Sonr Vault requires a smartphone with W3C compliant biometrics enabled.

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = ui.Separator("Or Reserve Handle").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    Already have an account? Login here

    By continuing, you agree to our Terms and Policy.

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = ui.FullScreenModal().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/webapp/components/auth/get_credential.templ b/pkg/webapp/components/auth/get_credential.templ deleted file mode 100644 index ed684b025..000000000 --- a/pkg/webapp/components/auth/get_credential.templ +++ /dev/null @@ -1,35 +0,0 @@ -package auth - -import "github.com/labstack/echo/v4" - -templ AssertCredentialForm() { -
    -
    -
    -
    -
    -
    -
    -} - -templ NavigatorCredentialsGetAll(c echo.Context) { - -} diff --git a/pkg/webapp/components/auth/get_credential_templ.go b/pkg/webapp/components/auth/get_credential_templ.go deleted file mode 100644 index bfb597672..000000000 --- a/pkg/webapp/components/auth/get_credential_templ.go +++ /dev/null @@ -1,71 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.793 -package auth - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "github.com/labstack/echo/v4" - -func AssertCredentialForm() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func NavigatorCredentialsGetAll(c echo.Context) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/webapp/components/auth/register.templ b/pkg/webapp/components/auth/register.templ index d1e7c65fb..8568241d3 100644 --- a/pkg/webapp/components/auth/register.templ +++ b/pkg/webapp/components/auth/register.templ @@ -1,6 +1,7 @@ package auth import ( + "github.com/labstack/echo/v4" "github.com/onsonr/sonr/pkg/common/middleware/session" "github.com/onsonr/sonr/pkg/webapp/components/ui" ) @@ -8,7 +9,6 @@ import ( // RegisterModal returns the Register Modal. templ RegisterModal() { @ui.OpenModal(session.GetData(ctx).Id, "Sign up") { - @BasicDetailsForm()
    @@ -16,26 +16,48 @@ templ RegisterModal() { } } -// RedirectModal returns the Modal with a QR code to scan. -templ RedirectModal() { - @ui.FullScreenModal() { -
    -
    -
    -

    Continue with your phone

    -

    Creating a Sonr Vault requires a smartphone with W3C compliant biometrics enabled.

    -
    -
    - - - @ui.Separator("Or Scan QR Code") - -
    -
    -

    Already have an account? Login here

    -

    By continuing, you agree to our Terms and Policy.

    +templ RegisterCredentialForm() { +
    +
    +
    +
    +
    - } +
    +} + +templ NavigatorCredentialsCreate(c echo.Context) { + } diff --git a/pkg/webapp/components/auth/register_start.templ b/pkg/webapp/components/auth/register_start.templ deleted file mode 100644 index 08ead730c..000000000 --- a/pkg/webapp/components/auth/register_start.templ +++ /dev/null @@ -1,53 +0,0 @@ -package auth - -templ BasicDetailsForm() { -
    -
    - @roleSelectInput() -
    -
    -} - -templ roleSelectInput() { -
    - -
    -} - -templ nameInput() { -
    -} - -templ usernameInput() { -
    -} diff --git a/pkg/webapp/components/auth/register_start_templ.go b/pkg/webapp/components/auth/register_start_templ.go deleted file mode 100644 index 35ee1d9f5..000000000 --- a/pkg/webapp/components/auth/register_start_templ.go +++ /dev/null @@ -1,135 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.793 -package auth - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func BasicDetailsForm() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = roleSelectInput().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func roleSelectInput() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func nameInput() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var3 := templ.GetChildren(ctx) - if templ_7745c5c3_Var3 == nil { - templ_7745c5c3_Var3 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -func usernameInput() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var4 := templ.GetChildren(ctx) - if templ_7745c5c3_Var4 == nil { - templ_7745c5c3_Var4 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/webapp/components/auth/register_templ.go b/pkg/webapp/components/auth/register_templ.go index 231cc7bcf..89cd4607c 100644 --- a/pkg/webapp/components/auth/register_templ.go +++ b/pkg/webapp/components/auth/register_templ.go @@ -9,6 +9,7 @@ import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import ( + "github.com/labstack/echo/v4" "github.com/onsonr/sonr/pkg/common/middleware/session" "github.com/onsonr/sonr/pkg/webapp/components/ui" ) @@ -47,11 +48,7 @@ func RegisterModal() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = BasicDetailsForm().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -65,8 +62,7 @@ func RegisterModal() templ.Component { }) } -// RedirectModal returns the Modal with a QR code to scan. -func RedirectModal() templ.Component { +func RegisterCredentialForm() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -87,33 +83,36 @@ func RedirectModal() templ.Component { templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    Continue with your phone

    Creating a Sonr Vault requires a smartphone with W3C compliant biometrics enabled.

    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = ui.Separator("Or Scan QR Code").Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    Already have an account? Login here

    By continuing, you agree to our Terms and Policy.

    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err - }) - templ_7745c5c3_Err = ui.FullScreenModal().Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer) + } + return templ_7745c5c3_Err + }) +} + +func NavigatorCredentialsCreate(c echo.Context) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/pkg/webapp/components/dash/layout.templ b/pkg/webapp/components/dash/layout.templ new file mode 100644 index 000000000..fa07135a8 --- /dev/null +++ b/pkg/webapp/components/dash/layout.templ @@ -0,0 +1,17 @@ +package ui + +// Variant is a component that has attributes +type Variant interface { + Attributes() templ.Attributes +} + +// ╭───────────────────────────────────────────────────────────╮ +// │ General Layout Components │ +// ╰───────────────────────────────────────────────────────────╯ + +// Columns is a component that renders a flex container with a gap of 3 and a max width of 100% +templ Columns() { +
    + { children... } +
    +} diff --git a/pkg/webapp/components/dash/layout_templ.go b/pkg/webapp/components/dash/layout_templ.go new file mode 100644 index 000000000..addc76889 --- /dev/null +++ b/pkg/webapp/components/dash/layout_templ.go @@ -0,0 +1,58 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package ui + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +// Variant is a component that has attributes +type Variant interface { + Attributes() templ.Attributes +} + +// ╭───────────────────────────────────────────────────────────╮ +// │ General Layout Components │ +// ╰───────────────────────────────────────────────────────────╯ + +// Columns is a component that renders a flex container with a gap of 3 and a max width of 100% +func Columns() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/webapp/components/landing/highlights.templ b/pkg/webapp/components/landing/highlights.templ index 841a52b87..6b1436c6f 100644 --- a/pkg/webapp/components/landing/highlights.templ +++ b/pkg/webapp/components/landing/highlights.templ @@ -15,24 +15,44 @@ var highlights = &models.Highlights{ Subtitle: "Sonr is a comprehensive system for Identity Management which proteects users across their digital personas while providing Developers a cost-effective solution for decentralized authentication.", Features: []*models.Feature{ { - Title: "∞ Factor Auth", + Title: "Crypto Wallet", Desc: "Sonr is designed to work across all platforms and devices, building a encrypted and anonymous identity layer for each user on the internet.", Icon: nil, + Image: &models.Image{ + Src: "", + Width: "44", + Height: "44", + }, }, { - Title: "Control Your Data", + Title: "PassKey Authenticator", Desc: "Sonr leverages advanced cryptography to permit facilitating Wallet Operations directly on-chain, without the need for a centralized server.", Icon: nil, + Image: &models.Image{ + Src: "", + Width: "44", + Height: "44", + }, }, { - Title: "Crypto Enabled", + Title: "Anonymous Identity", Desc: "Sonr follows the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.", Icon: nil, + Image: &models.Image{ + Src: "", + Width: "44", + Height: "44", + }, }, { - Title: "Works Everywhere", + Title: "Tokenized Authorization", Desc: "Sonr anonymously associates your online identities with a Quantum-Resistant Vault which only you can access.", Icon: nil, + Image: &models.Image{ + Src: "", + Width: "44", + Height: "44", + }, }, }, } diff --git a/pkg/webapp/components/landing/highlights_templ.go b/pkg/webapp/components/landing/highlights_templ.go index 753f3be5f..242587cc9 100644 --- a/pkg/webapp/components/landing/highlights_templ.go +++ b/pkg/webapp/components/landing/highlights_templ.go @@ -23,24 +23,44 @@ var highlights = &models.Highlights{ Subtitle: "Sonr is a comprehensive system for Identity Management which proteects users across their digital personas while providing Developers a cost-effective solution for decentralized authentication.", Features: []*models.Feature{ { - Title: "∞ Factor Auth", + Title: "Crypto Wallet", Desc: "Sonr is designed to work across all platforms and devices, building a encrypted and anonymous identity layer for each user on the internet.", Icon: nil, + Image: &models.Image{ + Src: "", + Width: "44", + Height: "44", + }, }, { - Title: "Control Your Data", + Title: "PassKey Authenticator", Desc: "Sonr leverages advanced cryptography to permit facilitating Wallet Operations directly on-chain, without the need for a centralized server.", Icon: nil, + Image: &models.Image{ + Src: "", + Width: "44", + Height: "44", + }, }, { - Title: "Crypto Enabled", + Title: "Anonymous Identity", Desc: "Sonr follows the latest specifications from W3C, DIF, and ICF to essentially have an Interchain-Connected, Smart Account System - seamlessly authenticated with PassKeys.", Icon: nil, + Image: &models.Image{ + Src: "", + Width: "44", + Height: "44", + }, }, { - Title: "Works Everywhere", + Title: "Tokenized Authorization", Desc: "Sonr anonymously associates your online identities with a Quantum-Resistant Vault which only you can access.", Icon: nil, + Image: &models.Image{ + Src: "", + Width: "44", + Height: "44", + }, }, }, } @@ -76,7 +96,7 @@ func Highlights() templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(highlights.Heading) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 52, Col: 26} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 72, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -89,7 +109,7 @@ func Highlights() templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(highlights.Subtitle) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 55, Col: 27} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 75, Col: 27} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -151,7 +171,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(getSelectedClass(index)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 74, Col: 34} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 94, Col: 34} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -164,7 +184,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(getClickPrevent(index)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 76, Col: 41} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 96, Col: 41} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -177,7 +197,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 80, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 100, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -190,7 +210,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(getShowBorder(index)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 83, Col: 33} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 103, Col: 33} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -203,7 +223,7 @@ func highlightTab(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 95, Col: 19} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 115, Col: 19} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -245,7 +265,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(getXShow(index)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 103, Col: 26} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 123, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { @@ -258,7 +278,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var12 string templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Src) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 114, Col: 29} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 134, Col: 29} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { @@ -271,7 +291,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var13 string templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Width) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 115, Col: 33} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 135, Col: 33} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { @@ -284,7 +304,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var14 string templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Image.Height) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 116, Col: 35} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 136, Col: 35} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { @@ -297,7 +317,7 @@ func highlightCard(index int, highlight *models.Feature) templ.Component { var templ_7745c5c3_Var15 string templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(highlight.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 117, Col: 25} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/webapp/components/landing/highlights.templ`, Line: 137, Col: 25} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { diff --git a/proto/did/v1/state.proto b/proto/did/v1/state.proto index 3d4576380..b6283e124 100644 --- a/proto/did/v1/state.proto +++ b/proto/did/v1/state.proto @@ -7,7 +7,7 @@ import "did/v1/genesis.proto"; option go_package = "github.com/onsonr/sonr/x/did/types"; -message Assertion { +message Account { option (cosmos.orm.v1.table) = { id: 1 primary_key: {fields: "did"} @@ -40,66 +40,10 @@ message Assertion { int64 creation_block = 7; } -message Authentication { +// PublicKey represents a public key +message PublicKey { option (cosmos.orm.v1.table) = { id: 2 - primary_key: {fields: "did"} - index: { - id: 1 - fields: "controller,subject" - unique: true - } - }; - - // The unique identifier of the authentication - string did = 1; - - // The authentication of the DID - string controller = 2; - - // Origin of the authentication - string subject = 3; - - // string is the verification method - string public_key_hex = 4; - - // CredentialID is the byte representation of the credential ID - bytes credential_id = 5; - - // Metadata of the authentication - map metadata = 6; - - // CreationBlock is the block number of the creation of the authentication - int64 creation_block = 7; -} - -// Macaroon is a Macaroon message type. -message Biscuit { - option (cosmos.orm.v1.table) = { - id: 5 - primary_key: { - fields: "id" - auto_increment: true - } - index: { - id: 1 - fields: "subject,origin" - unique: true - } - }; - - uint64 id = 1; - string controller = 2; - string subject = 3; - string origin = 4; - int64 expiry_height = 5; - string macaroon = 6; -} - -// Controller represents a Sonr DWN Vault -message Controller { - option (cosmos.orm.v1.table) = { - id: 3 primary_key: { fields: "number" auto_increment: true @@ -157,7 +101,7 @@ message Controller { // Verification represents a verification method message Verification { option (cosmos.orm.v1.table) = { - id: 6 + id: 3 primary_key: {fields: "did"} index: { id: 1 diff --git a/proto/dwn/v1/state.proto b/proto/dwn/v1/state.proto index fa5ba9440..625ab05cf 100644 --- a/proto/dwn/v1/state.proto +++ b/proto/dwn/v1/state.proto @@ -7,7 +7,7 @@ option go_package = "github.com/onsonr/sonr/x/dwn/types"; // https://github.com/cosmos/cosmos-sdk/blob/main/orm/README.md -message ExampleData { +message Credential { option (cosmos.orm.v1.table) = { id: 1; primary_key: { fields: "account" } @@ -16,4 +16,15 @@ message ExampleData { bytes account = 1; uint64 amount = 2; -} \ No newline at end of file +} + +message Profile { + option (cosmos.orm.v1.table) = { + id: 2; + primary_key: { fields: "account" } + index: { id: 1 fields: "amount" } + }; + + bytes account = 1; + uint64 amount = 2; +} diff --git a/proto/svc/v1/state.proto b/proto/svc/v1/state.proto index d1067bba4..890b1aa04 100644 --- a/proto/svc/v1/state.proto +++ b/proto/svc/v1/state.proto @@ -8,7 +8,7 @@ option go_package = "github.com/onsonr/sonr/x/svc/types"; // https://github.com/cosmos/cosmos-sdk/blob/main/orm/README.md -message Metadata { +message Domain { option (cosmos.orm.v1.table) = { id: 1 primary_key: { @@ -31,8 +31,8 @@ message Metadata { repeated string tags = 7; } -// Profile represents a DID alias -message Profile { +// Metadata represents a DID alias +message Metadata { option (cosmos.orm.v1.table) = { id: 2 primary_key: {fields: "id"} diff --git a/x/did/controller/table.go b/x/did/controller/table.go index 62ae0cfe6..1d6b00eb1 100644 --- a/x/did/controller/table.go +++ b/x/did/controller/table.go @@ -1,20 +1,13 @@ package controller -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/common/hexutil" - - didv1 "github.com/onsonr/sonr/api/did/v1" -) - -func LoadFromTableEntry(ctx sdk.Context, entry *didv1.Controller) (ControllerI, error) { - k, err := hexutil.Decode(entry.PublicKeyHex) - if err != nil { - return nil, err - } - return &controller{ - address: entry.Did, - chainID: ctx.ChainID(), - publicKey: k, - }, nil -} +// func LoadFromTableEntry(ctx sdk.Context, entry *didv1.Controller) (ControllerI, error) { +// k, err := hexutil.Decode(entry.PublicKeyHex) +// if err != nil { +// return nil, err +// } +// return &controller{ +// address: entry.Did, +// chainID: ctx.ChainID(), +// publicKey: k, +// }, nil +// } diff --git a/x/did/keeper/genesis.go b/x/did/keeper/genesis.go index e9e79e727..77b7c3bbf 100644 --- a/x/did/keeper/genesis.go +++ b/x/did/keeper/genesis.go @@ -23,18 +23,18 @@ func (k Keeper) NewController(ctx sdk.Context) (controller.ControllerI, error) { return controller, nil } -func (k Keeper) ResolveController(ctx sdk.Context, did string) (controller.ControllerI, error) { - ct, err := k.OrmDB.ControllerTable().GetByDid(ctx, did) - if err != nil { - return nil, err - } - c, err := controller.LoadFromTableEntry(ctx, ct) - if err != nil { - return nil, err - } - return c, nil -} - +// func (k Keeper) ResolveController(ctx sdk.Context, did string) (controller.ControllerI, error) { +// ct, err := k.OrmDB.ControllerTable().GetByDid(ctx, did) +// if err != nil { +// return nil, err +// } +// c, err := controller.LoadFromTableEntry(ctx, ct) +// if err != nil { +// return nil, err +// } +// return c, nil +// } +// // Logger returns the logger func (k Keeper) Logger() log.Logger { return k.logger diff --git a/x/did/types/pubkey.go b/x/did/types/pubkey.go index 88c1721f4..0910c0cef 100644 --- a/x/did/types/pubkey.go +++ b/x/did/types/pubkey.go @@ -16,11 +16,6 @@ type PubKeyI interface { // GetJwk() *commonv1.JSONWebKey } -// PubKey defines a generic pubkey. -type PublicKey interface { - VerifySignature(msg, sig []byte) bool -} - type PubKeyG[T any] interface { *T PublicKey diff --git a/x/did/types/state.pb.go b/x/did/types/state.pb.go index 5699701fa..a30b9ccd2 100644 --- a/x/did/types/state.pb.go +++ b/x/did/types/state.pb.go @@ -23,7 +23,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -type Assertion struct { +type Account struct { // The unique identifier of the assertion Did string `protobuf:"bytes,1,opt,name=did,proto3" json:"did,omitempty"` // The authentication of the DID @@ -40,18 +40,18 @@ type Assertion struct { CreationBlock int64 `protobuf:"varint,7,opt,name=creation_block,json=creationBlock,proto3" json:"creation_block,omitempty"` } -func (m *Assertion) Reset() { *m = Assertion{} } -func (m *Assertion) String() string { return proto.CompactTextString(m) } -func (*Assertion) ProtoMessage() {} -func (*Assertion) Descriptor() ([]byte, []int) { +func (m *Account) Reset() { *m = Account{} } +func (m *Account) String() string { return proto.CompactTextString(m) } +func (*Account) ProtoMessage() {} +func (*Account) Descriptor() ([]byte, []int) { return fileDescriptor_f44bb702879c34b4, []int{0} } -func (m *Assertion) XXX_Unmarshal(b []byte) error { +func (m *Account) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *Assertion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *Account) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_Assertion.Marshal(b, m, deterministic) + return xxx_messageInfo_Account.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -61,253 +61,69 @@ func (m *Assertion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *Assertion) XXX_Merge(src proto.Message) { - xxx_messageInfo_Assertion.Merge(m, src) +func (m *Account) XXX_Merge(src proto.Message) { + xxx_messageInfo_Account.Merge(m, src) } -func (m *Assertion) XXX_Size() int { +func (m *Account) XXX_Size() int { return m.Size() } -func (m *Assertion) XXX_DiscardUnknown() { - xxx_messageInfo_Assertion.DiscardUnknown(m) +func (m *Account) XXX_DiscardUnknown() { + xxx_messageInfo_Account.DiscardUnknown(m) } -var xxx_messageInfo_Assertion proto.InternalMessageInfo +var xxx_messageInfo_Account proto.InternalMessageInfo -func (m *Assertion) GetDid() string { +func (m *Account) GetDid() string { if m != nil { return m.Did } return "" } -func (m *Assertion) GetController() string { +func (m *Account) GetController() string { if m != nil { return m.Controller } return "" } -func (m *Assertion) GetSubject() string { +func (m *Account) GetSubject() string { if m != nil { return m.Subject } return "" } -func (m *Assertion) GetPublicKeyHex() string { +func (m *Account) GetPublicKeyHex() string { if m != nil { return m.PublicKeyHex } return "" } -func (m *Assertion) GetAssertionType() string { +func (m *Account) GetAssertionType() string { if m != nil { return m.AssertionType } return "" } -func (m *Assertion) GetAccumulator() map[string][]byte { +func (m *Account) GetAccumulator() map[string][]byte { if m != nil { return m.Accumulator } return nil } -func (m *Assertion) GetCreationBlock() int64 { +func (m *Account) GetCreationBlock() int64 { if m != nil { return m.CreationBlock } return 0 } -type Authentication struct { - // The unique identifier of the authentication - Did string `protobuf:"bytes,1,opt,name=did,proto3" json:"did,omitempty"` - // The authentication of the DID - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - // Origin of the authentication - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - // string is the verification method - PublicKeyHex string `protobuf:"bytes,4,opt,name=public_key_hex,json=publicKeyHex,proto3" json:"public_key_hex,omitempty"` - // CredentialID is the byte representation of the credential ID - CredentialId []byte `protobuf:"bytes,5,opt,name=credential_id,json=credentialId,proto3" json:"credential_id,omitempty"` - // Metadata of the authentication - Metadata map[string]string `protobuf:"bytes,6,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // CreationBlock is the block number of the creation of the authentication - CreationBlock int64 `protobuf:"varint,7,opt,name=creation_block,json=creationBlock,proto3" json:"creation_block,omitempty"` -} - -func (m *Authentication) Reset() { *m = Authentication{} } -func (m *Authentication) String() string { return proto.CompactTextString(m) } -func (*Authentication) ProtoMessage() {} -func (*Authentication) Descriptor() ([]byte, []int) { - return fileDescriptor_f44bb702879c34b4, []int{1} -} -func (m *Authentication) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Authentication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Authentication.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 *Authentication) XXX_Merge(src proto.Message) { - xxx_messageInfo_Authentication.Merge(m, src) -} -func (m *Authentication) XXX_Size() int { - return m.Size() -} -func (m *Authentication) XXX_DiscardUnknown() { - xxx_messageInfo_Authentication.DiscardUnknown(m) -} - -var xxx_messageInfo_Authentication proto.InternalMessageInfo - -func (m *Authentication) GetDid() string { - if m != nil { - return m.Did - } - return "" -} - -func (m *Authentication) GetController() string { - if m != nil { - return m.Controller - } - return "" -} - -func (m *Authentication) GetSubject() string { - if m != nil { - return m.Subject - } - return "" -} - -func (m *Authentication) GetPublicKeyHex() string { - if m != nil { - return m.PublicKeyHex - } - return "" -} - -func (m *Authentication) GetCredentialId() []byte { - if m != nil { - return m.CredentialId - } - return nil -} - -func (m *Authentication) GetMetadata() map[string]string { - if m != nil { - return m.Metadata - } - return nil -} - -func (m *Authentication) GetCreationBlock() int64 { - if m != nil { - return m.CreationBlock - } - return 0 -} - -// Macaroon is a Macaroon message type. -type Biscuit struct { - Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Controller string `protobuf:"bytes,2,opt,name=controller,proto3" json:"controller,omitempty"` - Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` - Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` - ExpiryHeight int64 `protobuf:"varint,5,opt,name=expiry_height,json=expiryHeight,proto3" json:"expiry_height,omitempty"` - Macaroon string `protobuf:"bytes,6,opt,name=macaroon,proto3" json:"macaroon,omitempty"` -} - -func (m *Biscuit) Reset() { *m = Biscuit{} } -func (m *Biscuit) String() string { return proto.CompactTextString(m) } -func (*Biscuit) ProtoMessage() {} -func (*Biscuit) Descriptor() ([]byte, []int) { - return fileDescriptor_f44bb702879c34b4, []int{2} -} -func (m *Biscuit) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Biscuit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Biscuit.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 *Biscuit) XXX_Merge(src proto.Message) { - xxx_messageInfo_Biscuit.Merge(m, src) -} -func (m *Biscuit) XXX_Size() int { - return m.Size() -} -func (m *Biscuit) XXX_DiscardUnknown() { - xxx_messageInfo_Biscuit.DiscardUnknown(m) -} - -var xxx_messageInfo_Biscuit proto.InternalMessageInfo - -func (m *Biscuit) GetId() uint64 { - if m != nil { - return m.Id - } - return 0 -} - -func (m *Biscuit) GetController() string { - if m != nil { - return m.Controller - } - return "" -} - -func (m *Biscuit) GetSubject() string { - if m != nil { - return m.Subject - } - return "" -} - -func (m *Biscuit) GetOrigin() string { - if m != nil { - return m.Origin - } - return "" -} - -func (m *Biscuit) GetExpiryHeight() int64 { - if m != nil { - return m.ExpiryHeight - } - return 0 -} - -func (m *Biscuit) GetMacaroon() string { - if m != nil { - return m.Macaroon - } - return "" -} - -// Controller represents a Sonr DWN Vault -type Controller struct { +// PublicKey represents a public key +type PublicKey struct { // The unique identifier of the controller Number uint64 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` // The unique identifier of the controller @@ -328,18 +144,18 @@ type Controller struct { CreationBlock int64 `protobuf:"varint,9,opt,name=creation_block,json=creationBlock,proto3" json:"creation_block,omitempty"` } -func (m *Controller) Reset() { *m = Controller{} } -func (m *Controller) String() string { return proto.CompactTextString(m) } -func (*Controller) ProtoMessage() {} -func (*Controller) Descriptor() ([]byte, []int) { - return fileDescriptor_f44bb702879c34b4, []int{3} +func (m *PublicKey) Reset() { *m = PublicKey{} } +func (m *PublicKey) String() string { return proto.CompactTextString(m) } +func (*PublicKey) ProtoMessage() {} +func (*PublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_f44bb702879c34b4, []int{1} } -func (m *Controller) XXX_Unmarshal(b []byte) error { +func (m *PublicKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *Controller) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_Controller.Marshal(b, m, deterministic) + return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -349,75 +165,75 @@ func (m *Controller) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *Controller) XXX_Merge(src proto.Message) { - xxx_messageInfo_Controller.Merge(m, src) +func (m *PublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_PublicKey.Merge(m, src) } -func (m *Controller) XXX_Size() int { +func (m *PublicKey) XXX_Size() int { return m.Size() } -func (m *Controller) XXX_DiscardUnknown() { - xxx_messageInfo_Controller.DiscardUnknown(m) +func (m *PublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_PublicKey.DiscardUnknown(m) } -var xxx_messageInfo_Controller proto.InternalMessageInfo +var xxx_messageInfo_PublicKey proto.InternalMessageInfo -func (m *Controller) GetNumber() uint64 { +func (m *PublicKey) GetNumber() uint64 { if m != nil { return m.Number } return 0 } -func (m *Controller) GetDid() string { +func (m *PublicKey) GetDid() string { if m != nil { return m.Did } return "" } -func (m *Controller) GetSonrAddress() string { +func (m *PublicKey) GetSonrAddress() string { if m != nil { return m.SonrAddress } return "" } -func (m *Controller) GetEthAddress() string { +func (m *PublicKey) GetEthAddress() string { if m != nil { return m.EthAddress } return "" } -func (m *Controller) GetBtcAddress() string { +func (m *PublicKey) GetBtcAddress() string { if m != nil { return m.BtcAddress } return "" } -func (m *Controller) GetPublicKeyHex() string { +func (m *PublicKey) GetPublicKeyHex() string { if m != nil { return m.PublicKeyHex } return "" } -func (m *Controller) GetKsVal() string { +func (m *PublicKey) GetKsVal() string { if m != nil { return m.KsVal } return "" } -func (m *Controller) GetClaimedBlock() int64 { +func (m *PublicKey) GetClaimedBlock() int64 { if m != nil { return m.ClaimedBlock } return 0 } -func (m *Controller) GetCreationBlock() int64 { +func (m *PublicKey) GetCreationBlock() int64 { if m != nil { return m.CreationBlock } @@ -450,7 +266,7 @@ func (m *Verification) Reset() { *m = Verification{} } func (m *Verification) String() string { return proto.CompactTextString(m) } func (*Verification) ProtoMessage() {} func (*Verification) Descriptor() ([]byte, []int) { - return fileDescriptor_f44bb702879c34b4, []int{4} + return fileDescriptor_f44bb702879c34b4, []int{2} } func (m *Verification) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -543,12 +359,9 @@ func (m *Verification) GetCreationBlock() int64 { } func init() { - proto.RegisterType((*Assertion)(nil), "did.v1.Assertion") - proto.RegisterMapType((map[string][]byte)(nil), "did.v1.Assertion.AccumulatorEntry") - proto.RegisterType((*Authentication)(nil), "did.v1.Authentication") - proto.RegisterMapType((map[string]string)(nil), "did.v1.Authentication.MetadataEntry") - proto.RegisterType((*Biscuit)(nil), "did.v1.Biscuit") - proto.RegisterType((*Controller)(nil), "did.v1.Controller") + proto.RegisterType((*Account)(nil), "did.v1.Account") + proto.RegisterMapType((map[string][]byte)(nil), "did.v1.Account.AccumulatorEntry") + proto.RegisterType((*PublicKey)(nil), "did.v1.PublicKey") proto.RegisterType((*Verification)(nil), "did.v1.Verification") proto.RegisterMapType((map[string]string)(nil), "did.v1.Verification.MetadataEntry") } @@ -556,62 +369,54 @@ func init() { func init() { proto.RegisterFile("did/v1/state.proto", fileDescriptor_f44bb702879c34b4) } var fileDescriptor_f44bb702879c34b4 = []byte{ - // 821 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x95, 0xdf, 0x8a, 0x23, 0x45, - 0x14, 0xc6, 0xa7, 0xba, 0x27, 0x3d, 0x93, 0x33, 0x99, 0xd0, 0x5b, 0x8c, 0x6b, 0x31, 0x68, 0x8c, - 0xd9, 0x75, 0x19, 0x71, 0x48, 0x58, 0xbd, 0x91, 0x51, 0x16, 0x67, 0x54, 0x58, 0x91, 0xbd, 0x89, - 0xb2, 0xa0, 0x37, 0xa1, 0xba, 0xab, 0x9c, 0x94, 0xe9, 0xee, 0x8a, 0x55, 0xd5, 0x61, 0xf2, 0x12, - 0xe2, 0x13, 0xf8, 0x3c, 0x5e, 0x2e, 0xe8, 0x85, 0x97, 0x32, 0xf3, 0x06, 0x5e, 0x09, 0x0a, 0x4a, - 0x55, 0x75, 0x27, 0x1d, 0x37, 0xb0, 0xba, 0x0a, 0x7b, 0x13, 0x72, 0xbe, 0x3e, 0xf5, 0xe7, 0xfc, - 0xce, 0xd7, 0xa7, 0x01, 0x33, 0xc1, 0x46, 0x8b, 0xfb, 0x23, 0x6d, 0xa8, 0xe1, 0xc3, 0xb9, 0x92, - 0x46, 0xe2, 0x88, 0x09, 0x36, 0x5c, 0xdc, 0x3f, 0x7e, 0x39, 0x95, 0x3a, 0x97, 0x7a, 0x24, 0x55, - 0x6e, 0x53, 0xa4, 0xca, 0x7d, 0xc2, 0xf1, 0x51, 0xb5, 0xe8, 0x92, 0x17, 0x5c, 0x0b, 0xed, 0xd5, - 0xc1, 0x1f, 0x01, 0xb4, 0xcf, 0xb5, 0xe6, 0xca, 0x08, 0x59, 0xe0, 0x18, 0x42, 0x26, 0x18, 0x41, - 0x7d, 0x74, 0xd2, 0x1e, 0xdb, 0xbf, 0xb8, 0x07, 0x90, 0xca, 0xc2, 0x28, 0x99, 0x65, 0x5c, 0x91, - 0xc0, 0x3d, 0x68, 0x28, 0x98, 0xc0, 0x9e, 0x2e, 0x93, 0xaf, 0x79, 0x6a, 0x48, 0xe8, 0x1e, 0xd6, - 0x21, 0xbe, 0x0b, 0xdd, 0x79, 0x99, 0x64, 0x22, 0x9d, 0xcc, 0xf8, 0x72, 0x32, 0xe5, 0x57, 0x64, - 0xd7, 0x25, 0x74, 0xbc, 0xfa, 0x29, 0x5f, 0x3e, 0xe4, 0x57, 0xf8, 0x0d, 0xe8, 0xd2, 0xfa, 0xf8, - 0x89, 0x59, 0xce, 0x39, 0x69, 0xb9, 0xac, 0xc3, 0x95, 0xfa, 0xf9, 0x72, 0xce, 0xf1, 0x47, 0x70, - 0x40, 0xd3, 0xb4, 0xcc, 0xcb, 0x8c, 0x1a, 0xa9, 0x48, 0xd4, 0x0f, 0x4f, 0x0e, 0xde, 0x1e, 0x0c, - 0x7d, 0xcd, 0xc3, 0x55, 0x01, 0xc3, 0xf3, 0x75, 0xd2, 0xc7, 0x85, 0x51, 0xcb, 0x71, 0x73, 0x99, - 0x3d, 0x2c, 0x55, 0x9c, 0xba, 0xb3, 0x92, 0x4c, 0xa6, 0x33, 0xb2, 0xd7, 0x47, 0x27, 0xe1, 0xf8, - 0xb0, 0x56, 0x2f, 0xac, 0x78, 0xfc, 0x00, 0xe2, 0xbf, 0xef, 0x63, 0xc9, 0xcc, 0xf8, 0xb2, 0x26, - 0x33, 0xe3, 0x4b, 0x7c, 0x04, 0xad, 0x05, 0xcd, 0x4a, 0xee, 0xa0, 0x74, 0xc6, 0x3e, 0x38, 0x0b, - 0xde, 0x45, 0x67, 0x6f, 0xfe, 0xfa, 0xfd, 0x8f, 0xdf, 0x86, 0x77, 0xa0, 0xe5, 0x68, 0x62, 0x02, - 0x78, 0x0d, 0xec, 0xb4, 0xc2, 0x13, 0x23, 0x82, 0x08, 0x1a, 0xfc, 0x16, 0x40, 0xf7, 0xbc, 0x34, - 0x53, 0x5e, 0x18, 0x91, 0xd2, 0x17, 0xd4, 0x83, 0x3b, 0x60, 0x01, 0x30, 0x7b, 0x07, 0x9a, 0x4d, - 0x04, 0x73, 0x2d, 0xe8, 0x8c, 0x3b, 0x6b, 0xf1, 0x13, 0x86, 0x3f, 0x80, 0xfd, 0x9c, 0x1b, 0xca, - 0xa8, 0xa1, 0x15, 0xfe, 0xbb, 0x2b, 0xfc, 0x1b, 0x05, 0x0c, 0x1f, 0x55, 0x69, 0xbe, 0x01, 0xab, - 0x55, 0xff, 0x94, 0xfe, 0x7b, 0x70, 0xb8, 0xb1, 0xc3, 0xb3, 0xd0, 0xb7, 0x9f, 0x0b, 0x7d, 0x30, - 0xf8, 0x09, 0xc1, 0xde, 0x85, 0xd0, 0x69, 0x29, 0x0c, 0xee, 0x42, 0x50, 0x21, 0xdf, 0x1d, 0x07, - 0xff, 0x89, 0xf8, 0x6d, 0x88, 0xa4, 0x12, 0x97, 0xa2, 0xa8, 0x48, 0x57, 0x91, 0x65, 0xcc, 0xaf, - 0xe6, 0x42, 0xd9, 0x2e, 0x88, 0xcb, 0xa9, 0x71, 0x8c, 0xc3, 0x71, 0xc7, 0x8b, 0x0f, 0x9d, 0x86, - 0x8f, 0x61, 0x3f, 0xa7, 0x29, 0x55, 0x52, 0x16, 0x24, 0x72, 0xcb, 0x57, 0xf1, 0xd9, 0x3d, 0x57, - 0x59, 0x1f, 0x22, 0x7b, 0xd5, 0x18, 0xe1, 0x23, 0xe8, 0x56, 0x67, 0x9e, 0xfa, 0x23, 0x5c, 0x59, - 0xad, 0xc1, 0x9f, 0x01, 0xc0, 0x87, 0xeb, 0x9b, 0xde, 0x86, 0xa8, 0x28, 0xf3, 0x84, 0xab, 0xaa, - 0xba, 0x2a, 0xaa, 0x5d, 0x16, 0xac, 0x5d, 0xf6, 0x3a, 0x74, 0xb4, 0x2c, 0xd4, 0x84, 0x32, 0xa6, - 0xb8, 0xd6, 0x55, 0x61, 0x07, 0x56, 0x3b, 0xf7, 0x12, 0x7e, 0x0d, 0x0e, 0xb8, 0x99, 0xae, 0x32, - 0x7c, 0x85, 0xc0, 0xcd, 0xb4, 0x91, 0x90, 0x98, 0x74, 0x95, 0xe0, 0x5f, 0x65, 0x48, 0x4c, 0x5a, - 0x27, 0x3c, 0x6d, 0xc8, 0x68, 0x8b, 0x21, 0x5f, 0x82, 0x68, 0xa6, 0x27, 0x0b, 0x9a, 0x39, 0x87, - 0xb4, 0xc7, 0xad, 0x99, 0x7e, 0x4c, 0x33, 0xe7, 0xd3, 0x8c, 0x8a, 0x9c, 0xb3, 0xca, 0x3f, 0xfb, - 0x9e, 0x61, 0x25, 0x3a, 0xfb, 0x6c, 0x71, 0x59, 0x7b, 0x8b, 0xcb, 0xce, 0xbe, 0x70, 0x38, 0x3f, - 0x03, 0xa8, 0xf9, 0xc4, 0x08, 0xe3, 0x4d, 0x02, 0x16, 0x28, 0xbe, 0xb5, 0x51, 0x72, 0x1c, 0x78, - 0xa9, 0x51, 0x64, 0x1c, 0x12, 0x84, 0xdb, 0x8e, 0x66, 0xbc, 0x4b, 0x10, 0x09, 0x07, 0xbf, 0x87, - 0xd0, 0x79, 0xcc, 0x95, 0xf8, 0xea, 0xf9, 0xdf, 0xe8, 0x57, 0x01, 0x98, 0x60, 0x93, 0x9c, 0x9b, - 0xa9, 0x64, 0x55, 0x27, 0xda, 0x4c, 0xb0, 0x47, 0x4e, 0xb0, 0x4d, 0x15, 0x5a, 0x97, 0x5c, 0xd5, - 0x26, 0xf3, 0x51, 0xd3, 0x96, 0xad, 0x67, 0x0d, 0x82, 0x6d, 0xdc, 0xdf, 0x82, 0x5b, 0x8b, 0xc6, - 0xc5, 0xfd, 0x3c, 0xf6, 0x2d, 0x88, 0x9b, 0x0f, 0xdc, 0x48, 0x7e, 0xd0, 0x18, 0x08, 0xfb, 0x9b, - 0xf3, 0xb8, 0x59, 0xfd, 0xbf, 0x18, 0x07, 0xed, 0xff, 0x7d, 0x1c, 0x7c, 0xe3, 0xba, 0x3c, 0xab, - 0xc7, 0xc1, 0x11, 0x74, 0x3d, 0xa9, 0xe6, 0x28, 0xc0, 0x03, 0x78, 0xa5, 0x31, 0x24, 0xd6, 0xdc, - 0x4f, 0x7d, 0xae, 0xeb, 0xf9, 0x3d, 0xe8, 0x3f, 0x45, 0xa6, 0xde, 0xa4, 0xce, 0x0b, 0x09, 0x22, - 0xd1, 0xc5, 0xfb, 0x3f, 0x5c, 0xf7, 0xd0, 0x93, 0xeb, 0x1e, 0xfa, 0xe5, 0xba, 0x87, 0xbe, 0xbb, - 0xe9, 0xed, 0x3c, 0xb9, 0xe9, 0xed, 0xfc, 0x7c, 0xd3, 0xdb, 0xf9, 0x72, 0x70, 0x29, 0xcc, 0xb4, - 0x4c, 0x86, 0xa9, 0xcc, 0x47, 0xb2, 0xb0, 0x4e, 0x1b, 0xb9, 0x9f, 0xab, 0x91, 0xfd, 0x32, 0xdb, - 0x1d, 0x75, 0x12, 0xb9, 0xaf, 0xf2, 0x3b, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xce, 0xd1, 0x02, - 0x2a, 0xe2, 0x07, 0x00, 0x00, + // 690 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xd1, 0x6a, 0x13, 0x4b, + 0x1c, 0xc6, 0x3b, 0xd9, 0x26, 0x6d, 0xfe, 0x49, 0xca, 0x76, 0xe8, 0x39, 0x67, 0x08, 0xe7, 0xe4, + 0xc4, 0x54, 0xa5, 0x62, 0x49, 0xa8, 0xde, 0x48, 0x95, 0x42, 0x0b, 0x82, 0x20, 0x05, 0x89, 0x52, + 0xd0, 0x9b, 0xb0, 0x3b, 0x33, 0x36, 0x6b, 0x76, 0x77, 0xe2, 0xcc, 0x6c, 0xe8, 0xbe, 0x84, 0xf8, + 0x04, 0x3e, 0x8f, 0x97, 0x05, 0x6f, 0xbc, 0x94, 0xf6, 0x0d, 0xbc, 0x12, 0x04, 0x91, 0x9d, 0xd9, + 0x4d, 0xb7, 0x36, 0x50, 0xf1, 0x26, 0xc9, 0x7c, 0xf3, 0xcd, 0xcc, 0xce, 0xef, 0xcb, 0xb7, 0x80, + 0x59, 0xc0, 0x06, 0xb3, 0x9d, 0x81, 0xd2, 0x9e, 0xe6, 0xfd, 0xa9, 0x14, 0x5a, 0xe0, 0x1a, 0x0b, + 0x58, 0x7f, 0xb6, 0xd3, 0xfe, 0x87, 0x0a, 0x15, 0x09, 0x35, 0x10, 0x32, 0xca, 0x2c, 0x42, 0x46, + 0xd6, 0xd0, 0xde, 0xc8, 0x17, 0x1d, 0xf3, 0x98, 0xab, 0x40, 0x59, 0xb5, 0xf7, 0xad, 0x02, 0x2b, + 0xfb, 0x94, 0x8a, 0x24, 0xd6, 0xd8, 0x05, 0x87, 0x05, 0x8c, 0xa0, 0x2e, 0xda, 0xaa, 0x0f, 0xb3, + 0x9f, 0xb8, 0x03, 0x40, 0x45, 0xac, 0xa5, 0x08, 0x43, 0x2e, 0x49, 0xc5, 0x4c, 0x94, 0x14, 0x4c, + 0x60, 0x45, 0x25, 0xfe, 0x1b, 0x4e, 0x35, 0x71, 0xcc, 0x64, 0x31, 0xc4, 0x37, 0x61, 0x6d, 0x9a, + 0xf8, 0x61, 0x40, 0x47, 0x13, 0x9e, 0x8e, 0xc6, 0xfc, 0x84, 0x2c, 0x1b, 0x43, 0xd3, 0xaa, 0x4f, + 0x79, 0xfa, 0x84, 0x9f, 0xe0, 0x5b, 0xb0, 0xe6, 0x29, 0xc5, 0xa5, 0x0e, 0x44, 0x3c, 0xd2, 0xe9, + 0x94, 0x93, 0xaa, 0x71, 0xb5, 0xe6, 0xea, 0x8b, 0x74, 0xca, 0xf1, 0x01, 0x34, 0x3c, 0x4a, 0x93, + 0x28, 0x09, 0x3d, 0x2d, 0x24, 0xa9, 0x75, 0x9d, 0xad, 0xc6, 0xbd, 0x6e, 0xdf, 0xde, 0xb8, 0x9f, + 0x3f, 0x7e, 0xf6, 0x5d, 0x58, 0x1e, 0xc7, 0x5a, 0xa6, 0xc3, 0xf2, 0xa2, 0xec, 0x28, 0x2a, 0xb9, + 0x67, 0x4e, 0xf2, 0x43, 0x41, 0x27, 0x64, 0xa5, 0x8b, 0xb6, 0x9c, 0x61, 0xab, 0x50, 0x0f, 0x32, + 0xb1, 0xbd, 0x07, 0xee, 0xaf, 0xfb, 0x64, 0x5c, 0x26, 0x3c, 0x2d, 0xb8, 0x4c, 0x78, 0x8a, 0x37, + 0xa0, 0x3a, 0xf3, 0xc2, 0x84, 0x1b, 0x24, 0xcd, 0xa1, 0x1d, 0xec, 0x56, 0x1e, 0xa0, 0xdd, 0x3b, + 0x5f, 0x3f, 0x7c, 0x7a, 0xe7, 0x6c, 0x42, 0xd5, 0xb0, 0xc4, 0x04, 0xf0, 0x05, 0xae, 0xed, 0x1c, + 0x8e, 0x8b, 0x08, 0x22, 0xa8, 0xf7, 0xa3, 0x02, 0xf5, 0x67, 0x05, 0x0d, 0xfc, 0x37, 0xd4, 0xe2, + 0x24, 0xf2, 0xb9, 0x34, 0xe7, 0x2c, 0x0f, 0xf3, 0x51, 0x11, 0x4a, 0xe5, 0x22, 0x94, 0x1b, 0xd0, + 0x54, 0x22, 0x96, 0x23, 0x8f, 0x31, 0xc9, 0x95, 0xca, 0xc9, 0x37, 0x32, 0x6d, 0xdf, 0x4a, 0xf8, + 0x7f, 0x68, 0x70, 0x3d, 0x9e, 0x3b, 0x2c, 0x7a, 0xe0, 0x7a, 0x5c, 0x32, 0xf8, 0x9a, 0xce, 0x0d, + 0x96, 0x3a, 0xf8, 0x9a, 0x16, 0x86, 0xab, 0xf9, 0xd5, 0x16, 0xe4, 0xf7, 0x17, 0xd4, 0x26, 0x6a, + 0x34, 0xf3, 0x42, 0x03, 0xb3, 0x3e, 0xac, 0x4e, 0xd4, 0x91, 0x17, 0xe2, 0x4d, 0x68, 0xd1, 0xd0, + 0x0b, 0x22, 0xce, 0x72, 0xd4, 0xab, 0x06, 0x75, 0x33, 0x17, 0x0d, 0xe9, 0x05, 0x81, 0xd4, 0x17, + 0x04, 0xb2, 0xfb, 0xd2, 0x00, 0x7d, 0x0e, 0x50, 0xf0, 0x71, 0x11, 0xc6, 0x97, 0x09, 0x64, 0x3c, + 0xf1, 0xfa, 0xa5, 0x2b, 0xbb, 0x15, 0x2b, 0x95, 0x2e, 0xe9, 0x3a, 0x04, 0xe1, 0xba, 0xa1, 0xe9, + 0x2e, 0x13, 0x44, 0x2a, 0xbd, 0xef, 0x0e, 0x34, 0x8f, 0xb8, 0x0c, 0x5e, 0x07, 0xd4, 0x1c, 0xf8, + 0x07, 0x05, 0xf8, 0x0f, 0x80, 0x05, 0x6c, 0x14, 0x71, 0x3d, 0x16, 0x2c, 0x4f, 0xa2, 0xce, 0x02, + 0x76, 0x68, 0x84, 0x2c, 0xd4, 0x40, 0xa9, 0x84, 0xcb, 0x3c, 0x82, 0x7c, 0x54, 0xee, 0x4d, 0xf5, + 0xba, 0xde, 0x2c, 0xe2, 0x7e, 0x17, 0xd6, 0x67, 0xa5, 0x07, 0xb7, 0xd5, 0xb1, 0x11, 0xb8, 0xe5, + 0x09, 0xd3, 0x9e, 0x3d, 0x58, 0x8d, 0xb8, 0xf6, 0x98, 0xa7, 0x3d, 0xb2, 0x6a, 0xaa, 0xd3, 0x2b, + 0xaa, 0x53, 0xbe, 0x7d, 0xff, 0x30, 0x37, 0xd9, 0xf2, 0xcc, 0xd7, 0xfc, 0x66, 0x50, 0xed, 0x87, + 0xd0, 0xba, 0xb4, 0xc3, 0x75, 0xb5, 0xa9, 0x97, 0x6b, 0xf3, 0xd6, 0xa4, 0x3c, 0x29, 0x6a, 0xb3, + 0x01, 0x6b, 0x96, 0x54, 0xb9, 0x32, 0xb8, 0x07, 0xff, 0x96, 0xca, 0x74, 0xc1, 0x7d, 0xdb, 0x7a, + 0x4d, 0xe6, 0xb7, 0xa1, 0x7b, 0x85, 0x4c, 0xb1, 0x49, 0xe1, 0x73, 0x08, 0x22, 0xce, 0xc1, 0xa3, + 0x8f, 0x67, 0x1d, 0x74, 0x7a, 0xd6, 0x41, 0x5f, 0xce, 0x3a, 0xe8, 0xfd, 0x79, 0x67, 0xe9, 0xf4, + 0xbc, 0xb3, 0xf4, 0xf9, 0xbc, 0xb3, 0xf4, 0xaa, 0x77, 0x1c, 0xe8, 0x71, 0xe2, 0xf7, 0xa9, 0x88, + 0x06, 0x22, 0xce, 0xfe, 0x69, 0x03, 0xf3, 0x71, 0x32, 0xc8, 0x5e, 0xa1, 0xd9, 0x8e, 0xca, 0xaf, + 0x99, 0xd7, 0xe7, 0xfd, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf3, 0xe7, 0x64, 0xd4, 0x8b, 0x05, + 0x00, 0x00, } -func (m *Assertion) Marshal() (dAtA []byte, err error) { +func (m *Account) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -621,12 +426,12 @@ func (m *Assertion) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Assertion) MarshalTo(dAtA []byte) (int, error) { +func (m *Account) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Assertion) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Account) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -695,7 +500,7 @@ func (m *Assertion) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *Authentication) Marshal() (dAtA []byte, err error) { +func (m *PublicKey) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -705,155 +510,12 @@ func (m *Authentication) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Authentication) MarshalTo(dAtA []byte) (int, error) { +func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Authentication) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.CreationBlock != 0 { - i = encodeVarintState(dAtA, i, uint64(m.CreationBlock)) - i-- - dAtA[i] = 0x38 - } - if len(m.Metadata) > 0 { - for k := range m.Metadata { - v := m.Metadata[k] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarintState(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarintState(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarintState(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x32 - } - } - if len(m.CredentialId) > 0 { - i -= len(m.CredentialId) - copy(dAtA[i:], m.CredentialId) - i = encodeVarintState(dAtA, i, uint64(len(m.CredentialId))) - i-- - dAtA[i] = 0x2a - } - if len(m.PublicKeyHex) > 0 { - i -= len(m.PublicKeyHex) - copy(dAtA[i:], m.PublicKeyHex) - i = encodeVarintState(dAtA, i, uint64(len(m.PublicKeyHex))) - i-- - dAtA[i] = 0x22 - } - if len(m.Subject) > 0 { - i -= len(m.Subject) - copy(dAtA[i:], m.Subject) - i = encodeVarintState(dAtA, i, uint64(len(m.Subject))) - i-- - dAtA[i] = 0x1a - } - if len(m.Controller) > 0 { - i -= len(m.Controller) - copy(dAtA[i:], m.Controller) - i = encodeVarintState(dAtA, i, uint64(len(m.Controller))) - i-- - dAtA[i] = 0x12 - } - if len(m.Did) > 0 { - i -= len(m.Did) - copy(dAtA[i:], m.Did) - i = encodeVarintState(dAtA, i, uint64(len(m.Did))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Biscuit) 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 *Biscuit) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Biscuit) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Macaroon) > 0 { - i -= len(m.Macaroon) - copy(dAtA[i:], m.Macaroon) - i = encodeVarintState(dAtA, i, uint64(len(m.Macaroon))) - i-- - dAtA[i] = 0x32 - } - if m.ExpiryHeight != 0 { - i = encodeVarintState(dAtA, i, uint64(m.ExpiryHeight)) - i-- - dAtA[i] = 0x28 - } - if len(m.Origin) > 0 { - i -= len(m.Origin) - copy(dAtA[i:], m.Origin) - i = encodeVarintState(dAtA, i, uint64(len(m.Origin))) - i-- - dAtA[i] = 0x22 - } - if len(m.Subject) > 0 { - i -= len(m.Subject) - copy(dAtA[i:], m.Subject) - i = encodeVarintState(dAtA, i, uint64(len(m.Subject))) - i-- - dAtA[i] = 0x1a - } - if len(m.Controller) > 0 { - i -= len(m.Controller) - copy(dAtA[i:], m.Controller) - i = encodeVarintState(dAtA, i, uint64(len(m.Controller))) - i-- - dAtA[i] = 0x12 - } - if m.Id != 0 { - i = encodeVarintState(dAtA, i, uint64(m.Id)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *Controller) 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 *Controller) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Controller) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *PublicKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1025,7 +687,7 @@ func encodeVarintState(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *Assertion) Size() (n int) { +func (m *Account) Size() (n int) { if m == nil { return 0 } @@ -1069,78 +731,7 @@ func (m *Assertion) Size() (n int) { return n } -func (m *Authentication) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Did) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.Controller) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.Subject) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.PublicKeyHex) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.CredentialId) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - if len(m.Metadata) > 0 { - for k, v := range m.Metadata { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sovState(uint64(len(k))) + 1 + len(v) + sovState(uint64(len(v))) - n += mapEntrySize + 1 + sovState(uint64(mapEntrySize)) - } - } - if m.CreationBlock != 0 { - n += 1 + sovState(uint64(m.CreationBlock)) - } - return n -} - -func (m *Biscuit) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Id != 0 { - n += 1 + sovState(uint64(m.Id)) - } - l = len(m.Controller) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.Subject) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - l = len(m.Origin) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - if m.ExpiryHeight != 0 { - n += 1 + sovState(uint64(m.ExpiryHeight)) - } - l = len(m.Macaroon) - if l > 0 { - n += 1 + l + sovState(uint64(l)) - } - return n -} - -func (m *Controller) Size() (n int) { +func (m *PublicKey) Size() (n int) { if m == nil { return 0 } @@ -1236,7 +827,7 @@ func sovState(x uint64) (n int) { func sozState(x uint64) (n int) { return sovState(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *Assertion) Unmarshal(dAtA []byte) error { +func (m *Account) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1259,10 +850,10 @@ func (m *Assertion) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Assertion: wiretype end group for non-group") + return fmt.Errorf("proto: Account: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Assertion: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Account: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1593,7 +1184,7 @@ func (m *Assertion) Unmarshal(dAtA []byte) error { } return nil } -func (m *Authentication) Unmarshal(dAtA []byte) error { +func (m *PublicKey) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1616,584 +1207,10 @@ func (m *Authentication) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Authentication: wiretype end group for non-group") + return fmt.Errorf("proto: PublicKey: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Authentication: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Did", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Did = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PublicKeyHex", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PublicKeyHex = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CredentialId", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthState - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CredentialId = append(m.CredentialId[:0], dAtA[iNdEx:postIndex]...) - if m.CredentialId == nil { - m.CredentialId = []byte{} - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthState - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Metadata == nil { - m.Metadata = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthState - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthState - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthState - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthState - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipState(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthState - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Metadata[mapkey] = mapvalue - iNdEx = postIndex - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CreationBlock", wireType) - } - m.CreationBlock = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.CreationBlock |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipState(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthState - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Biscuit) 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 ErrIntOverflowState - } - 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: Biscuit: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Biscuit: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - m.Id = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Id |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Controller = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subject = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ExpiryHeight", wireType) - } - m.ExpiryHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ExpiryHeight |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Macaroon", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowState - } - 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 ErrInvalidLengthState - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthState - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Macaroon = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipState(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthState - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Controller) 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 ErrIntOverflowState - } - 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: Controller: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Controller: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: diff --git a/x/dwn/keeper/orm_test.go b/x/dwn/keeper/orm_test.go deleted file mode 100644 index de439d2bf..000000000 --- a/x/dwn/keeper/orm_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package keeper_test - -import ( - "testing" - - apiv1 "github.com/onsonr/sonr/api/dwn/v1" - "github.com/stretchr/testify/require" -) - -func TestORM(t *testing.T) { - f := SetupTest(t) - - dt := f.k.OrmDB.ExampleDataTable() - acc := []byte("test_acc") - amt := uint64(7) - - err := dt.Insert(f.ctx, &apiv1.ExampleData{ - Account: acc, - Amount: amt, - }) - require.NoError(t, err) - - d, err := dt.Has(f.ctx, []byte("test_acc")) - require.NoError(t, err) - require.True(t, d) - - res, err := dt.Get(f.ctx, []byte("test_acc")) - require.NoError(t, err) - require.NotNil(t, res) - require.EqualValues(t, amt, res.Amount) -} diff --git a/x/dwn/types/state.pb.go b/x/dwn/types/state.pb.go index f3029c324..50a481acf 100644 --- a/x/dwn/types/state.pb.go +++ b/x/dwn/types/state.pb.go @@ -23,23 +23,23 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -type ExampleData struct { +type Credential struct { Account []byte `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` } -func (m *ExampleData) Reset() { *m = ExampleData{} } -func (m *ExampleData) String() string { return proto.CompactTextString(m) } -func (*ExampleData) ProtoMessage() {} -func (*ExampleData) Descriptor() ([]byte, []int) { +func (m *Credential) Reset() { *m = Credential{} } +func (m *Credential) String() string { return proto.CompactTextString(m) } +func (*Credential) ProtoMessage() {} +func (*Credential) Descriptor() ([]byte, []int) { return fileDescriptor_040a9b061177db90, []int{0} } -func (m *ExampleData) XXX_Unmarshal(b []byte) error { +func (m *Credential) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *ExampleData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *Credential) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_ExampleData.Marshal(b, m, deterministic) + return xxx_messageInfo_Credential.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -49,26 +49,78 @@ func (m *ExampleData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) return b[:n], nil } } -func (m *ExampleData) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExampleData.Merge(m, src) +func (m *Credential) XXX_Merge(src proto.Message) { + xxx_messageInfo_Credential.Merge(m, src) } -func (m *ExampleData) XXX_Size() int { +func (m *Credential) XXX_Size() int { return m.Size() } -func (m *ExampleData) XXX_DiscardUnknown() { - xxx_messageInfo_ExampleData.DiscardUnknown(m) +func (m *Credential) XXX_DiscardUnknown() { + xxx_messageInfo_Credential.DiscardUnknown(m) } -var xxx_messageInfo_ExampleData proto.InternalMessageInfo +var xxx_messageInfo_Credential proto.InternalMessageInfo -func (m *ExampleData) GetAccount() []byte { +func (m *Credential) GetAccount() []byte { if m != nil { return m.Account } return nil } -func (m *ExampleData) GetAmount() uint64 { +func (m *Credential) GetAmount() uint64 { + if m != nil { + return m.Amount + } + return 0 +} + +type Profile struct { + Account []byte `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` +} + +func (m *Profile) Reset() { *m = Profile{} } +func (m *Profile) String() string { return proto.CompactTextString(m) } +func (*Profile) ProtoMessage() {} +func (*Profile) Descriptor() ([]byte, []int) { + return fileDescriptor_040a9b061177db90, []int{1} +} +func (m *Profile) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Profile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Profile.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 *Profile) XXX_Merge(src proto.Message) { + xxx_messageInfo_Profile.Merge(m, src) +} +func (m *Profile) XXX_Size() int { + return m.Size() +} +func (m *Profile) XXX_DiscardUnknown() { + xxx_messageInfo_Profile.DiscardUnknown(m) +} + +var xxx_messageInfo_Profile proto.InternalMessageInfo + +func (m *Profile) GetAccount() []byte { + if m != nil { + return m.Account + } + return nil +} + +func (m *Profile) GetAmount() uint64 { if m != nil { return m.Amount } @@ -76,29 +128,31 @@ func (m *ExampleData) GetAmount() uint64 { } func init() { - proto.RegisterType((*ExampleData)(nil), "dwn.v1.ExampleData") + proto.RegisterType((*Credential)(nil), "dwn.v1.Credential") + proto.RegisterType((*Profile)(nil), "dwn.v1.Profile") } func init() { proto.RegisterFile("dwn/v1/state.proto", fileDescriptor_040a9b061177db90) } var fileDescriptor_040a9b061177db90 = []byte{ - // 205 bytes of a gzipped FileDescriptorProto + // 219 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4a, 0x29, 0xcf, 0xd3, 0x2f, 0x33, 0xd4, 0x2f, 0x2e, 0x49, 0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4b, 0x29, 0xcf, 0xd3, 0x2b, 0x33, 0x94, 0x12, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0xcf, - 0x2f, 0xca, 0x05, 0x29, 0xc9, 0x2f, 0xca, 0x85, 0x28, 0x50, 0x4a, 0xe0, 0xe2, 0x76, 0xad, 0x48, - 0xcc, 0x2d, 0xc8, 0x49, 0x75, 0x49, 0x2c, 0x49, 0x14, 0x92, 0xe0, 0x62, 0x4f, 0x4c, 0x4e, 0xce, - 0x2f, 0xcd, 0x2b, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x09, 0x82, 0x71, 0x85, 0xc4, 0xb8, 0xd8, - 0x12, 0x73, 0xc1, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x2c, 0x41, 0x50, 0x9e, 0x95, 0xfc, 0xa7, 0x79, - 0x97, 0xfb, 0x98, 0x25, 0xb9, 0x38, 0xe1, 0x3a, 0x85, 0xb8, 0x60, 0x4a, 0x05, 0x18, 0x25, 0x18, - 0x9d, 0x6c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, - 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x29, 0x3d, 0xb3, - 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x3f, 0x3f, 0xaf, 0x38, 0x3f, 0xaf, 0x48, 0x1f, - 0x4c, 0x54, 0xe8, 0x83, 0x7c, 0x52, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x76, 0xa6, 0x31, - 0x20, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x48, 0x77, 0x36, 0xdd, 0x00, 0x00, 0x00, + 0x2f, 0xca, 0x05, 0x29, 0xc9, 0x2f, 0xca, 0x85, 0x28, 0x50, 0x8a, 0xe7, 0xe2, 0x72, 0x2e, 0x4a, + 0x4d, 0x49, 0xcd, 0x2b, 0xc9, 0x4c, 0xcc, 0x11, 0x92, 0xe0, 0x62, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, + 0xcd, 0x2b, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x09, 0x82, 0x71, 0x85, 0xc4, 0xb8, 0xd8, 0x12, + 0x73, 0xc1, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x2c, 0x41, 0x50, 0x9e, 0x95, 0xfc, 0xa7, 0x79, 0x97, + 0xfb, 0x98, 0x25, 0xb9, 0x38, 0xe1, 0x3a, 0x85, 0xb8, 0x60, 0x4a, 0x05, 0x18, 0x25, 0x18, 0x95, + 0x62, 0xb8, 0xd8, 0x03, 0x8a, 0xf2, 0xd3, 0x32, 0x73, 0x52, 0xa9, 0x6f, 0x3a, 0x93, 0x93, 0xcd, + 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, + 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x29, 0xa5, 0x67, 0x96, 0x64, 0x94, + 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xe7, 0xe7, 0x15, 0xe7, 0xe7, 0x15, 0xe9, 0x83, 0x89, 0x0a, + 0x7d, 0x50, 0x30, 0x95, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0xc3, 0xc0, 0x18, 0x10, 0x00, + 0x00, 0xff, 0xff, 0x14, 0x0b, 0x56, 0x1c, 0x3a, 0x01, 0x00, 0x00, } -func (m *ExampleData) Marshal() (dAtA []byte, err error) { +func (m *Credential) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -108,12 +162,47 @@ func (m *ExampleData) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ExampleData) MarshalTo(dAtA []byte) (int, error) { +func (m *Credential) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ExampleData) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Credential) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Amount != 0 { + i = encodeVarintState(dAtA, i, uint64(m.Amount)) + i-- + dAtA[i] = 0x10 + } + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintState(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Profile) 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 *Profile) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Profile) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -144,7 +233,23 @@ func encodeVarintState(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *ExampleData) Size() (n int) { +func (m *Credential) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Account) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + if m.Amount != 0 { + n += 1 + sovState(uint64(m.Amount)) + } + return n +} + +func (m *Profile) Size() (n int) { if m == nil { return 0 } @@ -166,7 +271,7 @@ func sovState(x uint64) (n int) { func sozState(x uint64) (n int) { return sovState(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *ExampleData) Unmarshal(dAtA []byte) error { +func (m *Credential) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -189,10 +294,113 @@ func (m *ExampleData) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ExampleData: wiretype end group for non-group") + return fmt.Errorf("proto: Credential: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ExampleData: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Credential: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = append(m.Account[:0], dAtA[iNdEx:postIndex]...) + if m.Account == nil { + m.Account = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + m.Amount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Amount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipState(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthState + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Profile) 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 ErrIntOverflowState + } + 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: Profile: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Profile: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: diff --git a/x/svc/types/state.pb.go b/x/svc/types/state.pb.go index a7e9ac963..e7f9e4f88 100644 --- a/x/svc/types/state.pb.go +++ b/x/svc/types/state.pb.go @@ -23,7 +23,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -type Metadata struct { +type Domain struct { Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin,omitempty"` Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` @@ -33,11 +33,105 @@ type Metadata struct { Tags []string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"` } +func (m *Domain) Reset() { *m = Domain{} } +func (m *Domain) String() string { return proto.CompactTextString(m) } +func (*Domain) ProtoMessage() {} +func (*Domain) Descriptor() ([]byte, []int) { + return fileDescriptor_2859adb306f7c51f, []int{0} +} +func (m *Domain) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Domain) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Domain.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 *Domain) XXX_Merge(src proto.Message) { + xxx_messageInfo_Domain.Merge(m, src) +} +func (m *Domain) XXX_Size() int { + return m.Size() +} +func (m *Domain) XXX_DiscardUnknown() { + xxx_messageInfo_Domain.DiscardUnknown(m) +} + +var xxx_messageInfo_Domain proto.InternalMessageInfo + +func (m *Domain) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Domain) GetOrigin() string { + if m != nil { + return m.Origin + } + return "" +} + +func (m *Domain) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Domain) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *Domain) GetCategory() string { + if m != nil { + return m.Category + } + return "" +} + +func (m *Domain) GetIcon() string { + if m != nil { + return m.Icon + } + return "" +} + +func (m *Domain) GetTags() []string { + if m != nil { + return m.Tags + } + return nil +} + +// Metadata represents a DID alias +type Metadata struct { + // The unique identifier of the alias + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The alias of the DID + Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` + // Origin of the alias + Origin string `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` + // Controller of the alias + Controller string `protobuf:"bytes,4,opt,name=controller,proto3" json:"controller,omitempty"` +} + func (m *Metadata) Reset() { *m = Metadata{} } func (m *Metadata) String() string { return proto.CompactTextString(m) } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_2859adb306f7c51f, []int{0} + return fileDescriptor_2859adb306f7c51f, []int{1} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -66,11 +160,18 @@ func (m *Metadata) XXX_DiscardUnknown() { var xxx_messageInfo_Metadata proto.InternalMessageInfo -func (m *Metadata) GetId() uint64 { +func (m *Metadata) GetId() string { if m != nil { return m.Id } - return 0 + return "" +} + +func (m *Metadata) GetSubject() string { + if m != nil { + return m.Subject + } + return "" } func (m *Metadata) GetOrigin() string { @@ -80,108 +181,7 @@ func (m *Metadata) GetOrigin() string { return "" } -func (m *Metadata) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Metadata) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Metadata) GetCategory() string { - if m != nil { - return m.Category - } - return "" -} - -func (m *Metadata) GetIcon() string { - if m != nil { - return m.Icon - } - return "" -} - -func (m *Metadata) GetTags() []string { - if m != nil { - return m.Tags - } - return nil -} - -// Profile represents a DID alias -type Profile struct { - // The unique identifier of the alias - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // The alias of the DID - Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` - // Origin of the alias - Origin string `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` - // Controller of the alias - Controller string `protobuf:"bytes,4,opt,name=controller,proto3" json:"controller,omitempty"` -} - -func (m *Profile) Reset() { *m = Profile{} } -func (m *Profile) String() string { return proto.CompactTextString(m) } -func (*Profile) ProtoMessage() {} -func (*Profile) Descriptor() ([]byte, []int) { - return fileDescriptor_2859adb306f7c51f, []int{1} -} -func (m *Profile) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Profile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Profile.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 *Profile) XXX_Merge(src proto.Message) { - xxx_messageInfo_Profile.Merge(m, src) -} -func (m *Profile) XXX_Size() int { - return m.Size() -} -func (m *Profile) XXX_DiscardUnknown() { - xxx_messageInfo_Profile.DiscardUnknown(m) -} - -var xxx_messageInfo_Profile proto.InternalMessageInfo - -func (m *Profile) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -func (m *Profile) GetSubject() string { - if m != nil { - return m.Subject - } - return "" -} - -func (m *Profile) GetOrigin() string { - if m != nil { - return m.Origin - } - return "" -} - -func (m *Profile) GetController() string { +func (m *Metadata) GetController() string { if m != nil { return m.Controller } @@ -189,39 +189,39 @@ func (m *Profile) GetController() string { } func init() { + proto.RegisterType((*Domain)(nil), "svc.v1.Domain") proto.RegisterType((*Metadata)(nil), "svc.v1.Metadata") - proto.RegisterType((*Profile)(nil), "svc.v1.Profile") } func init() { proto.RegisterFile("svc/v1/state.proto", fileDescriptor_2859adb306f7c51f) } var fileDescriptor_2859adb306f7c51f = []byte{ - // 343 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xc1, 0x4a, 0x3b, 0x31, - 0x10, 0xc6, 0x9b, 0xdd, 0xfd, 0x6f, 0xdb, 0xfc, 0xa5, 0x94, 0x20, 0x1a, 0x7a, 0x08, 0x4b, 0xf1, - 0xd0, 0x83, 0x74, 0x29, 0xde, 0x8a, 0x27, 0xef, 0x82, 0xf4, 0xe8, 0x6d, 0x9b, 0x8d, 0x6b, 0xa4, - 0x9b, 0x29, 0x49, 0xba, 0xd8, 0x97, 0x10, 0x7d, 0x01, 0x9f, 0xc7, 0x83, 0x87, 0x82, 0x17, 0x8f, - 0xd2, 0xbe, 0x81, 0x4f, 0x20, 0x49, 0xb7, 0xb2, 0x5e, 0xc2, 0xcc, 0x37, 0xc3, 0x97, 0xef, 0xc7, - 0x60, 0x62, 0x2a, 0x9e, 0x56, 0x93, 0xd4, 0xd8, 0xcc, 0x8a, 0xf1, 0x52, 0x83, 0x05, 0x12, 0x9b, - 0x8a, 0x8f, 0xab, 0xc9, 0xe0, 0x94, 0x83, 0x29, 0xc1, 0xa4, 0xa0, 0x4b, 0xb7, 0x02, 0xba, 0xdc, - 0x2f, 0x0c, 0xdf, 0x11, 0xee, 0x5c, 0x0b, 0x9b, 0xe5, 0x99, 0xcd, 0x48, 0x0f, 0x07, 0x32, 0xa7, - 0x28, 0x41, 0xa3, 0x68, 0x16, 0xc8, 0x9c, 0x9c, 0xe0, 0x18, 0xb4, 0x2c, 0xa4, 0xa2, 0x41, 0x82, - 0x46, 0xdd, 0x59, 0xdd, 0x11, 0x82, 0x23, 0x95, 0x95, 0x82, 0x86, 0x5e, 0xf5, 0x35, 0x49, 0xf0, - 0xff, 0x5c, 0x18, 0xae, 0xe5, 0xd2, 0x4a, 0x50, 0x34, 0xf2, 0xa3, 0xa6, 0x44, 0x06, 0xb8, 0xc3, - 0x33, 0x2b, 0x0a, 0xd0, 0x6b, 0xfa, 0xcf, 0x8f, 0x7f, 0x7b, 0xe7, 0x28, 0x39, 0x28, 0x1a, 0xef, - 0x1d, 0x5d, 0xed, 0x34, 0x9b, 0x15, 0x86, 0xb6, 0x93, 0xd0, 0x69, 0xae, 0x9e, 0xb2, 0xef, 0xd7, - 0x8f, 0xa7, 0x90, 0xe2, 0xd8, 0x25, 0xed, 0x23, 0x72, 0x74, 0x48, 0xd8, 0x47, 0x14, 0x51, 0x34, - 0x7c, 0x41, 0xb8, 0x7d, 0xa3, 0xe1, 0x4e, 0x2e, 0x44, 0x83, 0xa6, 0xeb, 0x69, 0x28, 0x6e, 0x9b, - 0xd5, 0xfc, 0x41, 0x70, 0x5b, 0xe3, 0x1c, 0xda, 0x06, 0x67, 0xf8, 0x87, 0x93, 0x61, 0xcc, 0x41, - 0x59, 0x0d, 0x8b, 0x85, 0xd0, 0x35, 0x52, 0x43, 0x99, 0x9e, 0xf9, 0x34, 0x0c, 0x47, 0xee, 0x27, - 0x72, 0x8c, 0x7b, 0xb5, 0xe1, 0x79, 0x23, 0x53, 0x70, 0x75, 0xf9, 0xb6, 0x65, 0x68, 0xb3, 0x65, - 0xe8, 0x6b, 0xcb, 0xd0, 0xf3, 0x8e, 0xb5, 0x36, 0x3b, 0xd6, 0xfa, 0xdc, 0xb1, 0xd6, 0xed, 0xb0, - 0x90, 0xf6, 0x7e, 0x35, 0x1f, 0x73, 0x28, 0x53, 0x50, 0x06, 0x94, 0x4e, 0xfd, 0xf3, 0x98, 0xba, - 0x53, 0xda, 0xf5, 0x52, 0x98, 0x79, 0xec, 0xef, 0x74, 0xf1, 0x13, 0x00, 0x00, 0xff, 0xff, 0xd0, - 0x82, 0x18, 0x99, 0xde, 0x01, 0x00, 0x00, + // 344 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xb1, 0x6a, 0x23, 0x31, + 0x10, 0x86, 0xad, 0xdd, 0xbd, 0xb5, 0xad, 0x3b, 0x8c, 0x11, 0xc7, 0x9d, 0x70, 0x21, 0x16, 0x73, + 0x85, 0x8b, 0xc3, 0x8b, 0x49, 0x67, 0x52, 0x85, 0xb4, 0x69, 0x5c, 0xa6, 0x93, 0xb5, 0x62, 0xa3, + 0xe0, 0xd5, 0x18, 0x49, 0x5e, 0xe2, 0x97, 0x08, 0x21, 0x0f, 0x90, 0xe7, 0x09, 0xa9, 0x0c, 0x69, + 0x52, 0x06, 0xfb, 0x0d, 0xf2, 0x04, 0x41, 0xf2, 0x3a, 0x6c, 0x1a, 0x31, 0xf3, 0xcf, 0xf0, 0xeb, + 0xff, 0x18, 0x4c, 0x6c, 0x2d, 0xf2, 0x7a, 0x96, 0x5b, 0xc7, 0x9d, 0x9c, 0xae, 0x0d, 0x38, 0x20, + 0xa9, 0xad, 0xc5, 0xb4, 0x9e, 0x8d, 0xfe, 0x0a, 0xb0, 0x15, 0xd8, 0x1c, 0x4c, 0xe5, 0x57, 0xc0, + 0x54, 0xc7, 0x85, 0xf1, 0x0b, 0xc2, 0xe9, 0x25, 0x54, 0x5c, 0x69, 0x32, 0xc0, 0x91, 0x2a, 0x28, + 0xca, 0xd0, 0x24, 0x59, 0x44, 0xaa, 0x20, 0x7f, 0x70, 0x0a, 0x46, 0x95, 0x4a, 0xd3, 0x28, 0x43, + 0x93, 0xfe, 0xa2, 0xe9, 0x08, 0xc1, 0x89, 0xe6, 0x95, 0xa4, 0x71, 0x50, 0x43, 0x4d, 0x32, 0xfc, + 0xb3, 0x90, 0x56, 0x18, 0xb5, 0x76, 0x0a, 0x34, 0x4d, 0xc2, 0xa8, 0x2d, 0x91, 0x11, 0xee, 0x09, + 0xee, 0x64, 0x09, 0x66, 0x4b, 0x7f, 0x84, 0xf1, 0x57, 0xef, 0x1d, 0x95, 0x00, 0x4d, 0xd3, 0xa3, + 0xa3, 0xaf, 0xbd, 0xe6, 0x78, 0x69, 0x69, 0x37, 0x8b, 0xbd, 0xe6, 0xeb, 0x39, 0xfb, 0x78, 0x7a, + 0xbd, 0x8f, 0x29, 0x4e, 0x7d, 0xd2, 0x21, 0x22, 0xbf, 0x4e, 0x09, 0x87, 0x88, 0x22, 0x8a, 0xc6, + 0x8f, 0x08, 0xf7, 0xae, 0xa4, 0xe3, 0x05, 0x77, 0xbc, 0x85, 0xd3, 0x0f, 0x38, 0x14, 0x77, 0xed, + 0x66, 0x79, 0x2b, 0x85, 0x6b, 0x78, 0x4e, 0x6d, 0x0b, 0x34, 0xfe, 0x06, 0xca, 0x30, 0x16, 0xa0, + 0x9d, 0x81, 0xd5, 0x4a, 0x9a, 0x86, 0xa9, 0xa5, 0xcc, 0xff, 0x85, 0x38, 0x0c, 0x27, 0xfe, 0x27, + 0xf2, 0x1b, 0x0f, 0x1a, 0xc3, 0xff, 0xad, 0x50, 0xd1, 0xc5, 0xf9, 0xf3, 0x9e, 0xa1, 0xdd, 0x9e, + 0xa1, 0xf7, 0x3d, 0x43, 0x0f, 0x07, 0xd6, 0xd9, 0x1d, 0x58, 0xe7, 0xed, 0xc0, 0x3a, 0xd7, 0xe3, + 0x52, 0xb9, 0x9b, 0xcd, 0x72, 0x2a, 0xa0, 0xca, 0x41, 0x5b, 0xd0, 0x26, 0x0f, 0xcf, 0x5d, 0xee, + 0x2f, 0xe9, 0xb6, 0x6b, 0x69, 0x97, 0x69, 0x38, 0xd3, 0xd9, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x13, 0x81, 0x47, 0xf4, 0xdd, 0x01, 0x00, 0x00, } -func (m *Metadata) Marshal() (dAtA []byte, err error) { +func (m *Domain) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -231,12 +231,12 @@ func (m *Metadata) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Metadata) MarshalTo(dAtA []byte) (int, error) { +func (m *Domain) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Domain) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -293,7 +293,7 @@ func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *Profile) Marshal() (dAtA []byte, err error) { +func (m *Metadata) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -303,12 +303,12 @@ func (m *Profile) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Profile) MarshalTo(dAtA []byte) (int, error) { +func (m *Metadata) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Profile) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -355,7 +355,7 @@ func encodeVarintState(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *Metadata) Size() (n int) { +func (m *Domain) Size() (n int) { if m == nil { return 0 } @@ -393,7 +393,7 @@ func (m *Metadata) Size() (n int) { return n } -func (m *Profile) Size() (n int) { +func (m *Metadata) Size() (n int) { if m == nil { return 0 } @@ -424,7 +424,7 @@ func sovState(x uint64) (n int) { func sozState(x uint64) (n int) { return sovState(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *Metadata) Unmarshal(dAtA []byte) error { +func (m *Domain) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -447,10 +447,10 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Metadata: wiretype end group for non-group") + return fmt.Errorf("proto: Domain: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Domain: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -685,7 +685,7 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { } return nil } -func (m *Profile) Unmarshal(dAtA []byte) error { +func (m *Metadata) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -708,10 +708,10 @@ func (m *Profile) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Profile: wiretype end group for non-group") + return fmt.Errorf("proto: Metadata: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Profile: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: From 50217d169dc1258508cb43c4d3131981d45c7596 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 26 Nov 2024 00:09:37 -0500 Subject: [PATCH 15/30] fix: resolve rendering issue in login modal --- pkg/webapp/components/auth/login.templ | 1 - pkg/webapp/components/auth/login_templ.go | 4 ---- 2 files changed, 5 deletions(-) diff --git a/pkg/webapp/components/auth/login.templ b/pkg/webapp/components/auth/login.templ index bfd1ecca7..ad6f53750 100644 --- a/pkg/webapp/components/auth/login.templ +++ b/pkg/webapp/components/auth/login.templ @@ -14,7 +14,6 @@ templ LoginModal() { templ loginStart() { @ui.Breadcrumbs() - @BasicDetailsForm() @ui.Spacer()
    diff --git a/pkg/webapp/components/auth/login_templ.go b/pkg/webapp/components/auth/login_templ.go index f7251cb92..bda45eefa 100644 --- a/pkg/webapp/components/auth/login_templ.go +++ b/pkg/webapp/components/auth/login_templ.go @@ -86,10 +86,6 @@ func loginStart() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = BasicDetailsForm().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } templ_7745c5c3_Err = ui.Spacer().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err From b9b868d55ae1c509e861f25278625b71631dbedc Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 26 Nov 2024 10:54:32 -0500 Subject: [PATCH 16/30] refactor: migrate build system from Taskfile to Makefile --- Makefile | 33 +- Taskfile.yml | 86 - cmd/hway/styles.css | 3503 +++++++++++++++++++++++ pkg/webapp/bun.lockb | Bin 119323 -> 44070 bytes pkg/webapp/components/styles/styles.css | 3503 +++++++++++++++++++++++ proto/dwn/v1/genesis.proto | 14 + scripts/init_env.sh | 1 + scripts/upload_pkl.sh | 14 + 8 files changed, 7065 insertions(+), 89 deletions(-) delete mode 100644 Taskfile.yml create mode 100644 cmd/hway/styles.css create mode 100644 pkg/webapp/components/styles/styles.css create mode 100755 scripts/upload_pkl.sh diff --git a/Makefile b/Makefile index b928892b8..e678ef498 100644 --- a/Makefile +++ b/Makefile @@ -289,18 +289,45 @@ sh-testnet: mod-tidy .PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet ############################################################################### -### extras ### +### generation ### ############################################################################### +.PHONY: buf-deploy pkl-gen tailwind-gen templ-gen -.PHONY: buf-publish templ-gen +buf-deploy: + cd ./proto && bunx buf dep update && bunx buf build && bunx buf push + +pkl-deploy: + sh ./scripts/upload_pkl.sh + +pkl-gen: + pkl-gen-go pkl/base.types/Ctx.pkl + pkl-gen-go pkl/base.types/DWN.pkl + pkl-gen-go pkl/base.types/ORM.pkl + +tailwind-gen: + cd ./pkg/webapp && bun install && bun run build + cp ./pkg/webapp/components/styles/styles.css ./cmd/hway/styles.css + rm -rf ./pkg/webapp/node_modules templ-gen: templ generate -buf-publish: + +############################################################################### +### custom builds ### +############################################################################### +.PHONY: motr-build hway-build hway-serve + +buf-deploy: cd ./proto && bunx buf dep update && bunx buf build && bunx buf push +motr-build: + GOOS=js GOARCH=wasm go build -o build/app.wasm ./cmd/motr/main.go + +hway-build: tailwind-gen templ-gen + go build -o build/hway ./cmd/hway/main.go + ############################################################################### ### help ### diff --git a/Taskfile.yml b/Taskfile.yml deleted file mode 100644 index 652684c07..000000000 --- a/Taskfile.yml +++ /dev/null @@ -1,86 +0,0 @@ -version: "3" -vars: - ROOT_DIR: - sh: git rev-parse --show-toplevel - -tasks: - clean: - internal: true - cmds: - - rm -rf .task - - rm -rf pkg/design/node_modules - - rm -rf .out - - # ╭──────────────────────────────────────────────────╮ - # │ Generate Commands │ - # ╰──────────────────────────────────────────────────╯ - - gen:tailwind: - cmds: - - cd ./pkg/webapp && bun run build - - cp ./pkg/webapp/components/styles/styles.css ./cmd/hway/styles.css - - gen:pkl: - sources: - - pkl/base.types/Ctx.pkl - - pkl/base.types/DWN.pkl - - pkl/base.types/ORM.pkl - cmds: - - for: sources - cmd: go run github.com/apple/pkl-go/cmd/pkl-gen-go {{ .ITEM }} - - task: clean - - gen:templ: - cmds: - - templ generate - - # ╭──────────────────────────────────────────────────╮ - # │ Build Commands │ - # ╰──────────────────────────────────────────────────╯ - build:motr: - env: - GOOS: js - GOARCH: wasm - cmds: - - go build -o build/app.wasm ./cmd/motr/main.go - - build:hway: - cmds: - - task: gen:tailwind - - task: gen:templ - - go build -o build/hway ./cmd/hway/main.go - - # ╭──────────────────────────────────────────────────╮ - # │ Serve Commands │ - # ╰──────────────────────────────────────────────────╯ - - serve:hway: - cmds: - - task: build:hway - - ./build/hway - - # ╭──────────────────────────────────────────────────╮ - # │ Deploy Commands │ - # ╰──────────────────────────────────────────────────╯ - deploy:buf: - dir: proto - cmds: - - bunx buf dep update - - bunx buf build - - bunx buf push - - deploy:hway: - dir: cmd/hway - cmds: - - task: gen:design - - bunx wrangler deploy - - deploy:pkl: - cmds: - - bunx pkl project package pkl/*/ - - | - for dir in .out/*/; do - folder=$(basename "$dir") - rclone copy "$dir" "r2:pkljar/$folder" - done - - task: clean diff --git a/cmd/hway/styles.css b/cmd/hway/styles.css new file mode 100644 index 000000000..2e3888049 --- /dev/null +++ b/cmd/hway/styles.css @@ -0,0 +1,3503 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500&family=Inter+Tight:ital,wght@0,500;0,600;0,700;1,700&display=fallback"); + +/* src/css/styles.css */ + +*, ::before, ::after{ + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; + --motion-origin-scale-x: 1; + --motion-origin-scale-y: 1; + --motion-origin-translate-x: 0; + --motion-origin-translate-y: 0; + --motion-origin-rotate: 0; + --motion-origin-blur: 0; + --motion-origin-grayscale: 0; + --motion-origin-opacity: 1; + --motion-origin-background-color: ; + --motion-origin-text-color: ; + --motion-end-scale-x: 1; + --motion-end-scale-y: 1; + --motion-end-translate-x: 0; + --motion-end-translate-y: 0; + --motion-end-rotate: 0; + --motion-end-blur: 0; + --motion-end-grayscale: 0; + --motion-end-opacity: 1; + --motion-end-background-color: ; + --motion-end-text-color: ; + --motion-duration: 750ms; + --motion-timing: var(--motion-default-timing); + --motion-perceptual-duration-multiplier: 1; + --motion-delay: 0ms; + --motion-scale-duration: var(--motion-duration); + --motion-scale-timing: var(--motion-timing); + --motion-scale-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-scale-delay: var(--motion-delay); + --motion-translate-duration: var(--motion-duration); + --motion-translate-timing: var(--motion-timing); + --motion-translate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-translate-delay: var(--motion-delay); + --motion-rotate-duration: var(--motion-duration); + --motion-rotate-timing: var(--motion-timing); + --motion-rotate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-rotate-delay: var(--motion-delay); + --motion-filter-duration: var(--motion-duration); + --motion-filter-timing: var(--motion-timing); + --motion-filter-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-filter-delay: var(--motion-delay); + --motion-opacity-duration: var(--motion-duration); + --motion-opacity-timing: var(--motion-timing); + --motion-opacity-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-opacity-delay: var(--motion-delay); + --motion-background-color-duration: var(--motion-duration); + --motion-background-color-timing: var(--motion-timing); + --motion-background-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-background-color-delay: var(--motion-delay); + --motion-text-color-duration: var(--motion-duration); + --motion-text-color-timing: var(--motion-timing); + --motion-text-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-text-color-delay: var(--motion-delay); + --motion-scale-in-animation: none; + --motion-translate-in-animation: none; + --motion-rotate-in-animation: none; + --motion-filter-in-animation: none; + --motion-opacity-in-animation: none; + --motion-background-color-in-animation: none; + --motion-text-color-in-animation: none; + --motion-scale-out-animation: none; + --motion-translate-out-animation: none; + --motion-rotate-out-animation: none; + --motion-filter-out-animation: none; + --motion-opacity-out-animation: none; + --motion-background-color-out-animation: none; + --motion-text-color-out-animation: none; + --motion-all-enter-animations: var(--motion-scale-in-animation), var(--motion-translate-in-animation), var(--motion-rotate-in-animation), var(--motion-filter-in-animation), var(--motion-opacity-in-animation), var(--motion-background-color-in-animation), var(--motion-text-color-in-animation); + --motion-all-exit-animations: var(--motion-scale-out-animation), var(--motion-translate-out-animation), var(--motion-rotate-out-animation), var(--motion-filter-out-animation), var(--motion-opacity-out-animation), var(--motion-background-color-out-animation), var(--motion-text-color-out-animation); +} + +::backdrop{ + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; + --motion-origin-scale-x: 1; + --motion-origin-scale-y: 1; + --motion-origin-translate-x: 0; + --motion-origin-translate-y: 0; + --motion-origin-rotate: 0; + --motion-origin-blur: 0; + --motion-origin-grayscale: 0; + --motion-origin-opacity: 1; + --motion-origin-background-color: ; + --motion-origin-text-color: ; + --motion-end-scale-x: 1; + --motion-end-scale-y: 1; + --motion-end-translate-x: 0; + --motion-end-translate-y: 0; + --motion-end-rotate: 0; + --motion-end-blur: 0; + --motion-end-grayscale: 0; + --motion-end-opacity: 1; + --motion-end-background-color: ; + --motion-end-text-color: ; + --motion-duration: 750ms; + --motion-timing: var(--motion-default-timing); + --motion-perceptual-duration-multiplier: 1; + --motion-delay: 0ms; + --motion-scale-duration: var(--motion-duration); + --motion-scale-timing: var(--motion-timing); + --motion-scale-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-scale-delay: var(--motion-delay); + --motion-translate-duration: var(--motion-duration); + --motion-translate-timing: var(--motion-timing); + --motion-translate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-translate-delay: var(--motion-delay); + --motion-rotate-duration: var(--motion-duration); + --motion-rotate-timing: var(--motion-timing); + --motion-rotate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-rotate-delay: var(--motion-delay); + --motion-filter-duration: var(--motion-duration); + --motion-filter-timing: var(--motion-timing); + --motion-filter-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-filter-delay: var(--motion-delay); + --motion-opacity-duration: var(--motion-duration); + --motion-opacity-timing: var(--motion-timing); + --motion-opacity-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-opacity-delay: var(--motion-delay); + --motion-background-color-duration: var(--motion-duration); + --motion-background-color-timing: var(--motion-timing); + --motion-background-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-background-color-delay: var(--motion-delay); + --motion-text-color-duration: var(--motion-duration); + --motion-text-color-timing: var(--motion-timing); + --motion-text-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-text-color-delay: var(--motion-delay); + --motion-scale-in-animation: none; + --motion-translate-in-animation: none; + --motion-rotate-in-animation: none; + --motion-filter-in-animation: none; + --motion-opacity-in-animation: none; + --motion-background-color-in-animation: none; + --motion-text-color-in-animation: none; + --motion-scale-out-animation: none; + --motion-translate-out-animation: none; + --motion-rotate-out-animation: none; + --motion-filter-out-animation: none; + --motion-opacity-out-animation: none; + --motion-background-color-out-animation: none; + --motion-text-color-out-animation: none; + --motion-all-enter-animations: var(--motion-scale-in-animation), var(--motion-translate-in-animation), var(--motion-rotate-in-animation), var(--motion-filter-in-animation), var(--motion-opacity-in-animation), var(--motion-background-color-in-animation), var(--motion-text-color-in-animation); + --motion-all-exit-animations: var(--motion-scale-out-animation), var(--motion-translate-out-animation), var(--motion-rotate-out-animation), var(--motion-filter-out-animation), var(--motion-opacity-out-animation), var(--motion-background-color-out-animation), var(--motion-text-color-out-animation); +} + +/* ! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com */ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS +*/ + +html, +:host { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + -webkit-tap-highlight-color: transparent; + /* 7 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-feature-settings: normal; + /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + letter-spacing: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +input:where([type='button']), +input:where([type='reset']), +input:where([type='submit']) { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden]:where(:not([hidden="until-found"])) { + display: none; +} + +[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select{ + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + border-radius: 0px; + padding-top: 0.5rem; + padding-right: 0.75rem; + padding-bottom: 0.5rem; + padding-left: 0.75rem; + font-size: 1rem; + line-height: 1.5rem; + --tw-shadow: 0 0 #0000; +} + +[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus{ + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + border-color: #2563eb; +} + +input::-moz-placeholder, textarea::-moz-placeholder{ + color: #6b7280; + opacity: 1; +} + +input::placeholder,textarea::placeholder{ + color: #6b7280; + opacity: 1; +} + +::-webkit-datetime-edit-fields-wrapper{ + padding: 0; +} + +::-webkit-date-and-time-value{ + min-height: 1.5em; + text-align: inherit; +} + +::-webkit-datetime-edit{ + display: inline-flex; +} + +::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{ + padding-top: 0; + padding-bottom: 0; +} + +select{ + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); + background-position: right 0.5rem center; + background-repeat: no-repeat; + background-size: 1.5em 1.5em; + padding-right: 2.5rem; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; +} + +[multiple],[size]:where(select:not([size="1"])){ + background-image: initial; + background-position: initial; + background-repeat: unset; + background-size: initial; + padding-right: 0.75rem; + -webkit-print-color-adjust: unset; + print-color-adjust: unset; +} + +[type='checkbox'],[type='radio']{ + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding: 0; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + display: inline-block; + vertical-align: middle; + background-origin: border-box; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + flex-shrink: 0; + height: 1rem; + width: 1rem; + color: #2563eb; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + --tw-shadow: 0 0 #0000; +} + +[type='checkbox']{ + border-radius: 0px; +} + +[type='radio']{ + border-radius: 100%; +} + +[type='checkbox']:focus,[type='radio']:focus{ + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); +} + +[type='checkbox']:checked,[type='radio']:checked{ + border-color: transparent; + background-color: currentColor; + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; +} + +[type='checkbox']:checked{ + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); +} + +@media (forced-colors: active) { + [type='checkbox']:checked{ + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='radio']:checked{ + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); +} + +@media (forced-colors: active) { + [type='radio']:checked{ + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus{ + border-color: transparent; + background-color: currentColor; +} + +[type='checkbox']:indeterminate{ + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); + border-color: transparent; + background-color: currentColor; + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; +} + +@media (forced-colors: active) { + [type='checkbox']:indeterminate{ + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus{ + border-color: transparent; + background-color: currentColor; +} + +[type='file']{ + background: unset; + border-color: inherit; + border-width: 0; + border-radius: 0; + padding: 0; + font-size: unset; + line-height: inherit; +} + +[type='file']:focus{ + outline: 1px solid ButtonText; + outline: 1px auto -webkit-focus-ring-color; +} + +:root{ + --motion-default-timing: cubic-bezier(.165, .84, .44, 1); + --motion-bounce: linear(0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141 13.6%, 0.25, 0.391, 0.563, 0.765,1, 0.891 40.9%, 0.848, 0.813, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785,0.813, 0.848, 0.891 68.2%, 1 72.7%, 0.973, 0.953, 0.941, 0.938, 0.941, 0.953,0.973, 1, 0.988, 0.984, 0.988, 1); + --motion-spring-smooth: linear(0, 0.001 0.44%, 0.0045 0.94%, 0.0195 2.03%, 0.0446 3.19%, 0.0811 4.5%, 0.1598 6.82%, 0.3685 12.34%, 0.4693 15.17%, 0.5663, 0.6498 21.27%, 0.7215 24.39%, 0.7532 25.98%, 0.7829 27.65%, 0.8105, 0.8349 31.14%, 0.8573 32.95%, 0.8776 34.84%, 0.8964 36.87%, 0.9136 39.05%, 0.929 41.37%, 0.9421 43.77%, 0.9537 46.38%, 0.9636 49.14%, 0.9789 55.31%, 0.9888 62.35%, 0.9949 71.06%, 0.9982 82.52%, 0.9997 99.94%); + --motion-spring-snappy: linear(0, 0.0014, 0.0053 1.02%, 0.0126, 0.0227 2.18%, 0.0517 3.41%, 0.094 4.79%, 0.1865 7.26%, 0.4182 12.77%, 0.5246 15.46%, 0.6249, 0.7112, 0.7831 23.95%, 0.8146 25.4%, 0.844, 0.8699 28.45%, 0.8935, 0.9139 31.64%, 0.932, 0.9473, 0.9601 36.65%, 0.9714 38.47%, 0.9808 40.35%, 0.9948 44.49%, 1.0031 49.43%, 1.0057 53.35%, 1.0063 58.14%, 1.0014 80.78%, 1.0001 99.94%); + --motion-spring-bouncy: linear(0, 0.0018, 0.0069, 0.0151 1.74%, 0.0277 2.4%, 0.062 3.7%, 0.1115 5.15%, 0.2211 7.77%, 0.4778 13.21%, 0.5912 15.75%, 0.6987 18.44%, 0.7862 20.98%, 0.861 23.59%, 0.8926, 0.9205, 0.945 27.51%, 0.9671 28.89%, 0.9868, 1.003 31.79%, 1.0224 34.11%, 1.0358 36.58%, 1.0436 39.27%, 1.046 42.31%, 1.0446 44.71%, 1.0406 47.47%, 1.0118 61.84%, 1.0027 69.53%, 0.9981 80.49%, 0.9991 99.94%); + --motion-spring-bouncier: linear(0, 0.0023, 0.0088, 0.0194 1.59%, 0.035 2.17%, 0.078 3.33%, 0.1415 4.64%, 0.2054 5.75%, 0.2821 6.95%, 0.5912 11.45%, 0.7205 13.43%, 0.8393 15.45%, 0.936 17.39%, 0.9778, 1.015, 1.0477, 1.0759, 1.0998 22.22%, 1.1203, 1.1364, 1.1484 25.26%, 1.1586 26.61%, 1.1629 28.06%, 1.1613 29.56%, 1.1537 31.2%, 1.1434 32.6%, 1.1288 34.19%, 1.0508 41.29%, 1.0174 44.87%, 1.0025 46.89%, 0.9911 48.87%, 0.9826 50.9%, 0.9769 53.03%, 0.9735 56.02%, 0.9748 59.45%, 0.9964 72.64%, 1.0031 79.69%, 1.0042 86.83%, 1.0008 99.97%); + --motion-spring-bounciest: linear(0, 0.0032, 0.0131, 0.0294, 0.0524, 0.0824, 0.1192 1.54%, 0.2134 2.11%, 0.3102 2.59%, 0.4297 3.13%, 0.8732 4.95%, 1.0373, 1.1827 6.36%, 1.2972 7.01%, 1.3444, 1.3859, 1.4215, 1.4504, 1.4735, 1.4908, 1.5024, 1.5084 9.5%, 1.5091, 1.5061, 1.4993, 1.4886, 1.4745, 1.4565 11.11%, 1.4082 11.7%, 1.3585 12.2%, 1.295 12.77%, 1.0623 14.64%, 0.9773, 0.9031 16.08%, 0.8449 16.73%, 0.8014, 0.7701 17.95%, 0.7587, 0.7501, 0.7443, 0.7412 19.16%, 0.7421 19.68%, 0.7508 20.21%, 0.7672 20.77%, 0.7917 21.37%, 0.8169 21.87%, 0.8492 22.43%, 0.9681 24.32%, 1.0114, 1.0492 25.75%, 1.0789 26.41%, 1.1008, 1.1167, 1.1271, 1.1317 28.81%, 1.1314, 1.1271 29.87%, 1.1189 30.43%, 1.1063 31.03%, 1.0769 32.11%, 0.9941 34.72%, 0.9748 35.43%, 0.9597 36.09%, 0.9487, 0.9407, 0.9355, 0.933 38.46%, 0.9344 39.38%, 0.9421 40.38%, 0.9566 41.5%, 0.9989 44.12%, 1.0161 45.37%, 1.029 46.75%, 1.0341 48.1%, 1.0335 49.04%, 1.0295 50.05%, 1.0221 51.18%, 0.992 55.02%, 0.9854 56.38%, 0.9827 57.72%, 0.985 59.73%, 1.004 64.67%, 1.0088 67.34%, 1.0076 69.42%, 0.9981 74.28%, 0.9956 76.85%, 0.9961 79.06%, 1.0023 86.46%, 0.999 95.22%, 0.9994 100%); +} + +.container{ + width: 100%; +} + +@media (min-width: 640px){ + .container{ + max-width: 640px; + } +} + +@media (min-width: 768px){ + .container{ + max-width: 768px; + } +} + +@media (min-width: 1024px){ + .container{ + max-width: 1024px; + } +} + +@media (min-width: 1280px){ + .container{ + max-width: 1280px; + } +} + +@media (min-width: 1536px){ + .container{ + max-width: 1536px; + } +} + +.motion-preset-slide-up{ + --motion-origin-translate-y: 25%; + --motion-origin-opacity: 0; + --motion-opacity-in-animation: motion-opacity-in calc(var(--motion-opacity-duration) * var(--motion-opacity-perceptual-duration-multiplier)) var(--motion-opacity-timing) var(--motion-opacity-delay) both; + --motion-translate-in-animation: motion-translate-in calc(var(--motion-translate-duration) * var(--motion-translate-perceptual-duration-multiplier)) var(--motion-translate-timing) var(--motion-translate-delay) both; + animation: var(--motion-all-enter-animations); +} + +@keyframes RomboConfettiPop{ + 0%{ + opacity: 0; + transform: scale(1); + } + + 33%{ + opacity: 1; + transform: scale(1.15); + } + + 50%{ + transform: scale(0.975); + } + + 65%{ + transform: scale(1.025); + } + + 80%{ + transform: scale(0.99); + } + + 87%{ + transform: scale(1.01); + } + + 100%{ + opacity: 1; + transform: scale(1); + } +} + +@keyframes topfetti{ + 0%{ + background-position: 5% 90%, 10% 90%, 10% 90%, 15% 90%, 25% 90%, 25% 90%, 40% 90%, 55% 90%, 70% 90%; + } + + 50%{ + background-position: 0% 80%, 0% 20%, 10% 40%, 20% 0%, 30% 30%, 22% 50%, 50% 50%, 65% 20%, 90% 30%; + } + + 100%{ + background-position: 0% 70%, 0% 10%, 10% 30%, 20% -10%, 30% 20%, 22% 40%, 50% 40%, 65% 10%, 90% 20%; + background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; + } +} + +@keyframes bottomfetti{ + 0%{ + background-position: 10% -10%, 30% 10%, 55% -10%, 70% -10%, 85% -10%,70% -10%, 70% 0%; + } + + 50%{ + background-position: 0% 80%, 20% 80%, 45% 60%, 60% 100%, 75% 70%, 95% 60%, 105% 0%; + } + + 100%{ + background-position: 0% 90%, 20% 90%, 45% 70%, 60% 110%, 75% 80%, 95% 70%, 110% 10%; + background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; + } +} + +.fixed{ + position: fixed; +} + +.absolute{ + position: absolute; +} + +.relative{ + position: relative; +} + +.inset-0{ + inset: 0px; +} + +.bottom-0{ + bottom: 0px; +} + +.left-0{ + left: 0px; +} + +.left-1\/2{ + left: 50%; +} + +.right-0{ + right: 0px; +} + +.top-0{ + top: 0px; +} + +.top-2{ + top: 0.5rem; +} + +.-z-10{ + z-index: -10; +} + +.z-10{ + z-index: 10; +} + +.z-20{ + z-index: 20; +} + +.z-30{ + z-index: 30; +} + +.z-40{ + z-index: 40; +} + +.z-50{ + z-index: 50; +} + +.z-\[99\]{ + z-index: 99; +} + +.order-first{ + order: -9999; +} + +.-m-2{ + margin: -0.5rem; +} + +.m-2{ + margin: 0.5rem; +} + +.mx-auto{ + margin-left: auto; + margin-right: auto; +} + +.mb-1{ + margin-bottom: 0.25rem; +} + +.mb-2{ + margin-bottom: 0.5rem; +} + +.mb-3{ + margin-bottom: 0.75rem; +} + +.mb-4{ + margin-bottom: 1rem; +} + +.mb-6{ + margin-bottom: 1.5rem; +} + +.mb-8{ + margin-bottom: 2rem; +} + +.ml-1{ + margin-left: 0.25rem; +} + +.ml-2{ + margin-left: 0.5rem; +} + +.ml-3{ + margin-left: 0.75rem; +} + +.mr-1{ + margin-right: 0.25rem; +} + +.mr-2{ + margin-right: 0.5rem; +} + +.mr-3{ + margin-right: 0.75rem; +} + +.mr-4{ + margin-right: 1rem; +} + +.mr-5{ + margin-right: 1.25rem; +} + +.mr-7{ + margin-right: 1.75rem; +} + +.mt-1{ + margin-top: 0.25rem; +} + +.mt-12{ + margin-top: 3rem; +} + +.mt-2{ + margin-top: 0.5rem; +} + +.mt-24{ + margin-top: 6rem; +} + +.mt-4{ + margin-top: 1rem; +} + +.mt-5{ + margin-top: 1.25rem; +} + +.mt-6{ + margin-top: 1.5rem; +} + +.box-content{ + box-sizing: content-box; +} + +.block{ + display: block; +} + +.flex{ + display: flex; +} + +.inline-flex{ + display: inline-flex; +} + +.grid{ + display: grid; +} + +.hidden{ + display: none; +} + +.h-0\.5{ + height: 0.125rem; +} + +.h-10{ + height: 2.5rem; +} + +.h-14{ + height: 3.5rem; +} + +.h-20{ + height: 5rem; +} + +.h-3{ + height: 0.75rem; +} + +.h-32{ + height: 8rem; +} + +.h-4{ + height: 1rem; +} + +.h-5{ + height: 1.25rem; +} + +.h-8{ + height: 2rem; +} + +.h-9{ + height: 2.25rem; +} + +.h-\[280px\]{ + height: 280px; +} + +.h-auto{ + height: auto; +} + +.h-full{ + height: 100%; +} + +.h-screen{ + height: 100vh; +} + +.min-h-screen{ + min-height: 100vh; +} + +.w-0{ + width: 0px; +} + +.w-1\/3{ + width: 33.333333%; +} + +.w-14{ + width: 3.5rem; +} + +.w-16{ + width: 4rem; +} + +.w-20{ + width: 5rem; +} + +.w-3{ + width: 0.75rem; +} + +.w-4{ + width: 1rem; +} + +.w-5{ + width: 1.25rem; +} + +.w-8{ + width: 2rem; +} + +.w-\[22rem\]{ + width: 22rem; +} + +.w-\[365px\]{ + width: 365px; +} + +.w-\[calc\(100\%\+1rem\)\]{ + width: calc(100% + 1rem); +} + +.w-\[full\]{ + width: full; +} + +.w-auto{ + width: auto; +} + +.w-fit{ + width: -moz-fit-content; + width: fit-content; +} + +.w-full{ + width: 100%; +} + +.w-screen{ + width: 100vw; +} + +.max-w-2xl{ + max-width: 42rem; +} + +.max-w-3xl{ + max-width: 48rem; +} + +.max-w-4xl{ + max-width: 56rem; +} + +.max-w-5xl{ + max-width: 64rem; +} + +.max-w-6xl{ + max-width: 72rem; +} + +.max-w-\[94rem\]{ + max-width: 94rem; +} + +.max-w-lg{ + max-width: 32rem; +} + +.max-w-md{ + max-width: 28rem; +} + +.max-w-screen-sm{ + max-width: 640px; +} + +.max-w-sm{ + max-width: 24rem; +} + +.max-w-xl{ + max-width: 36rem; +} + +.max-w-xs{ + max-width: 20rem; +} + +.flex-shrink-0{ + flex-shrink: 0; +} + +.shrink-0{ + flex-shrink: 0; +} + +.grow{ + flex-grow: 1; +} + +.-translate-x-0{ + --tw-translate-x: -0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-1\/2{ + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-4{ + --tw-translate-x: -1rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-7{ + --tw-translate-x: -1.75rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-8{ + --tw-translate-x: -2rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-px{ + --tw-translate-x: -1px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-y-4{ + --tw-translate-y: -1rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-y-px{ + --tw-translate-y: -1px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-x-0{ + --tw-translate-x: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-x-8{ + --tw-translate-x: 2rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-0{ + --tw-translate-y: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-1\/3{ + --tw-translate-y: 33.333333%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-24{ + --tw-translate-y: 6rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-3{ + --tw-translate-y: 0.75rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-4{ + --tw-translate-y: 1rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.rotate-1{ + --tw-rotate: 1deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.scale-100{ + --tw-scale-x: 1; + --tw-scale-y: 1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.scale-90{ + --tw-scale-x: .9; + --tw-scale-y: .9; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.transform{ + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes infinite-scroll{ + from{ + transform: translateX(0); + } + + to{ + transform: translateX(-100%); + } +} + +.animate-infinite-scroll{ + animation: infinite-scroll 60s linear infinite; +} + +@keyframes infinite-scroll-inverse{ + from{ + transform: translateX(-100%); + } + + to{ + transform: translateX(0); + } +} + +.animate-infinite-scroll-inverse{ + animation: infinite-scroll-inverse 60s linear infinite; +} + +.cursor-default{ + cursor: default; +} + +.cursor-pointer{ + cursor: pointer; +} + +.grid-cols-2{ + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.flex-row{ + flex-direction: row; +} + +.flex-col{ + flex-direction: column; +} + +.flex-col-reverse{ + flex-direction: column-reverse; +} + +.flex-wrap{ + flex-wrap: wrap; +} + +.flex-nowrap{ + flex-wrap: nowrap; +} + +.items-start{ + align-items: flex-start; +} + +.items-end{ + align-items: flex-end; +} + +.items-center{ + align-items: center; +} + +.justify-end{ + justify-content: flex-end; +} + +.justify-center{ + justify-content: center; +} + +.justify-between{ + justify-content: space-between; +} + +.gap-12{ + gap: 3rem; +} + +.gap-2{ + gap: 0.5rem; +} + +.gap-3{ + gap: 0.75rem; +} + +.gap-4{ + gap: 1rem; +} + +.gap-8{ + gap: 2rem; +} + +.gap-x-3{ + -moz-column-gap: 0.75rem; + column-gap: 0.75rem; +} + +.gap-y-3{ + row-gap: 0.75rem; +} + +.space-x-1 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(0.25rem * var(--tw-space-x-reverse)); + margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-x-3 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(0.75rem * var(--tw-space-x-reverse)); + margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-x-4 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-y-1 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); +} + +.space-y-1\.5 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.375rem * var(--tw-space-y-reverse)); +} + +.space-y-12 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(3rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(3rem * var(--tw-space-y-reverse)); +} + +.space-y-2 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.space-y-4 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} + +.space-y-6 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); +} + +.overflow-hidden{ + overflow: hidden; +} + +.rounded{ + border-radius: 0.25rem; +} + +.rounded-full{ + border-radius: 9999px; +} + +.rounded-lg{ + border-radius: 0.5rem; +} + +.rounded-md{ + border-radius: 0.375rem; +} + +.rounded-xl{ + border-radius: 0.75rem; +} + +.rounded-t-lg{ + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; +} + +.border{ + border-width: 1px; +} + +.border-2{ + border-width: 2px; +} + +.border-\[2px\]{ + border-width: 2px; +} + +.border-t{ + border-top-width: 1px; +} + +.border-neutral-200\/60{ + border-color: rgb(229 229 229 / 0.6); +} + +.border-neutral-200\/70{ + border-color: rgb(229 229 229 / 0.7); +} + +.border-neutral-300{ + --tw-border-opacity: 1; + border-color: rgb(212 212 212 / var(--tw-border-opacity, 1)); +} + +.border-transparent{ + border-color: transparent; +} + +.border-white{ + --tw-border-opacity: 1; + border-color: rgb(255 255 255 / var(--tw-border-opacity, 1)); +} + +.border-zinc-200{ + --tw-border-opacity: 1; + border-color: rgb(228 228 231 / var(--tw-border-opacity, 1)); +} + +.border-zinc-300{ + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); +} + +.border-zinc-600{ + --tw-border-opacity: 1; + border-color: rgb(82 82 91 / var(--tw-border-opacity, 1)); +} + +.bg-blue-600{ + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)); +} + +.bg-neutral-50{ + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); +} + +.bg-neutral-900{ + --tw-bg-opacity: 1; + background-color: rgb(23 23 23 / var(--tw-bg-opacity, 1)); +} + +.bg-neutral-950{ + --tw-bg-opacity: 1; + background-color: rgb(10 10 10 / var(--tw-bg-opacity, 1)); +} + +.bg-transparent{ + background-color: transparent; +} + +.bg-white{ + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); +} + +.bg-zinc-100{ + --tw-bg-opacity: 1; + background-color: rgb(244 244 245 / var(--tw-bg-opacity, 1)); +} + +.bg-zinc-50{ + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); +} + +.bg-zinc-800{ + --tw-bg-opacity: 1; + background-color: rgb(39 39 42 / var(--tw-bg-opacity, 1)); +} + +.bg-zinc-900{ + --tw-bg-opacity: 1; + background-color: rgb(24 24 27 / var(--tw-bg-opacity, 1)); +} + +.bg-opacity-90{ + --tw-bg-opacity: 0.9; +} + +.bg-gradient-to-r{ + background-image: linear-gradient(to right, var(--tw-gradient-stops)); +} + +.bg-gradient-to-t{ + background-image: linear-gradient(to top, var(--tw-gradient-stops)); +} + +.from-black{ + --tw-gradient-from: #000 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.from-zinc-100{ + --tw-gradient-from: #f4f4f5 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(244 244 245 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.from-zinc-500{ + --tw-gradient-from: #71717a var(--tw-gradient-from-position); + --tw-gradient-to: rgb(113 113 122 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.via-zinc-900{ + --tw-gradient-to: rgb(24 24 27 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), #18181b var(--tw-gradient-via-position), var(--tw-gradient-to); +} + +.to-white{ + --tw-gradient-to: #fff var(--tw-gradient-to-position); +} + +.to-zinc-900{ + --tw-gradient-to: #18181b var(--tw-gradient-to-position); +} + +.bg-cover{ + background-size: cover; +} + +.bg-clip-text{ + -webkit-background-clip: text; + background-clip: text; +} + +.fill-current{ + fill: currentColor; +} + +.fill-zinc-300{ + fill: #d4d4d8; +} + +.fill-zinc-400{ + fill: #a1a1aa; +} + +.object-cover{ + -o-object-fit: cover; + object-fit: cover; +} + +.object-left{ + -o-object-position: left; + object-position: left; +} + +.p-1{ + padding: 0.25rem; +} + +.p-4{ + padding: 1rem; +} + +.p-5{ + padding: 1.25rem; +} + +.p-6{ + padding: 1.5rem; +} + +.p-7{ + padding: 1.75rem; +} + +.px-0\.5{ + padding-left: 0.125rem; + padding-right: 0.125rem; +} + +.px-2{ + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-2\.5{ + padding-left: 0.625rem; + padding-right: 0.625rem; +} + +.px-3{ + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-3\.5{ + padding-left: 0.875rem; + padding-right: 0.875rem; +} + +.px-4{ + padding-left: 1rem; + padding-right: 1rem; +} + +.px-5{ + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.px-6{ + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.px-7{ + padding-left: 1.75rem; + padding-right: 1.75rem; +} + +.px-8{ + padding-left: 2rem; + padding-right: 2rem; +} + +.py-0\.5{ + padding-top: 0.125rem; + padding-bottom: 0.125rem; +} + +.py-1{ + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-12{ + padding-top: 3rem; + padding-bottom: 3rem; +} + +.py-2{ + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.py-3{ + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.py-4{ + padding-top: 1rem; + padding-bottom: 1rem; +} + +.py-5{ + padding-top: 1.25rem; + padding-bottom: 1.25rem; +} + +.py-6{ + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +.py-8{ + padding-top: 2rem; + padding-bottom: 2rem; +} + +.py-px{ + padding-top: 1px; + padding-bottom: 1px; +} + +.pb-1{ + padding-bottom: 0.25rem; +} + +.pb-12{ + padding-bottom: 3rem; +} + +.pb-2{ + padding-bottom: 0.5rem; +} + +.pb-3{ + padding-bottom: 0.75rem; +} + +.pb-4{ + padding-bottom: 1rem; +} + +.pb-6{ + padding-bottom: 1.5rem; +} + +.pb-8{ + padding-bottom: 2rem; +} + +.pl-4{ + padding-left: 1rem; +} + +.pr-2{ + padding-right: 0.5rem; +} + +.pr-4{ + padding-right: 1rem; +} + +.pt-0{ + padding-top: 0px; +} + +.pt-2{ + padding-top: 0.5rem; +} + +.pt-32{ + padding-top: 8rem; +} + +.pt-6{ + padding-top: 1.5rem; +} + +.pt-8{ + padding-top: 2rem; +} + +.text-left{ + text-align: left; +} + +.text-center{ + text-align: center; +} + +.align-top{ + vertical-align: top; +} + +.font-inter{ + font-family: Inter, sans-serif; +} + +.font-inter-tight{ + font-family: Inter Tight, sans-serif; +} + +.font-sans{ + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} + +.text-2xl{ + font-size: 1.5rem; + line-height: 1.415; + letter-spacing: -0.017em; +} + +.text-3xl{ + font-size: 2rem; + line-height: 1.3125; + letter-spacing: -0.017em; +} + +.text-4xl{ + font-size: 2.5rem; + line-height: 1.25; + letter-spacing: -0.017em; +} + +.text-\[0\.6rem\]{ + font-size: 0.6rem; +} + +.text-base{ + font-size: 1rem; + line-height: 1.5; + letter-spacing: -0.017em; +} + +.text-lg{ + font-size: 1.125rem; + line-height: 1.5; + letter-spacing: -0.017em; +} + +.text-sm{ + font-size: 0.875rem; + line-height: 1.5715; +} + +.text-xl{ + font-size: 1.25rem; + line-height: 1.5; + letter-spacing: -0.017em; +} + +.text-xs{ + font-size: 0.75rem; + line-height: 1.5; +} + +.font-bold{ + font-weight: 700; +} + +.font-extrabold{ + font-weight: 800; +} + +.font-medium{ + font-weight: 500; +} + +.font-normal{ + font-weight: 400; +} + +.font-semibold{ + font-weight: 600; +} + +.uppercase{ + text-transform: uppercase; +} + +.italic{ + font-style: italic; +} + +.not-italic{ + font-style: normal; +} + +.tabular-nums{ + --tw-numeric-spacing: tabular-nums; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); +} + +.leading-none{ + line-height: 1; +} + +.tracking-tight{ + letter-spacing: -0.025em; +} + +.tracking-wide{ + letter-spacing: 0.025em; +} + +.text-blue-600{ + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity, 1)); +} + +.text-gray-400{ + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity, 1)); +} + +.text-gray-400\/70{ + color: rgb(156 163 175 / 0.7); +} + +.text-gray-500{ + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity, 1)); +} + +.text-gray-600{ + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity, 1)); +} + +.text-neutral-100{ + --tw-text-opacity: 1; + color: rgb(245 245 245 / var(--tw-text-opacity, 1)); +} + +.text-neutral-500{ + --tw-text-opacity: 1; + color: rgb(115 115 115 / var(--tw-text-opacity, 1)); +} + +.text-neutral-800{ + --tw-text-opacity: 1; + color: rgb(38 38 38 / var(--tw-text-opacity, 1)); +} + +.text-neutral-900{ + --tw-text-opacity: 1; + color: rgb(23 23 23 / var(--tw-text-opacity, 1)); +} + +.text-transparent{ + color: transparent; +} + +.text-white{ + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} + +.text-zinc-100{ + --tw-text-opacity: 1; + color: rgb(244 244 245 / var(--tw-text-opacity, 1)); +} + +.text-zinc-200{ + --tw-text-opacity: 1; + color: rgb(228 228 231 / var(--tw-text-opacity, 1)); +} + +.text-zinc-400{ + --tw-text-opacity: 1; + color: rgb(161 161 170 / var(--tw-text-opacity, 1)); +} + +.text-zinc-500{ + --tw-text-opacity: 1; + color: rgb(113 113 122 / var(--tw-text-opacity, 1)); +} + +.text-zinc-600{ + --tw-text-opacity: 1; + color: rgb(82 82 91 / var(--tw-text-opacity, 1)); +} + +.text-zinc-700{ + --tw-text-opacity: 1; + color: rgb(63 63 70 / var(--tw-text-opacity, 1)); +} + +.text-zinc-800{ + --tw-text-opacity: 1; + color: rgb(39 39 42 / var(--tw-text-opacity, 1)); +} + +.text-zinc-900{ + --tw-text-opacity: 1; + color: rgb(24 24 27 / var(--tw-text-opacity, 1)); +} + +.underline{ + text-decoration-line: underline; +} + +.no-underline{ + text-decoration-line: none; +} + +.underline-offset-4{ + text-underline-offset: 4px; +} + +.antialiased{ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.opacity-0{ + opacity: 0; +} + +.opacity-100{ + opacity: 1; +} + +.opacity-60{ + opacity: 0.6; +} + +.opacity-70{ + opacity: 0.7; +} + +.opacity-90{ + opacity: 0.9; +} + +.mix-blend-exclusion{ + mix-blend-mode: exclusion; +} + +.shadow{ + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-2xl{ + --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); + --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-md{ + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-sm{ + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-zinc-950\/20{ + --tw-shadow-color: rgb(9 9 11 / 0.2); + --tw-shadow: var(--tw-shadow-colored); +} + +.drop-shadow-md{ + --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.backdrop-blur-sm{ + --tw-backdrop-blur: blur(4px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.transition{ + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-colors{ + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.duration-100{ + transition-duration: 100ms; +} + +.duration-150{ + transition-duration: 150ms; +} + +.duration-200{ + transition-duration: 200ms; +} + +.duration-300{ + transition-duration: 300ms; +} + +.duration-500{ + transition-duration: 500ms; +} + +.duration-700{ + transition-duration: 700ms; +} + +.ease-in{ + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +} + +.ease-in-out{ + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.ease-out{ + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} + +@media screen and (prefers-reduced-motion: no-preference){ + @keyframes motion-scale-in{ + 0%{ + scale: var(--motion-origin-scale-x) var(--motion-origin-scale-y); + } + + 100%{ + scale: 1 1; + } + } + + @keyframes motion-scale-out{ + 0%{ + scale: 1 1; + } + + 100%{ + scale: var(--motion-end-scale-x) var(--motion-end-scale-y); + } + } + + @keyframes motion-translate-in{ + 0%{ + translate: var(--motion-origin-translate-x) var(--motion-origin-translate-y); + } + + 100%{ + translate: 0 0; + } + } + + @keyframes motion-translate-out{ + 0%{ + translate: 0 0; + } + + 100%{ + translate: var(--motion-end-translate-x) var(--motion-end-translate-y); + } + } + + @keyframes motion-rotate-in{ + 0%{ + rotate: var(--motion-origin-rotate); + } + + 100%{ + rotate: 0; + } + } + + @keyframes motion-rotate-out{ + 0%{ + rotate: 0; + } + + 100%{ + rotate: var(--motion-end-rotate); + } + } +} + +@keyframes motion-filter-in{ + 0%{ + filter: blur(var(--motion-origin-blur)) grayscale(var(--motion-origin-grayscale)); + } + + 100%{ + filter: blur(0) grayscale(0); + } +} + +@keyframes motion-filter-out{ + 0%{ + filter: blur(0) grayscale(0); + } + + 100%{ + filter: blur(var(--motion-end-blur)) grayscale(var(--motion-end-grayscale)); + } +} + +@keyframes motion-opacity-in{ + 0%{ + opacity: var(--motion-origin-opacity); + } +} + +@keyframes motion-opacity-out{ + 100%{ + opacity: var(--motion-end-opacity); + } +} + +@keyframes motion-background-color-in{ + 0%{ + background-color: var(--motion-origin-background-color); + } +} + +@keyframes motion-background-color-out{ + 100%{ + background-color: var(--motion-end-background-color); + } +} + +@keyframes motion-text-color-in{ + 0%{ + color: var(--motion-origin-text-color); + } +} + +@keyframes motion-text-color-out{ + 100%{ + color: var(--motion-end-text-color); + } +} + +.motion-scale-in-50{ + --motion-origin-scale-x: .5; + --motion-origin-scale-y: .5; + --motion-scale-in-animation: motion-scale-in calc(var(--motion-scale-duration) * var(--motion-scale-perceptual-duration-multiplier)) var(--motion-scale-timing) var(--motion-scale-delay) both; + animation: var(--motion-all-enter-animations); +} + +.motion-opacity-in-0{ + --motion-origin-opacity: 0.001; + --motion-opacity-in-animation: motion-opacity-in calc(var(--motion-opacity-duration) * var(--motion-opacity-perceptual-duration-multiplier)) var(--motion-opacity-timing) var(--motion-opacity-delay) both; + animation: var(--motion-all-enter-animations); +} + +.\[animation-delay\:-7\.5s\]{ + animation-delay: -7.5s; +} + +.\[background\:linear-gradient\(\#2E2E32\2c \#2E2E32\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ + background: linear-gradient(#2E2E32,#2E2E32) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; +} + +.\[background\:linear-gradient\(\#323237\2c \#323237\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ + background: linear-gradient(#323237,#323237) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; +} + +.\[background\:linear-gradient\(theme\(colors\.white\)\2c theme\(colors\.white\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ + background: linear-gradient(#fff,#fff) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; +} + +.\[background\:linear-gradient\(theme\(colors\.white\)\2c theme\(colors\.zinc\.50\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ + background: linear-gradient(#fff,#fafafa) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; +} + +.\[background\:linear-gradient\(theme\(colors\.zinc\.50\)\2c theme\(colors\.zinc\.50\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ + background: linear-gradient(#fafafa,#fafafa) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; +} + +.\[background\:linear-gradient\(theme\(colors\.zinc\.800\)\2c theme\(colors\.zinc\.800\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ + background: linear-gradient(#27272a,#27272a) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; +} + +.\[mask-image\:_linear-gradient\(to_right\2c transparent_0\2c _black_28\%\2c _black_calc\(100\%-28\%\)\2c transparent_100\%\)\]{ + -webkit-mask-image: linear-gradient(to right,transparent 0, black 28%, black calc(100% - 28%),transparent 100%); + mask-image: linear-gradient(to right,transparent 0, black 28%, black calc(100% - 28%),transparent 100%); +} + +.\[mask-image\:linear-gradient\(to_right\2c transparent_8px\2c _theme\(colors\.white\/\.7\)_64px\2c _theme\(colors\.white\)_50\%\2c _theme\(colors\.white\/\.7\)_calc\(100\%-64px\)\2c _transparent_calc\(100\%-8px\)\)\]{ + -webkit-mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); + mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); +} + +/* See Alpine.js: https://github.com/alpinejs/alpine#x-cloak */ + +[x-cloak=""] { + display: none; +} + +/* Custom styles */ + +.form-input:focus, +.form-textarea:focus, +.form-multiselect:focus, +.form-select:focus, +.form-checkbox:focus, +.form-radio:focus{ + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +/* Hamburger button */ + +.hamburger svg > *:nth-child(1), +.hamburger svg > *:nth-child(2), +.hamburger svg > *:nth-child(3) { + transform-origin: center; + transform: rotate(0deg); +} + +.hamburger svg > *:nth-child(1) { + transition: + y 0.1s 0.25s ease-in, + transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), + opacity 0.1s ease-in; +} + +.hamburger svg > *:nth-child(2) { + transition: transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19); +} + +.hamburger svg > *:nth-child(3) { + transition: + y 0.1s 0.25s ease-in, + transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), + width 0.1s 0.25s ease-in; +} + +.hamburger.active svg > *:nth-child(1) { + opacity: 0; + y: 11; + transform: rotate(225deg); + transition: + y 0.1s ease-out, + transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), + opacity 0.1s 0.12s ease-out; +} + +.hamburger.active svg > *:nth-child(2) { + transform: rotate(225deg); + transition: transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1); +} + +.hamburger.active svg > *:nth-child(3) { + y: 11; + transform: rotate(135deg); + transition: + y 0.1s ease-out, + transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), + width 0.1s ease-out; +} + +/* Typography */ + +.h1{ + font-size: 3.25rem; + line-height: 1.2; + letter-spacing: -0.017em; + font-weight: 700; +} + +.h2{ + font-size: 2.5rem; + line-height: 1.25; + letter-spacing: -0.017em; + font-weight: 700; +} + +.h3{ + font-size: 2rem; + line-height: 1.3125; + letter-spacing: -0.017em; + font-weight: 700; +} + +.h4{ + font-size: 1.5rem; + line-height: 1.415; + letter-spacing: -0.017em; + font-weight: 700; +} + +@media (min-width: 768px) { + .h1{ + font-size: 3.75rem; + line-height: 1.1666; + letter-spacing: -0.017em; + } + + .h2{ + font-size: 3.25rem; + line-height: 1.2; + letter-spacing: -0.017em; + } + + .h3{ + font-size: 2.5rem; + line-height: 1.25; + letter-spacing: -0.017em; + } +} + +/* Buttons */ + +.btn, +.btn-sm{ + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: 0.375rem; + border-width: 1px; + border-color: transparent; + font-size: 0.875rem; + line-height: 1.5715; + font-weight: 500; + letter-spacing: 0em; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.btn{ + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.btn-sm{ + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +/* Forms */ + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-results-button, +input[type="search"]::-webkit-search-results-decoration { + -webkit-appearance: none; +} + +.form-input, +.form-textarea, +.form-multiselect, +.form-select, +.form-checkbox, +.form-radio{ + border-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(228 228 231 / var(--tw-border-opacity, 1)); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-color: rgb(0 0 0 / 0.05); + --tw-shadow: var(--tw-shadow-colored); +} + +.form-input:focus, +.form-textarea:focus, +.form-multiselect:focus, +.form-select:focus, +.form-checkbox:focus, +.form-radio:focus{ + --tw-border-opacity: 1; + border-color: rgb(161 161 170 / var(--tw-border-opacity, 1)); +} + +.form-input, +.form-textarea, +.form-multiselect, +.form-select, +.form-checkbox{ + border-radius: 0.25rem; +} + +.form-input, +.form-textarea, +.form-multiselect, +.form-select{ + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: 0.875rem; + line-height: 1.5715; + --tw-text-opacity: 1; + color: rgb(82 82 91 / var(--tw-text-opacity, 1)); +} + +.form-input::-moz-placeholder, .form-textarea::-moz-placeholder{ + --tw-placeholder-opacity: 1; + color: rgb(161 161 170 / var(--tw-placeholder-opacity, 1)); +} + +.form-input::placeholder, +.form-textarea::placeholder{ + --tw-placeholder-opacity: 1; + color: rgb(161 161 170 / var(--tw-placeholder-opacity, 1)); +} + +.form-select{ + padding-right: 2.5rem; +} + +.form-checkbox, +.form-radio{ + --tw-text-opacity: 1; + color: rgb(39 39 42 / var(--tw-text-opacity, 1)); +} + +.form-checkbox{ + border-radius: 0.125rem; +} + +/* Chrome, Safari and Opera */ + +.no-scrollbar::-webkit-scrollbar { + display: none; +} + +.no-scrollbar { + -ms-overflow-style: none; + /* IE and Edge */ + scrollbar-width: none; + /* Firefox */ +} + +.placeholder\:text-neutral-500::-moz-placeholder{ + --tw-text-opacity: 1; + color: rgb(115 115 115 / var(--tw-text-opacity, 1)); +} + +.placeholder\:text-neutral-500::placeholder{ + --tw-text-opacity: 1; + color: rgb(115 115 115 / var(--tw-text-opacity, 1)); +} + +.placeholder\:text-zinc-400::-moz-placeholder{ + --tw-text-opacity: 1; + color: rgb(161 161 170 / var(--tw-text-opacity, 1)); +} + +.placeholder\:text-zinc-400::placeholder{ + --tw-text-opacity: 1; + color: rgb(161 161 170 / var(--tw-text-opacity, 1)); +} + +.before\:pointer-events-none::before{ + content: var(--tw-content); + pointer-events: none; +} + +.before\:absolute::before{ + content: var(--tw-content); + position: absolute; +} + +.before\:inset-0::before{ + content: var(--tw-content); + inset: 0px; +} + +.before\:-top-12::before{ + content: var(--tw-content); + top: -3rem; +} + +.before\:-z-10::before{ + content: var(--tw-content); + z-index: -10; +} + +.before\:h-52::before{ + content: var(--tw-content); + height: 13rem; +} + +.before\:h-80::before{ + content: var(--tw-content); + height: 20rem; +} + +.before\:h-96::before{ + content: var(--tw-content); + height: 24rem; +} + +.before\:w-52::before{ + content: var(--tw-content); + width: 13rem; +} + +.before\:w-96::before{ + content: var(--tw-content); + width: 24rem; +} + +.before\:rounded-full::before{ + content: var(--tw-content); + border-radius: 9999px; +} + +.before\:bg-zinc-900::before{ + content: var(--tw-content); + --tw-bg-opacity: 1; + background-color: rgb(24 24 27 / var(--tw-bg-opacity, 1)); +} + +.before\:bg-gradient-to-b::before{ + content: var(--tw-content); + background-image: linear-gradient(to bottom, var(--tw-gradient-stops)); +} + +.before\:from-zinc-100::before{ + content: var(--tw-content); + --tw-gradient-from: #f4f4f5 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(244 244 245 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.before\:opacity-\[\.08\]::before{ + content: var(--tw-content); + opacity: .08; +} + +.before\:opacity-\[\.15\]::before{ + content: var(--tw-content); + opacity: .15; +} + +.before\:blur-3xl::before{ + content: var(--tw-content); + --tw-blur: blur(64px); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.before\:content-\[\'\\0022\'\]::before{ + --tw-content: '\0022'; + content: var(--tw-content); +} + +.after\:pointer-events-none::after{ + content: var(--tw-content); + pointer-events: none; +} + +.after\:absolute::after{ + content: var(--tw-content); + position: absolute; +} + +.after\:right-0::after{ + content: var(--tw-content); + right: 0px; +} + +.after\:top-0::after{ + content: var(--tw-content); + top: 0px; +} + +.after\:top-1\/2::after{ + content: var(--tw-content); + top: 50%; +} + +.after\:hidden::after{ + content: var(--tw-content); + display: none; +} + +.after\:h-8::after{ + content: var(--tw-content); + height: 2rem; +} + +.after\:h-full::after{ + content: var(--tw-content); + height: 100%; +} + +.after\:w-96::after{ + content: var(--tw-content); + width: 24rem; +} + +.after\:w-px::after{ + content: var(--tw-content); + width: 1px; +} + +.after\:-translate-y-1\/2::after{ + content: var(--tw-content); + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.after\:border-l::after{ + content: var(--tw-content); + border-left-width: 1px; +} + +.after\:border-dashed::after{ + content: var(--tw-content); + border-style: dashed; +} + +.after\:border-zinc-300::after{ + content: var(--tw-content); + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); +} + +.after\:bg-gradient-to-l::after{ + content: var(--tw-content); + background-image: linear-gradient(to left, var(--tw-gradient-stops)); +} + +.after\:from-zinc-800::after{ + content: var(--tw-content); + --tw-gradient-from: #27272a var(--tw-gradient-from-position); + --tw-gradient-to: rgb(39 39 42 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.after\:content-\[\'\\0022\'\]::after{ + --tw-content: '\0022'; + content: var(--tw-content); +} + +.last\:after\:hidden:last-child::after{ + content: var(--tw-content); + display: none; +} + +.hover\:bg-neutral-100:hover{ + --tw-bg-opacity: 1; + background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-neutral-800:hover{ + --tw-bg-opacity: 1; + background-color: rgb(38 38 38 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-neutral-900:hover{ + --tw-bg-opacity: 1; + background-color: rgb(23 23 23 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-zinc-200:hover{ + --tw-bg-opacity: 1; + background-color: rgb(228 228 231 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-zinc-50:hover{ + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-zinc-800:hover{ + --tw-bg-opacity: 1; + background-color: rgb(39 39 42 / var(--tw-bg-opacity, 1)); +} + +.hover\:text-neutral-900:hover{ + --tw-text-opacity: 1; + color: rgb(23 23 23 / var(--tw-text-opacity, 1)); +} + +.hover\:text-white:hover{ + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} + +.hover\:text-zinc-300:hover{ + --tw-text-opacity: 1; + color: rgb(212 212 216 / var(--tw-text-opacity, 1)); +} + +.hover\:text-zinc-800:hover{ + --tw-text-opacity: 1; + color: rgb(39 39 42 / var(--tw-text-opacity, 1)); +} + +.hover\:text-zinc-900:hover{ + --tw-text-opacity: 1; + color: rgb(24 24 27 / var(--tw-text-opacity, 1)); +} + +.hover\:underline:hover{ + text-decoration-line: underline; +} + +.hover\:opacity-100:hover{ + opacity: 1; +} + +.focus\:border-neutral-300:focus{ + --tw-border-opacity: 1; + border-color: rgb(212 212 212 / var(--tw-border-opacity, 1)); +} + +.focus\:border-zinc-300:focus{ + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); +} + +.focus\:no-underline:focus{ + text-decoration-line: none; +} + +.focus\:outline-none:focus{ + outline: 2px solid transparent; + outline-offset: 2px; +} + +.focus\:ring-2:focus{ + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.focus\:ring-neutral-100:focus{ + --tw-ring-opacity: 1; + --tw-ring-color: rgb(245 245 245 / var(--tw-ring-opacity, 1)); +} + +.focus\:ring-neutral-400:focus{ + --tw-ring-opacity: 1; + --tw-ring-color: rgb(163 163 163 / var(--tw-ring-opacity, 1)); +} + +.focus\:ring-neutral-900:focus{ + --tw-ring-opacity: 1; + --tw-ring-color: rgb(23 23 23 / var(--tw-ring-opacity, 1)); +} + +.focus\:ring-offset-2:focus{ + --tw-ring-offset-width: 2px; +} + +.focus-visible\:outline-none:focus-visible{ + outline: 2px solid transparent; + outline-offset: 2px; +} + +.focus-visible\:ring-2:focus-visible{ + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.focus-visible\:ring-offset-2:focus-visible{ + --tw-ring-offset-width: 2px; +} + +.disabled\:pointer-events-none:disabled{ + pointer-events: none; +} + +.disabled\:cursor-not-allowed:disabled{ + cursor: not-allowed; +} + +.disabled\:opacity-50:disabled{ + opacity: 0.5; +} + +.group:hover .group-hover\:w-full{ + width: 100%; +} + +.group:hover .group-hover\:-rotate-6{ + --tw-rotate: -6deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:scale-150{ + --tw-scale-x: 1.5; + --tw-scale-y: 1.5; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:opacity-100{ + opacity: 1; +} + +.group:hover .group-hover\:\[animation-play-state\:paused\]{ + animation-play-state: paused; +} + +.peer:disabled ~ .peer-disabled\:cursor-not-allowed{ + cursor: not-allowed; +} + +.peer:disabled ~ .peer-disabled\:opacity-70{ + opacity: 0.7; +} + +@supports (overflow:clip){ + .supports-\[overflow\:clip\]\:overflow-clip{ + overflow: clip; + } +} + +@media not all and (min-width: 1024px){ + .max-lg\:w-32{ + width: 8rem; + } + + .max-lg\:after\:hidden::after{ + content: var(--tw-content); + display: none; + } +} + +@media not all and (min-width: 640px){ + .max-sm\:order-1{ + order: 1; + } +} + +@media (min-width: 640px){ + .sm\:col-span-2{ + grid-column: span 2 / span 2; + } + + .sm\:col-span-6{ + grid-column: span 6 / span 6; + } + + .sm\:mb-0{ + margin-bottom: 0px; + } + + .sm\:inline-flex{ + display: inline-flex; + } + + .sm\:h-auto{ + height: auto; + } + + .sm\:max-w-lg{ + max-width: 32rem; + } + + .sm\:max-w-none{ + max-width: none; + } + + .sm\:grid-cols-12{ + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + + .sm\:grid-cols-2{ + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .sm\:flex-row{ + flex-direction: row; + } + + .sm\:justify-center{ + justify-content: center; + } + + .sm\:justify-between{ + justify-content: space-between; + } + + .sm\:gap-4{ + gap: 1rem; + } + + .sm\:space-x-2 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); + } + + .sm\:space-x-4 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); + } + + .sm\:space-y-0 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0px * var(--tw-space-y-reverse)); + } + + .sm\:rounded-lg{ + border-radius: 0.5rem; + } + + .sm\:object-contain{ + -o-object-fit: contain; + object-fit: contain; + } + + .sm\:px-6{ + padding-left: 1.5rem; + padding-right: 1.5rem; + } +} + +@media (min-width: 768px){ + .md\:top-6{ + top: 1.5rem; + } + + .md\:col-span-3{ + grid-column: span 3 / span 3; + } + + .md\:-mx-5{ + margin-left: -1.25rem; + margin-right: -1.25rem; + } + + .md\:mb-0{ + margin-bottom: 0px; + } + + .md\:max-w-none{ + max-width: none; + } + + .md\:grid-cols-3{ + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .md\:grid-cols-4{ + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .md\:flex-row{ + flex-direction: row; + } + + .md\:justify-start{ + justify-content: flex-start; + } + + .md\:gap-0{ + gap: 0px; + } + + .md\:gap-4{ + gap: 1rem; + } + + .md\:gap-6{ + gap: 1.5rem; + } + + .md\:px-5{ + padding-left: 1.25rem; + padding-right: 1.25rem; + } + + .md\:py-12{ + padding-top: 3rem; + padding-bottom: 3rem; + } + + .md\:py-20{ + padding-top: 5rem; + padding-bottom: 5rem; + } + + .md\:pb-16{ + padding-bottom: 4rem; + } + + .md\:pb-20{ + padding-bottom: 5rem; + } + + .md\:pt-40{ + padding-top: 10rem; + } + + .md\:text-3xl{ + font-size: 2rem; + line-height: 1.3125; + letter-spacing: -0.017em; + } + + .md\:text-4xl{ + font-size: 2.5rem; + line-height: 1.25; + letter-spacing: -0.017em; + } + + .md\:text-5xl{ + font-size: 3.25rem; + line-height: 1.2; + letter-spacing: -0.017em; + } + + .md\:after\:block::after{ + content: var(--tw-content); + display: block; + } +} + +@media (min-width: 1024px){ + .lg\:col-span-2{ + grid-column: span 2 / span 2; + } + + .lg\:col-span-6{ + grid-column: span 6 / span 6; + } + + .lg\:mb-0{ + margin-bottom: 0px; + } + + .lg\:mt-32{ + margin-top: 8rem; + } + + .lg\:block{ + display: block; + } + + .lg\:flex{ + display: flex; + } + + .lg\:h-5{ + height: 1.25rem; + } + + .lg\:min-w-\[524px\]{ + min-width: 524px; + } + + .lg\:max-w-6xl{ + max-width: 72rem; + } + + .lg\:max-w-none{ + max-width: none; + } + + .lg\:grid-cols-3{ + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .lg\:gap-16{ + gap: 4rem; + } + + .lg\:gap-8{ + gap: 2rem; + } + + .lg\:space-x-12 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(3rem * var(--tw-space-x-reverse)); + margin-left: calc(3rem * calc(1 - var(--tw-space-x-reverse))); + } + + .lg\:space-y-0 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0px * var(--tw-space-y-reverse)); + } + + .lg\:p-24{ + padding: 6rem; + } + + .lg\:px-5{ + padding-left: 1.25rem; + padding-right: 1.25rem; + } + + .lg\:text-2xl{ + font-size: 1.5rem; + line-height: 1.415; + letter-spacing: -0.017em; + } + + .lg\:text-3xl{ + font-size: 2rem; + line-height: 1.3125; + letter-spacing: -0.017em; + } + + .lg\:text-xl{ + font-size: 1.25rem; + line-height: 1.5; + letter-spacing: -0.017em; + } +} + +@media (min-width: 1280px){ + .xl\:space-x-24 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(6rem * var(--tw-space-x-reverse)); + margin-left: calc(6rem * calc(1 - var(--tw-space-x-reverse))); + } +} + +.\[\&\>div\]\:mx-3>div{ + margin-left: 0.75rem; + margin-right: 0.75rem; +} + +.\[\&_\.active-breadcrumb\]\:font-medium .active-breadcrumb{ + font-weight: 500; +} + +.\[\&_\.active-breadcrumb\]\:text-neutral-600 .active-breadcrumb{ + --tw-text-opacity: 1; + color: rgb(82 82 82 / var(--tw-text-opacity, 1)); +} diff --git a/pkg/webapp/bun.lockb b/pkg/webapp/bun.lockb index 8f3a1229b7226e632aa1c3f292150fd125c37edc..4320dae9ef164aad2f36ec0f70a35dccd745dbf6 100755 GIT binary patch delta 6519 zcmeHLdsJ0b8bA90!a+sB3s<=E7DJND+Y6x_>X?P?mX1UD9sa znvPmN8q;YgYmt*KO`8XfjiF7=64RX4)T+!L)67^-IKS^ajMccBHS^!B)n4m&zWdwf z+xz?W_wC2Id)pr0eSeZS+Y?I0y9$<_K6m&J@$u(lMqRiOT5)jIc)!gR&%8FU>8HNG zD17pOq?Id*qyus&%-plIVT4+g;X`&XwPFNoXh0~BDAg>w?s%x9;>z24$ zm%3|K)HJoZx4=3%5W~mIksYhiCylqIuGQ5BKO0w46eMYWpg!)l+L|UZlW*{8kTlGC zw8PI%Ef~;`KoǾ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 literal 119323 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 diff --git a/pkg/webapp/components/styles/styles.css b/pkg/webapp/components/styles/styles.css new file mode 100644 index 000000000..2e3888049 --- /dev/null +++ b/pkg/webapp/components/styles/styles.css @@ -0,0 +1,3503 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500&family=Inter+Tight:ital,wght@0,500;0,600;0,700;1,700&display=fallback"); + +/* src/css/styles.css */ + +*, ::before, ::after{ + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; + --motion-origin-scale-x: 1; + --motion-origin-scale-y: 1; + --motion-origin-translate-x: 0; + --motion-origin-translate-y: 0; + --motion-origin-rotate: 0; + --motion-origin-blur: 0; + --motion-origin-grayscale: 0; + --motion-origin-opacity: 1; + --motion-origin-background-color: ; + --motion-origin-text-color: ; + --motion-end-scale-x: 1; + --motion-end-scale-y: 1; + --motion-end-translate-x: 0; + --motion-end-translate-y: 0; + --motion-end-rotate: 0; + --motion-end-blur: 0; + --motion-end-grayscale: 0; + --motion-end-opacity: 1; + --motion-end-background-color: ; + --motion-end-text-color: ; + --motion-duration: 750ms; + --motion-timing: var(--motion-default-timing); + --motion-perceptual-duration-multiplier: 1; + --motion-delay: 0ms; + --motion-scale-duration: var(--motion-duration); + --motion-scale-timing: var(--motion-timing); + --motion-scale-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-scale-delay: var(--motion-delay); + --motion-translate-duration: var(--motion-duration); + --motion-translate-timing: var(--motion-timing); + --motion-translate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-translate-delay: var(--motion-delay); + --motion-rotate-duration: var(--motion-duration); + --motion-rotate-timing: var(--motion-timing); + --motion-rotate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-rotate-delay: var(--motion-delay); + --motion-filter-duration: var(--motion-duration); + --motion-filter-timing: var(--motion-timing); + --motion-filter-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-filter-delay: var(--motion-delay); + --motion-opacity-duration: var(--motion-duration); + --motion-opacity-timing: var(--motion-timing); + --motion-opacity-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-opacity-delay: var(--motion-delay); + --motion-background-color-duration: var(--motion-duration); + --motion-background-color-timing: var(--motion-timing); + --motion-background-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-background-color-delay: var(--motion-delay); + --motion-text-color-duration: var(--motion-duration); + --motion-text-color-timing: var(--motion-timing); + --motion-text-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-text-color-delay: var(--motion-delay); + --motion-scale-in-animation: none; + --motion-translate-in-animation: none; + --motion-rotate-in-animation: none; + --motion-filter-in-animation: none; + --motion-opacity-in-animation: none; + --motion-background-color-in-animation: none; + --motion-text-color-in-animation: none; + --motion-scale-out-animation: none; + --motion-translate-out-animation: none; + --motion-rotate-out-animation: none; + --motion-filter-out-animation: none; + --motion-opacity-out-animation: none; + --motion-background-color-out-animation: none; + --motion-text-color-out-animation: none; + --motion-all-enter-animations: var(--motion-scale-in-animation), var(--motion-translate-in-animation), var(--motion-rotate-in-animation), var(--motion-filter-in-animation), var(--motion-opacity-in-animation), var(--motion-background-color-in-animation), var(--motion-text-color-in-animation); + --motion-all-exit-animations: var(--motion-scale-out-animation), var(--motion-translate-out-animation), var(--motion-rotate-out-animation), var(--motion-filter-out-animation), var(--motion-opacity-out-animation), var(--motion-background-color-out-animation), var(--motion-text-color-out-animation); +} + +::backdrop{ + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; + --motion-origin-scale-x: 1; + --motion-origin-scale-y: 1; + --motion-origin-translate-x: 0; + --motion-origin-translate-y: 0; + --motion-origin-rotate: 0; + --motion-origin-blur: 0; + --motion-origin-grayscale: 0; + --motion-origin-opacity: 1; + --motion-origin-background-color: ; + --motion-origin-text-color: ; + --motion-end-scale-x: 1; + --motion-end-scale-y: 1; + --motion-end-translate-x: 0; + --motion-end-translate-y: 0; + --motion-end-rotate: 0; + --motion-end-blur: 0; + --motion-end-grayscale: 0; + --motion-end-opacity: 1; + --motion-end-background-color: ; + --motion-end-text-color: ; + --motion-duration: 750ms; + --motion-timing: var(--motion-default-timing); + --motion-perceptual-duration-multiplier: 1; + --motion-delay: 0ms; + --motion-scale-duration: var(--motion-duration); + --motion-scale-timing: var(--motion-timing); + --motion-scale-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-scale-delay: var(--motion-delay); + --motion-translate-duration: var(--motion-duration); + --motion-translate-timing: var(--motion-timing); + --motion-translate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-translate-delay: var(--motion-delay); + --motion-rotate-duration: var(--motion-duration); + --motion-rotate-timing: var(--motion-timing); + --motion-rotate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-rotate-delay: var(--motion-delay); + --motion-filter-duration: var(--motion-duration); + --motion-filter-timing: var(--motion-timing); + --motion-filter-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-filter-delay: var(--motion-delay); + --motion-opacity-duration: var(--motion-duration); + --motion-opacity-timing: var(--motion-timing); + --motion-opacity-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-opacity-delay: var(--motion-delay); + --motion-background-color-duration: var(--motion-duration); + --motion-background-color-timing: var(--motion-timing); + --motion-background-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-background-color-delay: var(--motion-delay); + --motion-text-color-duration: var(--motion-duration); + --motion-text-color-timing: var(--motion-timing); + --motion-text-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); + --motion-text-color-delay: var(--motion-delay); + --motion-scale-in-animation: none; + --motion-translate-in-animation: none; + --motion-rotate-in-animation: none; + --motion-filter-in-animation: none; + --motion-opacity-in-animation: none; + --motion-background-color-in-animation: none; + --motion-text-color-in-animation: none; + --motion-scale-out-animation: none; + --motion-translate-out-animation: none; + --motion-rotate-out-animation: none; + --motion-filter-out-animation: none; + --motion-opacity-out-animation: none; + --motion-background-color-out-animation: none; + --motion-text-color-out-animation: none; + --motion-all-enter-animations: var(--motion-scale-in-animation), var(--motion-translate-in-animation), var(--motion-rotate-in-animation), var(--motion-filter-in-animation), var(--motion-opacity-in-animation), var(--motion-background-color-in-animation), var(--motion-text-color-in-animation); + --motion-all-exit-animations: var(--motion-scale-out-animation), var(--motion-translate-out-animation), var(--motion-rotate-out-animation), var(--motion-filter-out-animation), var(--motion-opacity-out-animation), var(--motion-background-color-out-animation), var(--motion-text-color-out-animation); +} + +/* ! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com */ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS +*/ + +html, +:host { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + -webkit-tap-highlight-color: transparent; + /* 7 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-feature-settings: normal; + /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + letter-spacing: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +input:where([type='button']), +input:where([type='reset']), +input:where([type='submit']) { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden]:where(:not([hidden="until-found"])) { + display: none; +} + +[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select{ + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + border-radius: 0px; + padding-top: 0.5rem; + padding-right: 0.75rem; + padding-bottom: 0.5rem; + padding-left: 0.75rem; + font-size: 1rem; + line-height: 1.5rem; + --tw-shadow: 0 0 #0000; +} + +[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus{ + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + border-color: #2563eb; +} + +input::-moz-placeholder, textarea::-moz-placeholder{ + color: #6b7280; + opacity: 1; +} + +input::placeholder,textarea::placeholder{ + color: #6b7280; + opacity: 1; +} + +::-webkit-datetime-edit-fields-wrapper{ + padding: 0; +} + +::-webkit-date-and-time-value{ + min-height: 1.5em; + text-align: inherit; +} + +::-webkit-datetime-edit{ + display: inline-flex; +} + +::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{ + padding-top: 0; + padding-bottom: 0; +} + +select{ + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); + background-position: right 0.5rem center; + background-repeat: no-repeat; + background-size: 1.5em 1.5em; + padding-right: 2.5rem; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; +} + +[multiple],[size]:where(select:not([size="1"])){ + background-image: initial; + background-position: initial; + background-repeat: unset; + background-size: initial; + padding-right: 0.75rem; + -webkit-print-color-adjust: unset; + print-color-adjust: unset; +} + +[type='checkbox'],[type='radio']{ + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding: 0; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + display: inline-block; + vertical-align: middle; + background-origin: border-box; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + flex-shrink: 0; + height: 1rem; + width: 1rem; + color: #2563eb; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + --tw-shadow: 0 0 #0000; +} + +[type='checkbox']{ + border-radius: 0px; +} + +[type='radio']{ + border-radius: 100%; +} + +[type='checkbox']:focus,[type='radio']:focus{ + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); +} + +[type='checkbox']:checked,[type='radio']:checked{ + border-color: transparent; + background-color: currentColor; + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; +} + +[type='checkbox']:checked{ + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); +} + +@media (forced-colors: active) { + [type='checkbox']:checked{ + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='radio']:checked{ + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); +} + +@media (forced-colors: active) { + [type='radio']:checked{ + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus{ + border-color: transparent; + background-color: currentColor; +} + +[type='checkbox']:indeterminate{ + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); + border-color: transparent; + background-color: currentColor; + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; +} + +@media (forced-colors: active) { + [type='checkbox']:indeterminate{ + -webkit-appearance: auto; + -moz-appearance: auto; + appearance: auto; + } +} + +[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus{ + border-color: transparent; + background-color: currentColor; +} + +[type='file']{ + background: unset; + border-color: inherit; + border-width: 0; + border-radius: 0; + padding: 0; + font-size: unset; + line-height: inherit; +} + +[type='file']:focus{ + outline: 1px solid ButtonText; + outline: 1px auto -webkit-focus-ring-color; +} + +:root{ + --motion-default-timing: cubic-bezier(.165, .84, .44, 1); + --motion-bounce: linear(0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141 13.6%, 0.25, 0.391, 0.563, 0.765,1, 0.891 40.9%, 0.848, 0.813, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785,0.813, 0.848, 0.891 68.2%, 1 72.7%, 0.973, 0.953, 0.941, 0.938, 0.941, 0.953,0.973, 1, 0.988, 0.984, 0.988, 1); + --motion-spring-smooth: linear(0, 0.001 0.44%, 0.0045 0.94%, 0.0195 2.03%, 0.0446 3.19%, 0.0811 4.5%, 0.1598 6.82%, 0.3685 12.34%, 0.4693 15.17%, 0.5663, 0.6498 21.27%, 0.7215 24.39%, 0.7532 25.98%, 0.7829 27.65%, 0.8105, 0.8349 31.14%, 0.8573 32.95%, 0.8776 34.84%, 0.8964 36.87%, 0.9136 39.05%, 0.929 41.37%, 0.9421 43.77%, 0.9537 46.38%, 0.9636 49.14%, 0.9789 55.31%, 0.9888 62.35%, 0.9949 71.06%, 0.9982 82.52%, 0.9997 99.94%); + --motion-spring-snappy: linear(0, 0.0014, 0.0053 1.02%, 0.0126, 0.0227 2.18%, 0.0517 3.41%, 0.094 4.79%, 0.1865 7.26%, 0.4182 12.77%, 0.5246 15.46%, 0.6249, 0.7112, 0.7831 23.95%, 0.8146 25.4%, 0.844, 0.8699 28.45%, 0.8935, 0.9139 31.64%, 0.932, 0.9473, 0.9601 36.65%, 0.9714 38.47%, 0.9808 40.35%, 0.9948 44.49%, 1.0031 49.43%, 1.0057 53.35%, 1.0063 58.14%, 1.0014 80.78%, 1.0001 99.94%); + --motion-spring-bouncy: linear(0, 0.0018, 0.0069, 0.0151 1.74%, 0.0277 2.4%, 0.062 3.7%, 0.1115 5.15%, 0.2211 7.77%, 0.4778 13.21%, 0.5912 15.75%, 0.6987 18.44%, 0.7862 20.98%, 0.861 23.59%, 0.8926, 0.9205, 0.945 27.51%, 0.9671 28.89%, 0.9868, 1.003 31.79%, 1.0224 34.11%, 1.0358 36.58%, 1.0436 39.27%, 1.046 42.31%, 1.0446 44.71%, 1.0406 47.47%, 1.0118 61.84%, 1.0027 69.53%, 0.9981 80.49%, 0.9991 99.94%); + --motion-spring-bouncier: linear(0, 0.0023, 0.0088, 0.0194 1.59%, 0.035 2.17%, 0.078 3.33%, 0.1415 4.64%, 0.2054 5.75%, 0.2821 6.95%, 0.5912 11.45%, 0.7205 13.43%, 0.8393 15.45%, 0.936 17.39%, 0.9778, 1.015, 1.0477, 1.0759, 1.0998 22.22%, 1.1203, 1.1364, 1.1484 25.26%, 1.1586 26.61%, 1.1629 28.06%, 1.1613 29.56%, 1.1537 31.2%, 1.1434 32.6%, 1.1288 34.19%, 1.0508 41.29%, 1.0174 44.87%, 1.0025 46.89%, 0.9911 48.87%, 0.9826 50.9%, 0.9769 53.03%, 0.9735 56.02%, 0.9748 59.45%, 0.9964 72.64%, 1.0031 79.69%, 1.0042 86.83%, 1.0008 99.97%); + --motion-spring-bounciest: linear(0, 0.0032, 0.0131, 0.0294, 0.0524, 0.0824, 0.1192 1.54%, 0.2134 2.11%, 0.3102 2.59%, 0.4297 3.13%, 0.8732 4.95%, 1.0373, 1.1827 6.36%, 1.2972 7.01%, 1.3444, 1.3859, 1.4215, 1.4504, 1.4735, 1.4908, 1.5024, 1.5084 9.5%, 1.5091, 1.5061, 1.4993, 1.4886, 1.4745, 1.4565 11.11%, 1.4082 11.7%, 1.3585 12.2%, 1.295 12.77%, 1.0623 14.64%, 0.9773, 0.9031 16.08%, 0.8449 16.73%, 0.8014, 0.7701 17.95%, 0.7587, 0.7501, 0.7443, 0.7412 19.16%, 0.7421 19.68%, 0.7508 20.21%, 0.7672 20.77%, 0.7917 21.37%, 0.8169 21.87%, 0.8492 22.43%, 0.9681 24.32%, 1.0114, 1.0492 25.75%, 1.0789 26.41%, 1.1008, 1.1167, 1.1271, 1.1317 28.81%, 1.1314, 1.1271 29.87%, 1.1189 30.43%, 1.1063 31.03%, 1.0769 32.11%, 0.9941 34.72%, 0.9748 35.43%, 0.9597 36.09%, 0.9487, 0.9407, 0.9355, 0.933 38.46%, 0.9344 39.38%, 0.9421 40.38%, 0.9566 41.5%, 0.9989 44.12%, 1.0161 45.37%, 1.029 46.75%, 1.0341 48.1%, 1.0335 49.04%, 1.0295 50.05%, 1.0221 51.18%, 0.992 55.02%, 0.9854 56.38%, 0.9827 57.72%, 0.985 59.73%, 1.004 64.67%, 1.0088 67.34%, 1.0076 69.42%, 0.9981 74.28%, 0.9956 76.85%, 0.9961 79.06%, 1.0023 86.46%, 0.999 95.22%, 0.9994 100%); +} + +.container{ + width: 100%; +} + +@media (min-width: 640px){ + .container{ + max-width: 640px; + } +} + +@media (min-width: 768px){ + .container{ + max-width: 768px; + } +} + +@media (min-width: 1024px){ + .container{ + max-width: 1024px; + } +} + +@media (min-width: 1280px){ + .container{ + max-width: 1280px; + } +} + +@media (min-width: 1536px){ + .container{ + max-width: 1536px; + } +} + +.motion-preset-slide-up{ + --motion-origin-translate-y: 25%; + --motion-origin-opacity: 0; + --motion-opacity-in-animation: motion-opacity-in calc(var(--motion-opacity-duration) * var(--motion-opacity-perceptual-duration-multiplier)) var(--motion-opacity-timing) var(--motion-opacity-delay) both; + --motion-translate-in-animation: motion-translate-in calc(var(--motion-translate-duration) * var(--motion-translate-perceptual-duration-multiplier)) var(--motion-translate-timing) var(--motion-translate-delay) both; + animation: var(--motion-all-enter-animations); +} + +@keyframes RomboConfettiPop{ + 0%{ + opacity: 0; + transform: scale(1); + } + + 33%{ + opacity: 1; + transform: scale(1.15); + } + + 50%{ + transform: scale(0.975); + } + + 65%{ + transform: scale(1.025); + } + + 80%{ + transform: scale(0.99); + } + + 87%{ + transform: scale(1.01); + } + + 100%{ + opacity: 1; + transform: scale(1); + } +} + +@keyframes topfetti{ + 0%{ + background-position: 5% 90%, 10% 90%, 10% 90%, 15% 90%, 25% 90%, 25% 90%, 40% 90%, 55% 90%, 70% 90%; + } + + 50%{ + background-position: 0% 80%, 0% 20%, 10% 40%, 20% 0%, 30% 30%, 22% 50%, 50% 50%, 65% 20%, 90% 30%; + } + + 100%{ + background-position: 0% 70%, 0% 10%, 10% 30%, 20% -10%, 30% 20%, 22% 40%, 50% 40%, 65% 10%, 90% 20%; + background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; + } +} + +@keyframes bottomfetti{ + 0%{ + background-position: 10% -10%, 30% 10%, 55% -10%, 70% -10%, 85% -10%,70% -10%, 70% 0%; + } + + 50%{ + background-position: 0% 80%, 20% 80%, 45% 60%, 60% 100%, 75% 70%, 95% 60%, 105% 0%; + } + + 100%{ + background-position: 0% 90%, 20% 90%, 45% 70%, 60% 110%, 75% 80%, 95% 70%, 110% 10%; + background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; + } +} + +.fixed{ + position: fixed; +} + +.absolute{ + position: absolute; +} + +.relative{ + position: relative; +} + +.inset-0{ + inset: 0px; +} + +.bottom-0{ + bottom: 0px; +} + +.left-0{ + left: 0px; +} + +.left-1\/2{ + left: 50%; +} + +.right-0{ + right: 0px; +} + +.top-0{ + top: 0px; +} + +.top-2{ + top: 0.5rem; +} + +.-z-10{ + z-index: -10; +} + +.z-10{ + z-index: 10; +} + +.z-20{ + z-index: 20; +} + +.z-30{ + z-index: 30; +} + +.z-40{ + z-index: 40; +} + +.z-50{ + z-index: 50; +} + +.z-\[99\]{ + z-index: 99; +} + +.order-first{ + order: -9999; +} + +.-m-2{ + margin: -0.5rem; +} + +.m-2{ + margin: 0.5rem; +} + +.mx-auto{ + margin-left: auto; + margin-right: auto; +} + +.mb-1{ + margin-bottom: 0.25rem; +} + +.mb-2{ + margin-bottom: 0.5rem; +} + +.mb-3{ + margin-bottom: 0.75rem; +} + +.mb-4{ + margin-bottom: 1rem; +} + +.mb-6{ + margin-bottom: 1.5rem; +} + +.mb-8{ + margin-bottom: 2rem; +} + +.ml-1{ + margin-left: 0.25rem; +} + +.ml-2{ + margin-left: 0.5rem; +} + +.ml-3{ + margin-left: 0.75rem; +} + +.mr-1{ + margin-right: 0.25rem; +} + +.mr-2{ + margin-right: 0.5rem; +} + +.mr-3{ + margin-right: 0.75rem; +} + +.mr-4{ + margin-right: 1rem; +} + +.mr-5{ + margin-right: 1.25rem; +} + +.mr-7{ + margin-right: 1.75rem; +} + +.mt-1{ + margin-top: 0.25rem; +} + +.mt-12{ + margin-top: 3rem; +} + +.mt-2{ + margin-top: 0.5rem; +} + +.mt-24{ + margin-top: 6rem; +} + +.mt-4{ + margin-top: 1rem; +} + +.mt-5{ + margin-top: 1.25rem; +} + +.mt-6{ + margin-top: 1.5rem; +} + +.box-content{ + box-sizing: content-box; +} + +.block{ + display: block; +} + +.flex{ + display: flex; +} + +.inline-flex{ + display: inline-flex; +} + +.grid{ + display: grid; +} + +.hidden{ + display: none; +} + +.h-0\.5{ + height: 0.125rem; +} + +.h-10{ + height: 2.5rem; +} + +.h-14{ + height: 3.5rem; +} + +.h-20{ + height: 5rem; +} + +.h-3{ + height: 0.75rem; +} + +.h-32{ + height: 8rem; +} + +.h-4{ + height: 1rem; +} + +.h-5{ + height: 1.25rem; +} + +.h-8{ + height: 2rem; +} + +.h-9{ + height: 2.25rem; +} + +.h-\[280px\]{ + height: 280px; +} + +.h-auto{ + height: auto; +} + +.h-full{ + height: 100%; +} + +.h-screen{ + height: 100vh; +} + +.min-h-screen{ + min-height: 100vh; +} + +.w-0{ + width: 0px; +} + +.w-1\/3{ + width: 33.333333%; +} + +.w-14{ + width: 3.5rem; +} + +.w-16{ + width: 4rem; +} + +.w-20{ + width: 5rem; +} + +.w-3{ + width: 0.75rem; +} + +.w-4{ + width: 1rem; +} + +.w-5{ + width: 1.25rem; +} + +.w-8{ + width: 2rem; +} + +.w-\[22rem\]{ + width: 22rem; +} + +.w-\[365px\]{ + width: 365px; +} + +.w-\[calc\(100\%\+1rem\)\]{ + width: calc(100% + 1rem); +} + +.w-\[full\]{ + width: full; +} + +.w-auto{ + width: auto; +} + +.w-fit{ + width: -moz-fit-content; + width: fit-content; +} + +.w-full{ + width: 100%; +} + +.w-screen{ + width: 100vw; +} + +.max-w-2xl{ + max-width: 42rem; +} + +.max-w-3xl{ + max-width: 48rem; +} + +.max-w-4xl{ + max-width: 56rem; +} + +.max-w-5xl{ + max-width: 64rem; +} + +.max-w-6xl{ + max-width: 72rem; +} + +.max-w-\[94rem\]{ + max-width: 94rem; +} + +.max-w-lg{ + max-width: 32rem; +} + +.max-w-md{ + max-width: 28rem; +} + +.max-w-screen-sm{ + max-width: 640px; +} + +.max-w-sm{ + max-width: 24rem; +} + +.max-w-xl{ + max-width: 36rem; +} + +.max-w-xs{ + max-width: 20rem; +} + +.flex-shrink-0{ + flex-shrink: 0; +} + +.shrink-0{ + flex-shrink: 0; +} + +.grow{ + flex-grow: 1; +} + +.-translate-x-0{ + --tw-translate-x: -0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-1\/2{ + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-4{ + --tw-translate-x: -1rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-7{ + --tw-translate-x: -1.75rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-8{ + --tw-translate-x: -2rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-x-px{ + --tw-translate-x: -1px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-y-4{ + --tw-translate-y: -1rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.-translate-y-px{ + --tw-translate-y: -1px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-x-0{ + --tw-translate-x: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-x-8{ + --tw-translate-x: 2rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-0{ + --tw-translate-y: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-1\/3{ + --tw-translate-y: 33.333333%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-24{ + --tw-translate-y: 6rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-3{ + --tw-translate-y: 0.75rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-4{ + --tw-translate-y: 1rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.rotate-1{ + --tw-rotate: 1deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.scale-100{ + --tw-scale-x: 1; + --tw-scale-y: 1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.scale-90{ + --tw-scale-x: .9; + --tw-scale-y: .9; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.transform{ + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes infinite-scroll{ + from{ + transform: translateX(0); + } + + to{ + transform: translateX(-100%); + } +} + +.animate-infinite-scroll{ + animation: infinite-scroll 60s linear infinite; +} + +@keyframes infinite-scroll-inverse{ + from{ + transform: translateX(-100%); + } + + to{ + transform: translateX(0); + } +} + +.animate-infinite-scroll-inverse{ + animation: infinite-scroll-inverse 60s linear infinite; +} + +.cursor-default{ + cursor: default; +} + +.cursor-pointer{ + cursor: pointer; +} + +.grid-cols-2{ + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.flex-row{ + flex-direction: row; +} + +.flex-col{ + flex-direction: column; +} + +.flex-col-reverse{ + flex-direction: column-reverse; +} + +.flex-wrap{ + flex-wrap: wrap; +} + +.flex-nowrap{ + flex-wrap: nowrap; +} + +.items-start{ + align-items: flex-start; +} + +.items-end{ + align-items: flex-end; +} + +.items-center{ + align-items: center; +} + +.justify-end{ + justify-content: flex-end; +} + +.justify-center{ + justify-content: center; +} + +.justify-between{ + justify-content: space-between; +} + +.gap-12{ + gap: 3rem; +} + +.gap-2{ + gap: 0.5rem; +} + +.gap-3{ + gap: 0.75rem; +} + +.gap-4{ + gap: 1rem; +} + +.gap-8{ + gap: 2rem; +} + +.gap-x-3{ + -moz-column-gap: 0.75rem; + column-gap: 0.75rem; +} + +.gap-y-3{ + row-gap: 0.75rem; +} + +.space-x-1 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(0.25rem * var(--tw-space-x-reverse)); + margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-x-3 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(0.75rem * var(--tw-space-x-reverse)); + margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-x-4 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-y-1 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); +} + +.space-y-1\.5 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.375rem * var(--tw-space-y-reverse)); +} + +.space-y-12 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(3rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(3rem * var(--tw-space-y-reverse)); +} + +.space-y-2 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.space-y-4 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} + +.space-y-6 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); +} + +.overflow-hidden{ + overflow: hidden; +} + +.rounded{ + border-radius: 0.25rem; +} + +.rounded-full{ + border-radius: 9999px; +} + +.rounded-lg{ + border-radius: 0.5rem; +} + +.rounded-md{ + border-radius: 0.375rem; +} + +.rounded-xl{ + border-radius: 0.75rem; +} + +.rounded-t-lg{ + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; +} + +.border{ + border-width: 1px; +} + +.border-2{ + border-width: 2px; +} + +.border-\[2px\]{ + border-width: 2px; +} + +.border-t{ + border-top-width: 1px; +} + +.border-neutral-200\/60{ + border-color: rgb(229 229 229 / 0.6); +} + +.border-neutral-200\/70{ + border-color: rgb(229 229 229 / 0.7); +} + +.border-neutral-300{ + --tw-border-opacity: 1; + border-color: rgb(212 212 212 / var(--tw-border-opacity, 1)); +} + +.border-transparent{ + border-color: transparent; +} + +.border-white{ + --tw-border-opacity: 1; + border-color: rgb(255 255 255 / var(--tw-border-opacity, 1)); +} + +.border-zinc-200{ + --tw-border-opacity: 1; + border-color: rgb(228 228 231 / var(--tw-border-opacity, 1)); +} + +.border-zinc-300{ + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); +} + +.border-zinc-600{ + --tw-border-opacity: 1; + border-color: rgb(82 82 91 / var(--tw-border-opacity, 1)); +} + +.bg-blue-600{ + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)); +} + +.bg-neutral-50{ + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); +} + +.bg-neutral-900{ + --tw-bg-opacity: 1; + background-color: rgb(23 23 23 / var(--tw-bg-opacity, 1)); +} + +.bg-neutral-950{ + --tw-bg-opacity: 1; + background-color: rgb(10 10 10 / var(--tw-bg-opacity, 1)); +} + +.bg-transparent{ + background-color: transparent; +} + +.bg-white{ + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); +} + +.bg-zinc-100{ + --tw-bg-opacity: 1; + background-color: rgb(244 244 245 / var(--tw-bg-opacity, 1)); +} + +.bg-zinc-50{ + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); +} + +.bg-zinc-800{ + --tw-bg-opacity: 1; + background-color: rgb(39 39 42 / var(--tw-bg-opacity, 1)); +} + +.bg-zinc-900{ + --tw-bg-opacity: 1; + background-color: rgb(24 24 27 / var(--tw-bg-opacity, 1)); +} + +.bg-opacity-90{ + --tw-bg-opacity: 0.9; +} + +.bg-gradient-to-r{ + background-image: linear-gradient(to right, var(--tw-gradient-stops)); +} + +.bg-gradient-to-t{ + background-image: linear-gradient(to top, var(--tw-gradient-stops)); +} + +.from-black{ + --tw-gradient-from: #000 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.from-zinc-100{ + --tw-gradient-from: #f4f4f5 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(244 244 245 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.from-zinc-500{ + --tw-gradient-from: #71717a var(--tw-gradient-from-position); + --tw-gradient-to: rgb(113 113 122 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.via-zinc-900{ + --tw-gradient-to: rgb(24 24 27 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), #18181b var(--tw-gradient-via-position), var(--tw-gradient-to); +} + +.to-white{ + --tw-gradient-to: #fff var(--tw-gradient-to-position); +} + +.to-zinc-900{ + --tw-gradient-to: #18181b var(--tw-gradient-to-position); +} + +.bg-cover{ + background-size: cover; +} + +.bg-clip-text{ + -webkit-background-clip: text; + background-clip: text; +} + +.fill-current{ + fill: currentColor; +} + +.fill-zinc-300{ + fill: #d4d4d8; +} + +.fill-zinc-400{ + fill: #a1a1aa; +} + +.object-cover{ + -o-object-fit: cover; + object-fit: cover; +} + +.object-left{ + -o-object-position: left; + object-position: left; +} + +.p-1{ + padding: 0.25rem; +} + +.p-4{ + padding: 1rem; +} + +.p-5{ + padding: 1.25rem; +} + +.p-6{ + padding: 1.5rem; +} + +.p-7{ + padding: 1.75rem; +} + +.px-0\.5{ + padding-left: 0.125rem; + padding-right: 0.125rem; +} + +.px-2{ + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-2\.5{ + padding-left: 0.625rem; + padding-right: 0.625rem; +} + +.px-3{ + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-3\.5{ + padding-left: 0.875rem; + padding-right: 0.875rem; +} + +.px-4{ + padding-left: 1rem; + padding-right: 1rem; +} + +.px-5{ + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.px-6{ + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.px-7{ + padding-left: 1.75rem; + padding-right: 1.75rem; +} + +.px-8{ + padding-left: 2rem; + padding-right: 2rem; +} + +.py-0\.5{ + padding-top: 0.125rem; + padding-bottom: 0.125rem; +} + +.py-1{ + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-12{ + padding-top: 3rem; + padding-bottom: 3rem; +} + +.py-2{ + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.py-3{ + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.py-4{ + padding-top: 1rem; + padding-bottom: 1rem; +} + +.py-5{ + padding-top: 1.25rem; + padding-bottom: 1.25rem; +} + +.py-6{ + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +.py-8{ + padding-top: 2rem; + padding-bottom: 2rem; +} + +.py-px{ + padding-top: 1px; + padding-bottom: 1px; +} + +.pb-1{ + padding-bottom: 0.25rem; +} + +.pb-12{ + padding-bottom: 3rem; +} + +.pb-2{ + padding-bottom: 0.5rem; +} + +.pb-3{ + padding-bottom: 0.75rem; +} + +.pb-4{ + padding-bottom: 1rem; +} + +.pb-6{ + padding-bottom: 1.5rem; +} + +.pb-8{ + padding-bottom: 2rem; +} + +.pl-4{ + padding-left: 1rem; +} + +.pr-2{ + padding-right: 0.5rem; +} + +.pr-4{ + padding-right: 1rem; +} + +.pt-0{ + padding-top: 0px; +} + +.pt-2{ + padding-top: 0.5rem; +} + +.pt-32{ + padding-top: 8rem; +} + +.pt-6{ + padding-top: 1.5rem; +} + +.pt-8{ + padding-top: 2rem; +} + +.text-left{ + text-align: left; +} + +.text-center{ + text-align: center; +} + +.align-top{ + vertical-align: top; +} + +.font-inter{ + font-family: Inter, sans-serif; +} + +.font-inter-tight{ + font-family: Inter Tight, sans-serif; +} + +.font-sans{ + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} + +.text-2xl{ + font-size: 1.5rem; + line-height: 1.415; + letter-spacing: -0.017em; +} + +.text-3xl{ + font-size: 2rem; + line-height: 1.3125; + letter-spacing: -0.017em; +} + +.text-4xl{ + font-size: 2.5rem; + line-height: 1.25; + letter-spacing: -0.017em; +} + +.text-\[0\.6rem\]{ + font-size: 0.6rem; +} + +.text-base{ + font-size: 1rem; + line-height: 1.5; + letter-spacing: -0.017em; +} + +.text-lg{ + font-size: 1.125rem; + line-height: 1.5; + letter-spacing: -0.017em; +} + +.text-sm{ + font-size: 0.875rem; + line-height: 1.5715; +} + +.text-xl{ + font-size: 1.25rem; + line-height: 1.5; + letter-spacing: -0.017em; +} + +.text-xs{ + font-size: 0.75rem; + line-height: 1.5; +} + +.font-bold{ + font-weight: 700; +} + +.font-extrabold{ + font-weight: 800; +} + +.font-medium{ + font-weight: 500; +} + +.font-normal{ + font-weight: 400; +} + +.font-semibold{ + font-weight: 600; +} + +.uppercase{ + text-transform: uppercase; +} + +.italic{ + font-style: italic; +} + +.not-italic{ + font-style: normal; +} + +.tabular-nums{ + --tw-numeric-spacing: tabular-nums; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); +} + +.leading-none{ + line-height: 1; +} + +.tracking-tight{ + letter-spacing: -0.025em; +} + +.tracking-wide{ + letter-spacing: 0.025em; +} + +.text-blue-600{ + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity, 1)); +} + +.text-gray-400{ + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity, 1)); +} + +.text-gray-400\/70{ + color: rgb(156 163 175 / 0.7); +} + +.text-gray-500{ + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity, 1)); +} + +.text-gray-600{ + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity, 1)); +} + +.text-neutral-100{ + --tw-text-opacity: 1; + color: rgb(245 245 245 / var(--tw-text-opacity, 1)); +} + +.text-neutral-500{ + --tw-text-opacity: 1; + color: rgb(115 115 115 / var(--tw-text-opacity, 1)); +} + +.text-neutral-800{ + --tw-text-opacity: 1; + color: rgb(38 38 38 / var(--tw-text-opacity, 1)); +} + +.text-neutral-900{ + --tw-text-opacity: 1; + color: rgb(23 23 23 / var(--tw-text-opacity, 1)); +} + +.text-transparent{ + color: transparent; +} + +.text-white{ + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} + +.text-zinc-100{ + --tw-text-opacity: 1; + color: rgb(244 244 245 / var(--tw-text-opacity, 1)); +} + +.text-zinc-200{ + --tw-text-opacity: 1; + color: rgb(228 228 231 / var(--tw-text-opacity, 1)); +} + +.text-zinc-400{ + --tw-text-opacity: 1; + color: rgb(161 161 170 / var(--tw-text-opacity, 1)); +} + +.text-zinc-500{ + --tw-text-opacity: 1; + color: rgb(113 113 122 / var(--tw-text-opacity, 1)); +} + +.text-zinc-600{ + --tw-text-opacity: 1; + color: rgb(82 82 91 / var(--tw-text-opacity, 1)); +} + +.text-zinc-700{ + --tw-text-opacity: 1; + color: rgb(63 63 70 / var(--tw-text-opacity, 1)); +} + +.text-zinc-800{ + --tw-text-opacity: 1; + color: rgb(39 39 42 / var(--tw-text-opacity, 1)); +} + +.text-zinc-900{ + --tw-text-opacity: 1; + color: rgb(24 24 27 / var(--tw-text-opacity, 1)); +} + +.underline{ + text-decoration-line: underline; +} + +.no-underline{ + text-decoration-line: none; +} + +.underline-offset-4{ + text-underline-offset: 4px; +} + +.antialiased{ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.opacity-0{ + opacity: 0; +} + +.opacity-100{ + opacity: 1; +} + +.opacity-60{ + opacity: 0.6; +} + +.opacity-70{ + opacity: 0.7; +} + +.opacity-90{ + opacity: 0.9; +} + +.mix-blend-exclusion{ + mix-blend-mode: exclusion; +} + +.shadow{ + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-2xl{ + --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); + --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-md{ + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-sm{ + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-zinc-950\/20{ + --tw-shadow-color: rgb(9 9 11 / 0.2); + --tw-shadow: var(--tw-shadow-colored); +} + +.drop-shadow-md{ + --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.backdrop-blur-sm{ + --tw-backdrop-blur: blur(4px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.transition{ + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-colors{ + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.duration-100{ + transition-duration: 100ms; +} + +.duration-150{ + transition-duration: 150ms; +} + +.duration-200{ + transition-duration: 200ms; +} + +.duration-300{ + transition-duration: 300ms; +} + +.duration-500{ + transition-duration: 500ms; +} + +.duration-700{ + transition-duration: 700ms; +} + +.ease-in{ + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +} + +.ease-in-out{ + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.ease-out{ + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} + +@media screen and (prefers-reduced-motion: no-preference){ + @keyframes motion-scale-in{ + 0%{ + scale: var(--motion-origin-scale-x) var(--motion-origin-scale-y); + } + + 100%{ + scale: 1 1; + } + } + + @keyframes motion-scale-out{ + 0%{ + scale: 1 1; + } + + 100%{ + scale: var(--motion-end-scale-x) var(--motion-end-scale-y); + } + } + + @keyframes motion-translate-in{ + 0%{ + translate: var(--motion-origin-translate-x) var(--motion-origin-translate-y); + } + + 100%{ + translate: 0 0; + } + } + + @keyframes motion-translate-out{ + 0%{ + translate: 0 0; + } + + 100%{ + translate: var(--motion-end-translate-x) var(--motion-end-translate-y); + } + } + + @keyframes motion-rotate-in{ + 0%{ + rotate: var(--motion-origin-rotate); + } + + 100%{ + rotate: 0; + } + } + + @keyframes motion-rotate-out{ + 0%{ + rotate: 0; + } + + 100%{ + rotate: var(--motion-end-rotate); + } + } +} + +@keyframes motion-filter-in{ + 0%{ + filter: blur(var(--motion-origin-blur)) grayscale(var(--motion-origin-grayscale)); + } + + 100%{ + filter: blur(0) grayscale(0); + } +} + +@keyframes motion-filter-out{ + 0%{ + filter: blur(0) grayscale(0); + } + + 100%{ + filter: blur(var(--motion-end-blur)) grayscale(var(--motion-end-grayscale)); + } +} + +@keyframes motion-opacity-in{ + 0%{ + opacity: var(--motion-origin-opacity); + } +} + +@keyframes motion-opacity-out{ + 100%{ + opacity: var(--motion-end-opacity); + } +} + +@keyframes motion-background-color-in{ + 0%{ + background-color: var(--motion-origin-background-color); + } +} + +@keyframes motion-background-color-out{ + 100%{ + background-color: var(--motion-end-background-color); + } +} + +@keyframes motion-text-color-in{ + 0%{ + color: var(--motion-origin-text-color); + } +} + +@keyframes motion-text-color-out{ + 100%{ + color: var(--motion-end-text-color); + } +} + +.motion-scale-in-50{ + --motion-origin-scale-x: .5; + --motion-origin-scale-y: .5; + --motion-scale-in-animation: motion-scale-in calc(var(--motion-scale-duration) * var(--motion-scale-perceptual-duration-multiplier)) var(--motion-scale-timing) var(--motion-scale-delay) both; + animation: var(--motion-all-enter-animations); +} + +.motion-opacity-in-0{ + --motion-origin-opacity: 0.001; + --motion-opacity-in-animation: motion-opacity-in calc(var(--motion-opacity-duration) * var(--motion-opacity-perceptual-duration-multiplier)) var(--motion-opacity-timing) var(--motion-opacity-delay) both; + animation: var(--motion-all-enter-animations); +} + +.\[animation-delay\:-7\.5s\]{ + animation-delay: -7.5s; +} + +.\[background\:linear-gradient\(\#2E2E32\2c \#2E2E32\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ + background: linear-gradient(#2E2E32,#2E2E32) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; +} + +.\[background\:linear-gradient\(\#323237\2c \#323237\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ + background: linear-gradient(#323237,#323237) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; +} + +.\[background\:linear-gradient\(theme\(colors\.white\)\2c theme\(colors\.white\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ + background: linear-gradient(#fff,#fff) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; +} + +.\[background\:linear-gradient\(theme\(colors\.white\)\2c theme\(colors\.zinc\.50\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ + background: linear-gradient(#fff,#fafafa) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; +} + +.\[background\:linear-gradient\(theme\(colors\.zinc\.50\)\2c theme\(colors\.zinc\.50\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ + background: linear-gradient(#fafafa,#fafafa) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; +} + +.\[background\:linear-gradient\(theme\(colors\.zinc\.800\)\2c theme\(colors\.zinc\.800\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ + background: linear-gradient(#27272a,#27272a) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; +} + +.\[mask-image\:_linear-gradient\(to_right\2c transparent_0\2c _black_28\%\2c _black_calc\(100\%-28\%\)\2c transparent_100\%\)\]{ + -webkit-mask-image: linear-gradient(to right,transparent 0, black 28%, black calc(100% - 28%),transparent 100%); + mask-image: linear-gradient(to right,transparent 0, black 28%, black calc(100% - 28%),transparent 100%); +} + +.\[mask-image\:linear-gradient\(to_right\2c transparent_8px\2c _theme\(colors\.white\/\.7\)_64px\2c _theme\(colors\.white\)_50\%\2c _theme\(colors\.white\/\.7\)_calc\(100\%-64px\)\2c _transparent_calc\(100\%-8px\)\)\]{ + -webkit-mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); + mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); +} + +/* See Alpine.js: https://github.com/alpinejs/alpine#x-cloak */ + +[x-cloak=""] { + display: none; +} + +/* Custom styles */ + +.form-input:focus, +.form-textarea:focus, +.form-multiselect:focus, +.form-select:focus, +.form-checkbox:focus, +.form-radio:focus{ + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +/* Hamburger button */ + +.hamburger svg > *:nth-child(1), +.hamburger svg > *:nth-child(2), +.hamburger svg > *:nth-child(3) { + transform-origin: center; + transform: rotate(0deg); +} + +.hamburger svg > *:nth-child(1) { + transition: + y 0.1s 0.25s ease-in, + transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), + opacity 0.1s ease-in; +} + +.hamburger svg > *:nth-child(2) { + transition: transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19); +} + +.hamburger svg > *:nth-child(3) { + transition: + y 0.1s 0.25s ease-in, + transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), + width 0.1s 0.25s ease-in; +} + +.hamburger.active svg > *:nth-child(1) { + opacity: 0; + y: 11; + transform: rotate(225deg); + transition: + y 0.1s ease-out, + transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), + opacity 0.1s 0.12s ease-out; +} + +.hamburger.active svg > *:nth-child(2) { + transform: rotate(225deg); + transition: transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1); +} + +.hamburger.active svg > *:nth-child(3) { + y: 11; + transform: rotate(135deg); + transition: + y 0.1s ease-out, + transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), + width 0.1s ease-out; +} + +/* Typography */ + +.h1{ + font-size: 3.25rem; + line-height: 1.2; + letter-spacing: -0.017em; + font-weight: 700; +} + +.h2{ + font-size: 2.5rem; + line-height: 1.25; + letter-spacing: -0.017em; + font-weight: 700; +} + +.h3{ + font-size: 2rem; + line-height: 1.3125; + letter-spacing: -0.017em; + font-weight: 700; +} + +.h4{ + font-size: 1.5rem; + line-height: 1.415; + letter-spacing: -0.017em; + font-weight: 700; +} + +@media (min-width: 768px) { + .h1{ + font-size: 3.75rem; + line-height: 1.1666; + letter-spacing: -0.017em; + } + + .h2{ + font-size: 3.25rem; + line-height: 1.2; + letter-spacing: -0.017em; + } + + .h3{ + font-size: 2.5rem; + line-height: 1.25; + letter-spacing: -0.017em; + } +} + +/* Buttons */ + +.btn, +.btn-sm{ + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: 0.375rem; + border-width: 1px; + border-color: transparent; + font-size: 0.875rem; + line-height: 1.5715; + font-weight: 500; + letter-spacing: 0em; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.btn{ + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.btn-sm{ + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +/* Forms */ + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-results-button, +input[type="search"]::-webkit-search-results-decoration { + -webkit-appearance: none; +} + +.form-input, +.form-textarea, +.form-multiselect, +.form-select, +.form-checkbox, +.form-radio{ + border-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(228 228 231 / var(--tw-border-opacity, 1)); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-color: rgb(0 0 0 / 0.05); + --tw-shadow: var(--tw-shadow-colored); +} + +.form-input:focus, +.form-textarea:focus, +.form-multiselect:focus, +.form-select:focus, +.form-checkbox:focus, +.form-radio:focus{ + --tw-border-opacity: 1; + border-color: rgb(161 161 170 / var(--tw-border-opacity, 1)); +} + +.form-input, +.form-textarea, +.form-multiselect, +.form-select, +.form-checkbox{ + border-radius: 0.25rem; +} + +.form-input, +.form-textarea, +.form-multiselect, +.form-select{ + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: 0.875rem; + line-height: 1.5715; + --tw-text-opacity: 1; + color: rgb(82 82 91 / var(--tw-text-opacity, 1)); +} + +.form-input::-moz-placeholder, .form-textarea::-moz-placeholder{ + --tw-placeholder-opacity: 1; + color: rgb(161 161 170 / var(--tw-placeholder-opacity, 1)); +} + +.form-input::placeholder, +.form-textarea::placeholder{ + --tw-placeholder-opacity: 1; + color: rgb(161 161 170 / var(--tw-placeholder-opacity, 1)); +} + +.form-select{ + padding-right: 2.5rem; +} + +.form-checkbox, +.form-radio{ + --tw-text-opacity: 1; + color: rgb(39 39 42 / var(--tw-text-opacity, 1)); +} + +.form-checkbox{ + border-radius: 0.125rem; +} + +/* Chrome, Safari and Opera */ + +.no-scrollbar::-webkit-scrollbar { + display: none; +} + +.no-scrollbar { + -ms-overflow-style: none; + /* IE and Edge */ + scrollbar-width: none; + /* Firefox */ +} + +.placeholder\:text-neutral-500::-moz-placeholder{ + --tw-text-opacity: 1; + color: rgb(115 115 115 / var(--tw-text-opacity, 1)); +} + +.placeholder\:text-neutral-500::placeholder{ + --tw-text-opacity: 1; + color: rgb(115 115 115 / var(--tw-text-opacity, 1)); +} + +.placeholder\:text-zinc-400::-moz-placeholder{ + --tw-text-opacity: 1; + color: rgb(161 161 170 / var(--tw-text-opacity, 1)); +} + +.placeholder\:text-zinc-400::placeholder{ + --tw-text-opacity: 1; + color: rgb(161 161 170 / var(--tw-text-opacity, 1)); +} + +.before\:pointer-events-none::before{ + content: var(--tw-content); + pointer-events: none; +} + +.before\:absolute::before{ + content: var(--tw-content); + position: absolute; +} + +.before\:inset-0::before{ + content: var(--tw-content); + inset: 0px; +} + +.before\:-top-12::before{ + content: var(--tw-content); + top: -3rem; +} + +.before\:-z-10::before{ + content: var(--tw-content); + z-index: -10; +} + +.before\:h-52::before{ + content: var(--tw-content); + height: 13rem; +} + +.before\:h-80::before{ + content: var(--tw-content); + height: 20rem; +} + +.before\:h-96::before{ + content: var(--tw-content); + height: 24rem; +} + +.before\:w-52::before{ + content: var(--tw-content); + width: 13rem; +} + +.before\:w-96::before{ + content: var(--tw-content); + width: 24rem; +} + +.before\:rounded-full::before{ + content: var(--tw-content); + border-radius: 9999px; +} + +.before\:bg-zinc-900::before{ + content: var(--tw-content); + --tw-bg-opacity: 1; + background-color: rgb(24 24 27 / var(--tw-bg-opacity, 1)); +} + +.before\:bg-gradient-to-b::before{ + content: var(--tw-content); + background-image: linear-gradient(to bottom, var(--tw-gradient-stops)); +} + +.before\:from-zinc-100::before{ + content: var(--tw-content); + --tw-gradient-from: #f4f4f5 var(--tw-gradient-from-position); + --tw-gradient-to: rgb(244 244 245 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.before\:opacity-\[\.08\]::before{ + content: var(--tw-content); + opacity: .08; +} + +.before\:opacity-\[\.15\]::before{ + content: var(--tw-content); + opacity: .15; +} + +.before\:blur-3xl::before{ + content: var(--tw-content); + --tw-blur: blur(64px); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +.before\:content-\[\'\\0022\'\]::before{ + --tw-content: '\0022'; + content: var(--tw-content); +} + +.after\:pointer-events-none::after{ + content: var(--tw-content); + pointer-events: none; +} + +.after\:absolute::after{ + content: var(--tw-content); + position: absolute; +} + +.after\:right-0::after{ + content: var(--tw-content); + right: 0px; +} + +.after\:top-0::after{ + content: var(--tw-content); + top: 0px; +} + +.after\:top-1\/2::after{ + content: var(--tw-content); + top: 50%; +} + +.after\:hidden::after{ + content: var(--tw-content); + display: none; +} + +.after\:h-8::after{ + content: var(--tw-content); + height: 2rem; +} + +.after\:h-full::after{ + content: var(--tw-content); + height: 100%; +} + +.after\:w-96::after{ + content: var(--tw-content); + width: 24rem; +} + +.after\:w-px::after{ + content: var(--tw-content); + width: 1px; +} + +.after\:-translate-y-1\/2::after{ + content: var(--tw-content); + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.after\:border-l::after{ + content: var(--tw-content); + border-left-width: 1px; +} + +.after\:border-dashed::after{ + content: var(--tw-content); + border-style: dashed; +} + +.after\:border-zinc-300::after{ + content: var(--tw-content); + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); +} + +.after\:bg-gradient-to-l::after{ + content: var(--tw-content); + background-image: linear-gradient(to left, var(--tw-gradient-stops)); +} + +.after\:from-zinc-800::after{ + content: var(--tw-content); + --tw-gradient-from: #27272a var(--tw-gradient-from-position); + --tw-gradient-to: rgb(39 39 42 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.after\:content-\[\'\\0022\'\]::after{ + --tw-content: '\0022'; + content: var(--tw-content); +} + +.last\:after\:hidden:last-child::after{ + content: var(--tw-content); + display: none; +} + +.hover\:bg-neutral-100:hover{ + --tw-bg-opacity: 1; + background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-neutral-800:hover{ + --tw-bg-opacity: 1; + background-color: rgb(38 38 38 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-neutral-900:hover{ + --tw-bg-opacity: 1; + background-color: rgb(23 23 23 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-zinc-200:hover{ + --tw-bg-opacity: 1; + background-color: rgb(228 228 231 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-zinc-50:hover{ + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); +} + +.hover\:bg-zinc-800:hover{ + --tw-bg-opacity: 1; + background-color: rgb(39 39 42 / var(--tw-bg-opacity, 1)); +} + +.hover\:text-neutral-900:hover{ + --tw-text-opacity: 1; + color: rgb(23 23 23 / var(--tw-text-opacity, 1)); +} + +.hover\:text-white:hover{ + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} + +.hover\:text-zinc-300:hover{ + --tw-text-opacity: 1; + color: rgb(212 212 216 / var(--tw-text-opacity, 1)); +} + +.hover\:text-zinc-800:hover{ + --tw-text-opacity: 1; + color: rgb(39 39 42 / var(--tw-text-opacity, 1)); +} + +.hover\:text-zinc-900:hover{ + --tw-text-opacity: 1; + color: rgb(24 24 27 / var(--tw-text-opacity, 1)); +} + +.hover\:underline:hover{ + text-decoration-line: underline; +} + +.hover\:opacity-100:hover{ + opacity: 1; +} + +.focus\:border-neutral-300:focus{ + --tw-border-opacity: 1; + border-color: rgb(212 212 212 / var(--tw-border-opacity, 1)); +} + +.focus\:border-zinc-300:focus{ + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); +} + +.focus\:no-underline:focus{ + text-decoration-line: none; +} + +.focus\:outline-none:focus{ + outline: 2px solid transparent; + outline-offset: 2px; +} + +.focus\:ring-2:focus{ + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.focus\:ring-neutral-100:focus{ + --tw-ring-opacity: 1; + --tw-ring-color: rgb(245 245 245 / var(--tw-ring-opacity, 1)); +} + +.focus\:ring-neutral-400:focus{ + --tw-ring-opacity: 1; + --tw-ring-color: rgb(163 163 163 / var(--tw-ring-opacity, 1)); +} + +.focus\:ring-neutral-900:focus{ + --tw-ring-opacity: 1; + --tw-ring-color: rgb(23 23 23 / var(--tw-ring-opacity, 1)); +} + +.focus\:ring-offset-2:focus{ + --tw-ring-offset-width: 2px; +} + +.focus-visible\:outline-none:focus-visible{ + outline: 2px solid transparent; + outline-offset: 2px; +} + +.focus-visible\:ring-2:focus-visible{ + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.focus-visible\:ring-offset-2:focus-visible{ + --tw-ring-offset-width: 2px; +} + +.disabled\:pointer-events-none:disabled{ + pointer-events: none; +} + +.disabled\:cursor-not-allowed:disabled{ + cursor: not-allowed; +} + +.disabled\:opacity-50:disabled{ + opacity: 0.5; +} + +.group:hover .group-hover\:w-full{ + width: 100%; +} + +.group:hover .group-hover\:-rotate-6{ + --tw-rotate: -6deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:scale-150{ + --tw-scale-x: 1.5; + --tw-scale-y: 1.5; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.group:hover .group-hover\:opacity-100{ + opacity: 1; +} + +.group:hover .group-hover\:\[animation-play-state\:paused\]{ + animation-play-state: paused; +} + +.peer:disabled ~ .peer-disabled\:cursor-not-allowed{ + cursor: not-allowed; +} + +.peer:disabled ~ .peer-disabled\:opacity-70{ + opacity: 0.7; +} + +@supports (overflow:clip){ + .supports-\[overflow\:clip\]\:overflow-clip{ + overflow: clip; + } +} + +@media not all and (min-width: 1024px){ + .max-lg\:w-32{ + width: 8rem; + } + + .max-lg\:after\:hidden::after{ + content: var(--tw-content); + display: none; + } +} + +@media not all and (min-width: 640px){ + .max-sm\:order-1{ + order: 1; + } +} + +@media (min-width: 640px){ + .sm\:col-span-2{ + grid-column: span 2 / span 2; + } + + .sm\:col-span-6{ + grid-column: span 6 / span 6; + } + + .sm\:mb-0{ + margin-bottom: 0px; + } + + .sm\:inline-flex{ + display: inline-flex; + } + + .sm\:h-auto{ + height: auto; + } + + .sm\:max-w-lg{ + max-width: 32rem; + } + + .sm\:max-w-none{ + max-width: none; + } + + .sm\:grid-cols-12{ + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + + .sm\:grid-cols-2{ + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .sm\:flex-row{ + flex-direction: row; + } + + .sm\:justify-center{ + justify-content: center; + } + + .sm\:justify-between{ + justify-content: space-between; + } + + .sm\:gap-4{ + gap: 1rem; + } + + .sm\:space-x-2 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); + } + + .sm\:space-x-4 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); + } + + .sm\:space-y-0 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0px * var(--tw-space-y-reverse)); + } + + .sm\:rounded-lg{ + border-radius: 0.5rem; + } + + .sm\:object-contain{ + -o-object-fit: contain; + object-fit: contain; + } + + .sm\:px-6{ + padding-left: 1.5rem; + padding-right: 1.5rem; + } +} + +@media (min-width: 768px){ + .md\:top-6{ + top: 1.5rem; + } + + .md\:col-span-3{ + grid-column: span 3 / span 3; + } + + .md\:-mx-5{ + margin-left: -1.25rem; + margin-right: -1.25rem; + } + + .md\:mb-0{ + margin-bottom: 0px; + } + + .md\:max-w-none{ + max-width: none; + } + + .md\:grid-cols-3{ + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .md\:grid-cols-4{ + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .md\:flex-row{ + flex-direction: row; + } + + .md\:justify-start{ + justify-content: flex-start; + } + + .md\:gap-0{ + gap: 0px; + } + + .md\:gap-4{ + gap: 1rem; + } + + .md\:gap-6{ + gap: 1.5rem; + } + + .md\:px-5{ + padding-left: 1.25rem; + padding-right: 1.25rem; + } + + .md\:py-12{ + padding-top: 3rem; + padding-bottom: 3rem; + } + + .md\:py-20{ + padding-top: 5rem; + padding-bottom: 5rem; + } + + .md\:pb-16{ + padding-bottom: 4rem; + } + + .md\:pb-20{ + padding-bottom: 5rem; + } + + .md\:pt-40{ + padding-top: 10rem; + } + + .md\:text-3xl{ + font-size: 2rem; + line-height: 1.3125; + letter-spacing: -0.017em; + } + + .md\:text-4xl{ + font-size: 2.5rem; + line-height: 1.25; + letter-spacing: -0.017em; + } + + .md\:text-5xl{ + font-size: 3.25rem; + line-height: 1.2; + letter-spacing: -0.017em; + } + + .md\:after\:block::after{ + content: var(--tw-content); + display: block; + } +} + +@media (min-width: 1024px){ + .lg\:col-span-2{ + grid-column: span 2 / span 2; + } + + .lg\:col-span-6{ + grid-column: span 6 / span 6; + } + + .lg\:mb-0{ + margin-bottom: 0px; + } + + .lg\:mt-32{ + margin-top: 8rem; + } + + .lg\:block{ + display: block; + } + + .lg\:flex{ + display: flex; + } + + .lg\:h-5{ + height: 1.25rem; + } + + .lg\:min-w-\[524px\]{ + min-width: 524px; + } + + .lg\:max-w-6xl{ + max-width: 72rem; + } + + .lg\:max-w-none{ + max-width: none; + } + + .lg\:grid-cols-3{ + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .lg\:gap-16{ + gap: 4rem; + } + + .lg\:gap-8{ + gap: 2rem; + } + + .lg\:space-x-12 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(3rem * var(--tw-space-x-reverse)); + margin-left: calc(3rem * calc(1 - var(--tw-space-x-reverse))); + } + + .lg\:space-y-0 > :not([hidden]) ~ :not([hidden]){ + --tw-space-y-reverse: 0; + margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0px * var(--tw-space-y-reverse)); + } + + .lg\:p-24{ + padding: 6rem; + } + + .lg\:px-5{ + padding-left: 1.25rem; + padding-right: 1.25rem; + } + + .lg\:text-2xl{ + font-size: 1.5rem; + line-height: 1.415; + letter-spacing: -0.017em; + } + + .lg\:text-3xl{ + font-size: 2rem; + line-height: 1.3125; + letter-spacing: -0.017em; + } + + .lg\:text-xl{ + font-size: 1.25rem; + line-height: 1.5; + letter-spacing: -0.017em; + } +} + +@media (min-width: 1280px){ + .xl\:space-x-24 > :not([hidden]) ~ :not([hidden]){ + --tw-space-x-reverse: 0; + margin-right: calc(6rem * var(--tw-space-x-reverse)); + margin-left: calc(6rem * calc(1 - var(--tw-space-x-reverse))); + } +} + +.\[\&\>div\]\:mx-3>div{ + margin-left: 0.75rem; + margin-right: 0.75rem; +} + +.\[\&_\.active-breadcrumb\]\:font-medium .active-breadcrumb{ + font-weight: 500; +} + +.\[\&_\.active-breadcrumb\]\:text-neutral-600 .active-breadcrumb{ + --tw-text-opacity: 1; + color: rgb(82 82 82 / var(--tw-text-opacity, 1)); +} diff --git a/proto/dwn/v1/genesis.proto b/proto/dwn/v1/genesis.proto index 5a8198483..86bce0067 100644 --- a/proto/dwn/v1/genesis.proto +++ b/proto/dwn/v1/genesis.proto @@ -11,6 +11,7 @@ message GenesisState { // Params defines all the parameters of the module. Params params = 1 [(gogoproto.nullable) = false]; } + // Params defines the set of module parameters. message Params { option (amino.name) = "vault/params"; @@ -22,6 +23,19 @@ message Params { Schema schema = 4; } +// Capability reprensents the available capabilities of a decentralized web node +message Capability { + string name = 1; + string description = 2; +} + +// Resource reprensents the available resources of a decentralized web node +message Resource { + string name = 1; + string description = 2; +} + +// Schema is the Database Model for Decentralized Web Nodes message Schema { int32 version = 1; string account = 2; diff --git a/scripts/init_env.sh b/scripts/init_env.sh index 236e666d2..1617e9d15 100755 --- a/scripts/init_env.sh +++ b/scripts/init_env.sh @@ -1,6 +1,7 @@ #!/bin/bash go install github.com/cosmos/gex@latest +go install github.com/apple/pkl-go/cmd/pkl-gen-go@latest rm -rf ~/.ipfs diff --git a/scripts/upload_pkl.sh b/scripts/upload_pkl.sh new file mode 100755 index 000000000..425a8fd05 --- /dev/null +++ b/scripts/upload_pkl.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -e + +ROOT_DIR=$(git rev-parse --show-toplevel) + +bunx pkl project package $ROOT_DIR/pkl/*/ + +for dir in .out/*/; do + folder=$(basename "$dir") + rclone copy "$dir" "r2:pkljar/$folder" +done + +rm -rf .out From e89bbb05b156c28de5bc88fb2211f8846eff7ece Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 26 Nov 2024 11:44:17 -0500 Subject: [PATCH 17/30] refactor: Deployment setup --- .gitignore | 2 + Makefile | 41 +- deploy/local/devbox.json | 4 +- devbox.json | 29 +- devbox.lock | 48 + pkg/webapp/components/styles/styles.css | 3503 ---------------------- pkg/webapp/{components => }/globals.css | 0 pkg/webapp/package.json | 2 +- scripts/{init_env.sh => ipfs_config.sh} | 2 - scripts/tailwindgen.sh | 17 + scripts/{upload_pkl.sh => upload_cdn.sh} | 3 + 11 files changed, 106 insertions(+), 3545 deletions(-) delete mode 100644 pkg/webapp/components/styles/styles.css rename pkg/webapp/{components => }/globals.css (100%) rename scripts/{init_env.sh => ipfs_config.sh} (94%) create mode 100755 scripts/tailwindgen.sh rename scripts/{upload_pkl.sh => upload_cdn.sh} (77%) diff --git a/.gitignore b/.gitignore index 77a37edf4..912ee974f 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ aof* dist **/.haptic +static +pkg/webapp/dist # Test binary *.test diff --git a/Makefile b/Makefile index e678ef498..37d9ab10d 100644 --- a/Makefile +++ b/Makefile @@ -262,6 +262,9 @@ ictest-tokenfactory: ### testnet ### ############################################################################### +setup-ipfs: + ./scripts/ipfs_config.sh + setup-testnet: mod-tidy is-localic-installed install local-image set-testnet-configs setup-testnet-keys # Run this before testnet keys are added @@ -291,25 +294,19 @@ sh-testnet: mod-tidy ############################################################################### ### generation ### ############################################################################### -.PHONY: buf-deploy pkl-gen tailwind-gen templ-gen - -buf-deploy: - cd ./proto && bunx buf dep update && bunx buf build && bunx buf push - -pkl-deploy: - sh ./scripts/upload_pkl.sh +.PHONY: pkl-gen styles-gen templ-gen pkl-gen: + go install github.com/apple/pkl-go/cmd/pkl-gen-go@latest pkl-gen-go pkl/base.types/Ctx.pkl pkl-gen-go pkl/base.types/DWN.pkl pkl-gen-go pkl/base.types/ORM.pkl -tailwind-gen: - cd ./pkg/webapp && bun install && bun run build - cp ./pkg/webapp/components/styles/styles.css ./cmd/hway/styles.css - rm -rf ./pkg/webapp/node_modules +styles-gen: + sh ./scripts/tailwindgen.sh templ-gen: + @go install github.com/a-h/templ/cmd/templ@latest templ generate @@ -318,15 +315,23 @@ templ-gen: ############################################################################### .PHONY: motr-build hway-build hway-serve -buf-deploy: +motr-build: + GOOS=js GOARCH=wasm go build -o static/wasm/app.wasm ./cmd/motr/main.go + +hway-build: styles-gen templ-gen + go build -o build/hway ./cmd/hway/main.go + + +############################################################################### +### help ### +############################################################################### +.PHONY: deploy-buf deploy-cdn + +deploy-buf: cd ./proto && bunx buf dep update && bunx buf build && bunx buf push - -motr-build: - GOOS=js GOARCH=wasm go build -o build/app.wasm ./cmd/motr/main.go - -hway-build: tailwind-gen templ-gen - go build -o build/hway ./cmd/hway/main.go +deploy-cdn: + sh ./scripts/upload_cdn.sh ############################################################################### diff --git a/deploy/local/devbox.json b/deploy/local/devbox.json index 7161a4296..00e5ad434 100644 --- a/deploy/local/devbox.json +++ b/deploy/local/devbox.json @@ -26,9 +26,9 @@ "init_hook": ["export ROOT=$(git rev-parse --show-toplevel)"], "scripts": { "devnet": ["cd $ROOT", "make sh-testnet"], - "ipfs": ["ipfs daemon"], + "ipfs": ["cd $ROOT", "make setup-ipfs", "ipfs daemon"], "air": ["cd $ROOT", "air"], - "gex": ["gex"] + "gex": ["go install github.com/cosmos/gex@latest", "gex"] } } } diff --git a/devbox.json b/devbox.json index fcc628a9c..e5649f070 100644 --- a/devbox.json +++ b/devbox.json @@ -1,32 +1,23 @@ { "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json", - "packages": [ - "go@1.22", - "bun@latest", - "ipfs@latest", - "templ@latest", - "gum@latest" - ], + "packages": ["go@1.22", "bun@latest", "gum@latest"], "env": { "GOPATH": "$HOME/go", "PATH": "./build:$HOME/go/bin:$PATH", "TEMPL_EXPERIMENT": "rawgo" }, "shell": { - "init_hook": [ - "./scripts/init_env.sh" - ], "scripts": { - "start-local": [ - "cd deploy/local && devbox services up" + "deploy-buf": ["gum spin --title='Deploying buf' -- make deploy-buf"], + "deploy-cdn": [ + "gum spin --title='Generating PKL' -- make pkl-gen", + "gum spin --title='Generating Styles' -- make styles-gen", + "gum spin --title='Building Motr WASM' -- make motr-build", + "gum spin --title='Uploading to Bucket' -- make deploy-cdn" ], - "start-testnet": [ - "cd deploy/testnet && devbox services up" - ], - "start-gex": [ - "go install github.com/cosmos/gex@latest", - "gex" - ] + "start-local": ["cd deploy/local && devbox services up"], + "start-testnet": ["cd deploy/testnet && devbox services up"], + "start-gex": ["go install github.com/cosmos/gex@latest", "gex"] } } } diff --git a/devbox.lock b/devbox.lock index d498be17a..86b5293ce 100644 --- a/devbox.lock +++ b/devbox.lock @@ -97,6 +97,54 @@ } } }, + "gum@latest": { + "last_modified": "2024-11-16T04:25:12Z", + "resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#gum", + "source": "devbox-search", + "version": "0.14.5", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/rzqm62ixipbzbhfagqlic5xxag9a2v82-gum-0.14.5", + "default": true + } + ], + "store_path": "/nix/store/rzqm62ixipbzbhfagqlic5xxag9a2v82-gum-0.14.5" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/3ick2j8z9jgkk3cyc1ik4zkbs3m4583n-gum-0.14.5", + "default": true + } + ], + "store_path": "/nix/store/3ick2j8z9jgkk3cyc1ik4zkbs3m4583n-gum-0.14.5" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/9rh8qxbxgb07v3a62mx9404ynk2yhxrj-gum-0.14.5", + "default": true + } + ], + "store_path": "/nix/store/9rh8qxbxgb07v3a62mx9404ynk2yhxrj-gum-0.14.5" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/1bnivwijzrnzx5h0hd5rywwy8rlhxmw5-gum-0.14.5", + "default": true + } + ], + "store_path": "/nix/store/1bnivwijzrnzx5h0hd5rywwy8rlhxmw5-gum-0.14.5" + } + } + }, "ipfs@latest": { "last_modified": "2023-02-24T09:01:09Z", "resolved": "github:NixOS/nixpkgs/7d0ed7f2e5aea07ab22ccb338d27fbe347ed2f11#ipfs", diff --git a/pkg/webapp/components/styles/styles.css b/pkg/webapp/components/styles/styles.css deleted file mode 100644 index 2e3888049..000000000 --- a/pkg/webapp/components/styles/styles.css +++ /dev/null @@ -1,3503 +0,0 @@ -@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500&family=Inter+Tight:ital,wght@0,500;0,600;0,700;1,700&display=fallback"); - -/* src/css/styles.css */ - -*, ::before, ::after{ - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; - --motion-origin-scale-x: 1; - --motion-origin-scale-y: 1; - --motion-origin-translate-x: 0; - --motion-origin-translate-y: 0; - --motion-origin-rotate: 0; - --motion-origin-blur: 0; - --motion-origin-grayscale: 0; - --motion-origin-opacity: 1; - --motion-origin-background-color: ; - --motion-origin-text-color: ; - --motion-end-scale-x: 1; - --motion-end-scale-y: 1; - --motion-end-translate-x: 0; - --motion-end-translate-y: 0; - --motion-end-rotate: 0; - --motion-end-blur: 0; - --motion-end-grayscale: 0; - --motion-end-opacity: 1; - --motion-end-background-color: ; - --motion-end-text-color: ; - --motion-duration: 750ms; - --motion-timing: var(--motion-default-timing); - --motion-perceptual-duration-multiplier: 1; - --motion-delay: 0ms; - --motion-scale-duration: var(--motion-duration); - --motion-scale-timing: var(--motion-timing); - --motion-scale-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-scale-delay: var(--motion-delay); - --motion-translate-duration: var(--motion-duration); - --motion-translate-timing: var(--motion-timing); - --motion-translate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-translate-delay: var(--motion-delay); - --motion-rotate-duration: var(--motion-duration); - --motion-rotate-timing: var(--motion-timing); - --motion-rotate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-rotate-delay: var(--motion-delay); - --motion-filter-duration: var(--motion-duration); - --motion-filter-timing: var(--motion-timing); - --motion-filter-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-filter-delay: var(--motion-delay); - --motion-opacity-duration: var(--motion-duration); - --motion-opacity-timing: var(--motion-timing); - --motion-opacity-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-opacity-delay: var(--motion-delay); - --motion-background-color-duration: var(--motion-duration); - --motion-background-color-timing: var(--motion-timing); - --motion-background-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-background-color-delay: var(--motion-delay); - --motion-text-color-duration: var(--motion-duration); - --motion-text-color-timing: var(--motion-timing); - --motion-text-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-text-color-delay: var(--motion-delay); - --motion-scale-in-animation: none; - --motion-translate-in-animation: none; - --motion-rotate-in-animation: none; - --motion-filter-in-animation: none; - --motion-opacity-in-animation: none; - --motion-background-color-in-animation: none; - --motion-text-color-in-animation: none; - --motion-scale-out-animation: none; - --motion-translate-out-animation: none; - --motion-rotate-out-animation: none; - --motion-filter-out-animation: none; - --motion-opacity-out-animation: none; - --motion-background-color-out-animation: none; - --motion-text-color-out-animation: none; - --motion-all-enter-animations: var(--motion-scale-in-animation), var(--motion-translate-in-animation), var(--motion-rotate-in-animation), var(--motion-filter-in-animation), var(--motion-opacity-in-animation), var(--motion-background-color-in-animation), var(--motion-text-color-in-animation); - --motion-all-exit-animations: var(--motion-scale-out-animation), var(--motion-translate-out-animation), var(--motion-rotate-out-animation), var(--motion-filter-out-animation), var(--motion-opacity-out-animation), var(--motion-background-color-out-animation), var(--motion-text-color-out-animation); -} - -::backdrop{ - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; - --motion-origin-scale-x: 1; - --motion-origin-scale-y: 1; - --motion-origin-translate-x: 0; - --motion-origin-translate-y: 0; - --motion-origin-rotate: 0; - --motion-origin-blur: 0; - --motion-origin-grayscale: 0; - --motion-origin-opacity: 1; - --motion-origin-background-color: ; - --motion-origin-text-color: ; - --motion-end-scale-x: 1; - --motion-end-scale-y: 1; - --motion-end-translate-x: 0; - --motion-end-translate-y: 0; - --motion-end-rotate: 0; - --motion-end-blur: 0; - --motion-end-grayscale: 0; - --motion-end-opacity: 1; - --motion-end-background-color: ; - --motion-end-text-color: ; - --motion-duration: 750ms; - --motion-timing: var(--motion-default-timing); - --motion-perceptual-duration-multiplier: 1; - --motion-delay: 0ms; - --motion-scale-duration: var(--motion-duration); - --motion-scale-timing: var(--motion-timing); - --motion-scale-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-scale-delay: var(--motion-delay); - --motion-translate-duration: var(--motion-duration); - --motion-translate-timing: var(--motion-timing); - --motion-translate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-translate-delay: var(--motion-delay); - --motion-rotate-duration: var(--motion-duration); - --motion-rotate-timing: var(--motion-timing); - --motion-rotate-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-rotate-delay: var(--motion-delay); - --motion-filter-duration: var(--motion-duration); - --motion-filter-timing: var(--motion-timing); - --motion-filter-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-filter-delay: var(--motion-delay); - --motion-opacity-duration: var(--motion-duration); - --motion-opacity-timing: var(--motion-timing); - --motion-opacity-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-opacity-delay: var(--motion-delay); - --motion-background-color-duration: var(--motion-duration); - --motion-background-color-timing: var(--motion-timing); - --motion-background-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-background-color-delay: var(--motion-delay); - --motion-text-color-duration: var(--motion-duration); - --motion-text-color-timing: var(--motion-timing); - --motion-text-color-perceptual-duration-multiplier: var(--motion-perceptual-duration-multiplier); - --motion-text-color-delay: var(--motion-delay); - --motion-scale-in-animation: none; - --motion-translate-in-animation: none; - --motion-rotate-in-animation: none; - --motion-filter-in-animation: none; - --motion-opacity-in-animation: none; - --motion-background-color-in-animation: none; - --motion-text-color-in-animation: none; - --motion-scale-out-animation: none; - --motion-translate-out-animation: none; - --motion-rotate-out-animation: none; - --motion-filter-out-animation: none; - --motion-opacity-out-animation: none; - --motion-background-color-out-animation: none; - --motion-text-color-out-animation: none; - --motion-all-enter-animations: var(--motion-scale-in-animation), var(--motion-translate-in-animation), var(--motion-rotate-in-animation), var(--motion-filter-in-animation), var(--motion-opacity-in-animation), var(--motion-background-color-in-animation), var(--motion-text-color-in-animation); - --motion-all-exit-animations: var(--motion-scale-out-animation), var(--motion-translate-out-animation), var(--motion-rotate-out-animation), var(--motion-filter-out-animation), var(--motion-opacity-out-animation), var(--motion-background-color-out-animation), var(--motion-text-color-out-animation); -} - -/* ! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com */ - -/* -1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) -2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) -*/ - -*, -::before, -::after { - box-sizing: border-box; - /* 1 */ - border-width: 0; - /* 2 */ - border-style: solid; - /* 2 */ - border-color: #e5e7eb; - /* 2 */ -} - -::before, -::after { - --tw-content: ''; -} - -/* -1. Use a consistent sensible line-height in all browsers. -2. Prevent adjustments of font size after orientation changes in iOS. -3. Use a more readable tab size. -4. Use the user's configured `sans` font-family by default. -5. Use the user's configured `sans` font-feature-settings by default. -6. Use the user's configured `sans` font-variation-settings by default. -7. Disable tap highlights on iOS -*/ - -html, -:host { - line-height: 1.5; - /* 1 */ - -webkit-text-size-adjust: 100%; - /* 2 */ - -moz-tab-size: 4; - /* 3 */ - -o-tab-size: 4; - tab-size: 4; - /* 3 */ - font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - /* 4 */ - font-feature-settings: normal; - /* 5 */ - font-variation-settings: normal; - /* 6 */ - -webkit-tap-highlight-color: transparent; - /* 7 */ -} - -/* -1. Remove the margin in all browsers. -2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. -*/ - -body { - margin: 0; - /* 1 */ - line-height: inherit; - /* 2 */ -} - -/* -1. Add the correct height in Firefox. -2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) -3. Ensure horizontal rules are visible by default. -*/ - -hr { - height: 0; - /* 1 */ - color: inherit; - /* 2 */ - border-top-width: 1px; - /* 3 */ -} - -/* -Add the correct text decoration in Chrome, Edge, and Safari. -*/ - -abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; -} - -/* -Remove the default font size and weight for headings. -*/ - -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: inherit; - font-weight: inherit; -} - -/* -Reset links to optimize for opt-in styling instead of opt-out. -*/ - -a { - color: inherit; - text-decoration: inherit; -} - -/* -Add the correct font weight in Edge and Safari. -*/ - -b, -strong { - font-weight: bolder; -} - -/* -1. Use the user's configured `mono` font-family by default. -2. Use the user's configured `mono` font-feature-settings by default. -3. Use the user's configured `mono` font-variation-settings by default. -4. Correct the odd `em` font sizing in all browsers. -*/ - -code, -kbd, -samp, -pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - /* 1 */ - font-feature-settings: normal; - /* 2 */ - font-variation-settings: normal; - /* 3 */ - font-size: 1em; - /* 4 */ -} - -/* -Add the correct font size in all browsers. -*/ - -small { - font-size: 80%; -} - -/* -Prevent `sub` and `sup` elements from affecting the line height in all browsers. -*/ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -/* -1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) -2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) -3. Remove gaps between table borders by default. -*/ - -table { - text-indent: 0; - /* 1 */ - border-color: inherit; - /* 2 */ - border-collapse: collapse; - /* 3 */ -} - -/* -1. Change the font styles in all browsers. -2. Remove the margin in Firefox and Safari. -3. Remove default padding in all browsers. -*/ - -button, -input, -optgroup, -select, -textarea { - font-family: inherit; - /* 1 */ - font-feature-settings: inherit; - /* 1 */ - font-variation-settings: inherit; - /* 1 */ - font-size: 100%; - /* 1 */ - font-weight: inherit; - /* 1 */ - line-height: inherit; - /* 1 */ - letter-spacing: inherit; - /* 1 */ - color: inherit; - /* 1 */ - margin: 0; - /* 2 */ - padding: 0; - /* 3 */ -} - -/* -Remove the inheritance of text transform in Edge and Firefox. -*/ - -button, -select { - text-transform: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Remove default button styles. -*/ - -button, -input:where([type='button']), -input:where([type='reset']), -input:where([type='submit']) { - -webkit-appearance: button; - /* 1 */ - background-color: transparent; - /* 2 */ - background-image: none; - /* 2 */ -} - -/* -Use the modern Firefox focus style for all focusable elements. -*/ - -:-moz-focusring { - outline: auto; -} - -/* -Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) -*/ - -:-moz-ui-invalid { - box-shadow: none; -} - -/* -Add the correct vertical alignment in Chrome and Firefox. -*/ - -progress { - vertical-align: baseline; -} - -/* -Correct the cursor style of increment and decrement buttons in Safari. -*/ - -::-webkit-inner-spin-button, -::-webkit-outer-spin-button { - height: auto; -} - -/* -1. Correct the odd appearance in Chrome and Safari. -2. Correct the outline style in Safari. -*/ - -[type='search'] { - -webkit-appearance: textfield; - /* 1 */ - outline-offset: -2px; - /* 2 */ -} - -/* -Remove the inner padding in Chrome and Safari on macOS. -*/ - -::-webkit-search-decoration { - -webkit-appearance: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Change font properties to `inherit` in Safari. -*/ - -::-webkit-file-upload-button { - -webkit-appearance: button; - /* 1 */ - font: inherit; - /* 2 */ -} - -/* -Add the correct display in Chrome and Safari. -*/ - -summary { - display: list-item; -} - -/* -Removes the default spacing and border for appropriate elements. -*/ - -blockquote, -dl, -dd, -h1, -h2, -h3, -h4, -h5, -h6, -hr, -figure, -p, -pre { - margin: 0; -} - -fieldset { - margin: 0; - padding: 0; -} - -legend { - padding: 0; -} - -ol, -ul, -menu { - list-style: none; - margin: 0; - padding: 0; -} - -/* -Reset default styling for dialogs. -*/ - -dialog { - padding: 0; -} - -/* -Prevent resizing textareas horizontally by default. -*/ - -textarea { - resize: vertical; -} - -/* -1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) -2. Set the default placeholder color to the user's configured gray 400 color. -*/ - -input::-moz-placeholder, textarea::-moz-placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -input::placeholder, -textarea::placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -/* -Set the default cursor for buttons. -*/ - -button, -[role="button"] { - cursor: pointer; -} - -/* -Make sure disabled buttons don't get the pointer cursor. -*/ - -:disabled { - cursor: default; -} - -/* -1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) -2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) - This can trigger a poorly considered lint error in some tools but is included by design. -*/ - -img, -svg, -video, -canvas, -audio, -iframe, -embed, -object { - display: block; - /* 1 */ - vertical-align: middle; - /* 2 */ -} - -/* -Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) -*/ - -img, -video { - max-width: 100%; - height: auto; -} - -/* Make elements with the HTML hidden attribute stay hidden by default */ - -[hidden]:where(:not([hidden="until-found"])) { - display: none; -} - -[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select{ - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - border-radius: 0px; - padding-top: 0.5rem; - padding-right: 0.75rem; - padding-bottom: 0.5rem; - padding-left: 0.75rem; - font-size: 1rem; - line-height: 1.5rem; - --tw-shadow: 0 0 #0000; -} - -[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus{ - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - border-color: #2563eb; -} - -input::-moz-placeholder, textarea::-moz-placeholder{ - color: #6b7280; - opacity: 1; -} - -input::placeholder,textarea::placeholder{ - color: #6b7280; - opacity: 1; -} - -::-webkit-datetime-edit-fields-wrapper{ - padding: 0; -} - -::-webkit-date-and-time-value{ - min-height: 1.5em; - text-align: inherit; -} - -::-webkit-datetime-edit{ - display: inline-flex; -} - -::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{ - padding-top: 0; - padding-bottom: 0; -} - -select{ - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); - background-position: right 0.5rem center; - background-repeat: no-repeat; - background-size: 1.5em 1.5em; - padding-right: 2.5rem; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; -} - -[multiple],[size]:where(select:not([size="1"])){ - background-image: initial; - background-position: initial; - background-repeat: unset; - background-size: initial; - padding-right: 0.75rem; - -webkit-print-color-adjust: unset; - print-color-adjust: unset; -} - -[type='checkbox'],[type='radio']{ - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - padding: 0; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; - display: inline-block; - vertical-align: middle; - background-origin: border-box; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - flex-shrink: 0; - height: 1rem; - width: 1rem; - color: #2563eb; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - --tw-shadow: 0 0 #0000; -} - -[type='checkbox']{ - border-radius: 0px; -} - -[type='radio']{ - border-radius: 100%; -} - -[type='checkbox']:focus,[type='radio']:focus{ - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 2px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); -} - -[type='checkbox']:checked,[type='radio']:checked{ - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -[type='checkbox']:checked{ - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); -} - -@media (forced-colors: active) { - [type='checkbox']:checked{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='radio']:checked{ - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); -} - -@media (forced-colors: active) { - [type='radio']:checked{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus{ - border-color: transparent; - background-color: currentColor; -} - -[type='checkbox']:indeterminate{ - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -@media (forced-colors: active) { - [type='checkbox']:indeterminate{ - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus{ - border-color: transparent; - background-color: currentColor; -} - -[type='file']{ - background: unset; - border-color: inherit; - border-width: 0; - border-radius: 0; - padding: 0; - font-size: unset; - line-height: inherit; -} - -[type='file']:focus{ - outline: 1px solid ButtonText; - outline: 1px auto -webkit-focus-ring-color; -} - -:root{ - --motion-default-timing: cubic-bezier(.165, .84, .44, 1); - --motion-bounce: linear(0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141 13.6%, 0.25, 0.391, 0.563, 0.765,1, 0.891 40.9%, 0.848, 0.813, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785,0.813, 0.848, 0.891 68.2%, 1 72.7%, 0.973, 0.953, 0.941, 0.938, 0.941, 0.953,0.973, 1, 0.988, 0.984, 0.988, 1); - --motion-spring-smooth: linear(0, 0.001 0.44%, 0.0045 0.94%, 0.0195 2.03%, 0.0446 3.19%, 0.0811 4.5%, 0.1598 6.82%, 0.3685 12.34%, 0.4693 15.17%, 0.5663, 0.6498 21.27%, 0.7215 24.39%, 0.7532 25.98%, 0.7829 27.65%, 0.8105, 0.8349 31.14%, 0.8573 32.95%, 0.8776 34.84%, 0.8964 36.87%, 0.9136 39.05%, 0.929 41.37%, 0.9421 43.77%, 0.9537 46.38%, 0.9636 49.14%, 0.9789 55.31%, 0.9888 62.35%, 0.9949 71.06%, 0.9982 82.52%, 0.9997 99.94%); - --motion-spring-snappy: linear(0, 0.0014, 0.0053 1.02%, 0.0126, 0.0227 2.18%, 0.0517 3.41%, 0.094 4.79%, 0.1865 7.26%, 0.4182 12.77%, 0.5246 15.46%, 0.6249, 0.7112, 0.7831 23.95%, 0.8146 25.4%, 0.844, 0.8699 28.45%, 0.8935, 0.9139 31.64%, 0.932, 0.9473, 0.9601 36.65%, 0.9714 38.47%, 0.9808 40.35%, 0.9948 44.49%, 1.0031 49.43%, 1.0057 53.35%, 1.0063 58.14%, 1.0014 80.78%, 1.0001 99.94%); - --motion-spring-bouncy: linear(0, 0.0018, 0.0069, 0.0151 1.74%, 0.0277 2.4%, 0.062 3.7%, 0.1115 5.15%, 0.2211 7.77%, 0.4778 13.21%, 0.5912 15.75%, 0.6987 18.44%, 0.7862 20.98%, 0.861 23.59%, 0.8926, 0.9205, 0.945 27.51%, 0.9671 28.89%, 0.9868, 1.003 31.79%, 1.0224 34.11%, 1.0358 36.58%, 1.0436 39.27%, 1.046 42.31%, 1.0446 44.71%, 1.0406 47.47%, 1.0118 61.84%, 1.0027 69.53%, 0.9981 80.49%, 0.9991 99.94%); - --motion-spring-bouncier: linear(0, 0.0023, 0.0088, 0.0194 1.59%, 0.035 2.17%, 0.078 3.33%, 0.1415 4.64%, 0.2054 5.75%, 0.2821 6.95%, 0.5912 11.45%, 0.7205 13.43%, 0.8393 15.45%, 0.936 17.39%, 0.9778, 1.015, 1.0477, 1.0759, 1.0998 22.22%, 1.1203, 1.1364, 1.1484 25.26%, 1.1586 26.61%, 1.1629 28.06%, 1.1613 29.56%, 1.1537 31.2%, 1.1434 32.6%, 1.1288 34.19%, 1.0508 41.29%, 1.0174 44.87%, 1.0025 46.89%, 0.9911 48.87%, 0.9826 50.9%, 0.9769 53.03%, 0.9735 56.02%, 0.9748 59.45%, 0.9964 72.64%, 1.0031 79.69%, 1.0042 86.83%, 1.0008 99.97%); - --motion-spring-bounciest: linear(0, 0.0032, 0.0131, 0.0294, 0.0524, 0.0824, 0.1192 1.54%, 0.2134 2.11%, 0.3102 2.59%, 0.4297 3.13%, 0.8732 4.95%, 1.0373, 1.1827 6.36%, 1.2972 7.01%, 1.3444, 1.3859, 1.4215, 1.4504, 1.4735, 1.4908, 1.5024, 1.5084 9.5%, 1.5091, 1.5061, 1.4993, 1.4886, 1.4745, 1.4565 11.11%, 1.4082 11.7%, 1.3585 12.2%, 1.295 12.77%, 1.0623 14.64%, 0.9773, 0.9031 16.08%, 0.8449 16.73%, 0.8014, 0.7701 17.95%, 0.7587, 0.7501, 0.7443, 0.7412 19.16%, 0.7421 19.68%, 0.7508 20.21%, 0.7672 20.77%, 0.7917 21.37%, 0.8169 21.87%, 0.8492 22.43%, 0.9681 24.32%, 1.0114, 1.0492 25.75%, 1.0789 26.41%, 1.1008, 1.1167, 1.1271, 1.1317 28.81%, 1.1314, 1.1271 29.87%, 1.1189 30.43%, 1.1063 31.03%, 1.0769 32.11%, 0.9941 34.72%, 0.9748 35.43%, 0.9597 36.09%, 0.9487, 0.9407, 0.9355, 0.933 38.46%, 0.9344 39.38%, 0.9421 40.38%, 0.9566 41.5%, 0.9989 44.12%, 1.0161 45.37%, 1.029 46.75%, 1.0341 48.1%, 1.0335 49.04%, 1.0295 50.05%, 1.0221 51.18%, 0.992 55.02%, 0.9854 56.38%, 0.9827 57.72%, 0.985 59.73%, 1.004 64.67%, 1.0088 67.34%, 1.0076 69.42%, 0.9981 74.28%, 0.9956 76.85%, 0.9961 79.06%, 1.0023 86.46%, 0.999 95.22%, 0.9994 100%); -} - -.container{ - width: 100%; -} - -@media (min-width: 640px){ - .container{ - max-width: 640px; - } -} - -@media (min-width: 768px){ - .container{ - max-width: 768px; - } -} - -@media (min-width: 1024px){ - .container{ - max-width: 1024px; - } -} - -@media (min-width: 1280px){ - .container{ - max-width: 1280px; - } -} - -@media (min-width: 1536px){ - .container{ - max-width: 1536px; - } -} - -.motion-preset-slide-up{ - --motion-origin-translate-y: 25%; - --motion-origin-opacity: 0; - --motion-opacity-in-animation: motion-opacity-in calc(var(--motion-opacity-duration) * var(--motion-opacity-perceptual-duration-multiplier)) var(--motion-opacity-timing) var(--motion-opacity-delay) both; - --motion-translate-in-animation: motion-translate-in calc(var(--motion-translate-duration) * var(--motion-translate-perceptual-duration-multiplier)) var(--motion-translate-timing) var(--motion-translate-delay) both; - animation: var(--motion-all-enter-animations); -} - -@keyframes RomboConfettiPop{ - 0%{ - opacity: 0; - transform: scale(1); - } - - 33%{ - opacity: 1; - transform: scale(1.15); - } - - 50%{ - transform: scale(0.975); - } - - 65%{ - transform: scale(1.025); - } - - 80%{ - transform: scale(0.99); - } - - 87%{ - transform: scale(1.01); - } - - 100%{ - opacity: 1; - transform: scale(1); - } -} - -@keyframes topfetti{ - 0%{ - background-position: 5% 90%, 10% 90%, 10% 90%, 15% 90%, 25% 90%, 25% 90%, 40% 90%, 55% 90%, 70% 90%; - } - - 50%{ - background-position: 0% 80%, 0% 20%, 10% 40%, 20% 0%, 30% 30%, 22% 50%, 50% 50%, 65% 20%, 90% 30%; - } - - 100%{ - background-position: 0% 70%, 0% 10%, 10% 30%, 20% -10%, 30% 20%, 22% 40%, 50% 40%, 65% 10%, 90% 20%; - background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; - } -} - -@keyframes bottomfetti{ - 0%{ - background-position: 10% -10%, 30% 10%, 55% -10%, 70% -10%, 85% -10%,70% -10%, 70% 0%; - } - - 50%{ - background-position: 0% 80%, 20% 80%, 45% 60%, 60% 100%, 75% 70%, 95% 60%, 105% 0%; - } - - 100%{ - background-position: 0% 90%, 20% 90%, 45% 70%, 60% 110%, 75% 80%, 95% 70%, 110% 10%; - background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; - } -} - -.fixed{ - position: fixed; -} - -.absolute{ - position: absolute; -} - -.relative{ - position: relative; -} - -.inset-0{ - inset: 0px; -} - -.bottom-0{ - bottom: 0px; -} - -.left-0{ - left: 0px; -} - -.left-1\/2{ - left: 50%; -} - -.right-0{ - right: 0px; -} - -.top-0{ - top: 0px; -} - -.top-2{ - top: 0.5rem; -} - -.-z-10{ - z-index: -10; -} - -.z-10{ - z-index: 10; -} - -.z-20{ - z-index: 20; -} - -.z-30{ - z-index: 30; -} - -.z-40{ - z-index: 40; -} - -.z-50{ - z-index: 50; -} - -.z-\[99\]{ - z-index: 99; -} - -.order-first{ - order: -9999; -} - -.-m-2{ - margin: -0.5rem; -} - -.m-2{ - margin: 0.5rem; -} - -.mx-auto{ - margin-left: auto; - margin-right: auto; -} - -.mb-1{ - margin-bottom: 0.25rem; -} - -.mb-2{ - margin-bottom: 0.5rem; -} - -.mb-3{ - margin-bottom: 0.75rem; -} - -.mb-4{ - margin-bottom: 1rem; -} - -.mb-6{ - margin-bottom: 1.5rem; -} - -.mb-8{ - margin-bottom: 2rem; -} - -.ml-1{ - margin-left: 0.25rem; -} - -.ml-2{ - margin-left: 0.5rem; -} - -.ml-3{ - margin-left: 0.75rem; -} - -.mr-1{ - margin-right: 0.25rem; -} - -.mr-2{ - margin-right: 0.5rem; -} - -.mr-3{ - margin-right: 0.75rem; -} - -.mr-4{ - margin-right: 1rem; -} - -.mr-5{ - margin-right: 1.25rem; -} - -.mr-7{ - margin-right: 1.75rem; -} - -.mt-1{ - margin-top: 0.25rem; -} - -.mt-12{ - margin-top: 3rem; -} - -.mt-2{ - margin-top: 0.5rem; -} - -.mt-24{ - margin-top: 6rem; -} - -.mt-4{ - margin-top: 1rem; -} - -.mt-5{ - margin-top: 1.25rem; -} - -.mt-6{ - margin-top: 1.5rem; -} - -.box-content{ - box-sizing: content-box; -} - -.block{ - display: block; -} - -.flex{ - display: flex; -} - -.inline-flex{ - display: inline-flex; -} - -.grid{ - display: grid; -} - -.hidden{ - display: none; -} - -.h-0\.5{ - height: 0.125rem; -} - -.h-10{ - height: 2.5rem; -} - -.h-14{ - height: 3.5rem; -} - -.h-20{ - height: 5rem; -} - -.h-3{ - height: 0.75rem; -} - -.h-32{ - height: 8rem; -} - -.h-4{ - height: 1rem; -} - -.h-5{ - height: 1.25rem; -} - -.h-8{ - height: 2rem; -} - -.h-9{ - height: 2.25rem; -} - -.h-\[280px\]{ - height: 280px; -} - -.h-auto{ - height: auto; -} - -.h-full{ - height: 100%; -} - -.h-screen{ - height: 100vh; -} - -.min-h-screen{ - min-height: 100vh; -} - -.w-0{ - width: 0px; -} - -.w-1\/3{ - width: 33.333333%; -} - -.w-14{ - width: 3.5rem; -} - -.w-16{ - width: 4rem; -} - -.w-20{ - width: 5rem; -} - -.w-3{ - width: 0.75rem; -} - -.w-4{ - width: 1rem; -} - -.w-5{ - width: 1.25rem; -} - -.w-8{ - width: 2rem; -} - -.w-\[22rem\]{ - width: 22rem; -} - -.w-\[365px\]{ - width: 365px; -} - -.w-\[calc\(100\%\+1rem\)\]{ - width: calc(100% + 1rem); -} - -.w-\[full\]{ - width: full; -} - -.w-auto{ - width: auto; -} - -.w-fit{ - width: -moz-fit-content; - width: fit-content; -} - -.w-full{ - width: 100%; -} - -.w-screen{ - width: 100vw; -} - -.max-w-2xl{ - max-width: 42rem; -} - -.max-w-3xl{ - max-width: 48rem; -} - -.max-w-4xl{ - max-width: 56rem; -} - -.max-w-5xl{ - max-width: 64rem; -} - -.max-w-6xl{ - max-width: 72rem; -} - -.max-w-\[94rem\]{ - max-width: 94rem; -} - -.max-w-lg{ - max-width: 32rem; -} - -.max-w-md{ - max-width: 28rem; -} - -.max-w-screen-sm{ - max-width: 640px; -} - -.max-w-sm{ - max-width: 24rem; -} - -.max-w-xl{ - max-width: 36rem; -} - -.max-w-xs{ - max-width: 20rem; -} - -.flex-shrink-0{ - flex-shrink: 0; -} - -.shrink-0{ - flex-shrink: 0; -} - -.grow{ - flex-grow: 1; -} - -.-translate-x-0{ - --tw-translate-x: -0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-1\/2{ - --tw-translate-x: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-4{ - --tw-translate-x: -1rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-7{ - --tw-translate-x: -1.75rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-8{ - --tw-translate-x: -2rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-x-px{ - --tw-translate-x: -1px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-y-4{ - --tw-translate-y: -1rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.-translate-y-px{ - --tw-translate-y: -1px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-x-0{ - --tw-translate-x: 0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-x-8{ - --tw-translate-x: 2rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-0{ - --tw-translate-y: 0px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-1\/3{ - --tw-translate-y: 33.333333%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-24{ - --tw-translate-y: 6rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-3{ - --tw-translate-y: 0.75rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.translate-y-4{ - --tw-translate-y: 1rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.rotate-1{ - --tw-rotate: 1deg; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.scale-100{ - --tw-scale-x: 1; - --tw-scale-y: 1; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.scale-90{ - --tw-scale-x: .9; - --tw-scale-y: .9; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.transform{ - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -@keyframes infinite-scroll{ - from{ - transform: translateX(0); - } - - to{ - transform: translateX(-100%); - } -} - -.animate-infinite-scroll{ - animation: infinite-scroll 60s linear infinite; -} - -@keyframes infinite-scroll-inverse{ - from{ - transform: translateX(-100%); - } - - to{ - transform: translateX(0); - } -} - -.animate-infinite-scroll-inverse{ - animation: infinite-scroll-inverse 60s linear infinite; -} - -.cursor-default{ - cursor: default; -} - -.cursor-pointer{ - cursor: pointer; -} - -.grid-cols-2{ - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.flex-row{ - flex-direction: row; -} - -.flex-col{ - flex-direction: column; -} - -.flex-col-reverse{ - flex-direction: column-reverse; -} - -.flex-wrap{ - flex-wrap: wrap; -} - -.flex-nowrap{ - flex-wrap: nowrap; -} - -.items-start{ - align-items: flex-start; -} - -.items-end{ - align-items: flex-end; -} - -.items-center{ - align-items: center; -} - -.justify-end{ - justify-content: flex-end; -} - -.justify-center{ - justify-content: center; -} - -.justify-between{ - justify-content: space-between; -} - -.gap-12{ - gap: 3rem; -} - -.gap-2{ - gap: 0.5rem; -} - -.gap-3{ - gap: 0.75rem; -} - -.gap-4{ - gap: 1rem; -} - -.gap-8{ - gap: 2rem; -} - -.gap-x-3{ - -moz-column-gap: 0.75rem; - column-gap: 0.75rem; -} - -.gap-y-3{ - row-gap: 0.75rem; -} - -.space-x-1 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(0.25rem * var(--tw-space-x-reverse)); - margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse))); -} - -.space-x-3 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(0.75rem * var(--tw-space-x-reverse)); - margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); -} - -.space-x-4 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(1rem * var(--tw-space-x-reverse)); - margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); -} - -.space-y-1 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); -} - -.space-y-1\.5 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.375rem * var(--tw-space-y-reverse)); -} - -.space-y-12 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(3rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(3rem * var(--tw-space-y-reverse)); -} - -.space-y-2 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); -} - -.space-y-4 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1rem * var(--tw-space-y-reverse)); -} - -.space-y-6 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); -} - -.overflow-hidden{ - overflow: hidden; -} - -.rounded{ - border-radius: 0.25rem; -} - -.rounded-full{ - border-radius: 9999px; -} - -.rounded-lg{ - border-radius: 0.5rem; -} - -.rounded-md{ - border-radius: 0.375rem; -} - -.rounded-xl{ - border-radius: 0.75rem; -} - -.rounded-t-lg{ - border-top-left-radius: 0.5rem; - border-top-right-radius: 0.5rem; -} - -.border{ - border-width: 1px; -} - -.border-2{ - border-width: 2px; -} - -.border-\[2px\]{ - border-width: 2px; -} - -.border-t{ - border-top-width: 1px; -} - -.border-neutral-200\/60{ - border-color: rgb(229 229 229 / 0.6); -} - -.border-neutral-200\/70{ - border-color: rgb(229 229 229 / 0.7); -} - -.border-neutral-300{ - --tw-border-opacity: 1; - border-color: rgb(212 212 212 / var(--tw-border-opacity, 1)); -} - -.border-transparent{ - border-color: transparent; -} - -.border-white{ - --tw-border-opacity: 1; - border-color: rgb(255 255 255 / var(--tw-border-opacity, 1)); -} - -.border-zinc-200{ - --tw-border-opacity: 1; - border-color: rgb(228 228 231 / var(--tw-border-opacity, 1)); -} - -.border-zinc-300{ - --tw-border-opacity: 1; - border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); -} - -.border-zinc-600{ - --tw-border-opacity: 1; - border-color: rgb(82 82 91 / var(--tw-border-opacity, 1)); -} - -.bg-blue-600{ - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)); -} - -.bg-neutral-50{ - --tw-bg-opacity: 1; - background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); -} - -.bg-neutral-900{ - --tw-bg-opacity: 1; - background-color: rgb(23 23 23 / var(--tw-bg-opacity, 1)); -} - -.bg-neutral-950{ - --tw-bg-opacity: 1; - background-color: rgb(10 10 10 / var(--tw-bg-opacity, 1)); -} - -.bg-transparent{ - background-color: transparent; -} - -.bg-white{ - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); -} - -.bg-zinc-100{ - --tw-bg-opacity: 1; - background-color: rgb(244 244 245 / var(--tw-bg-opacity, 1)); -} - -.bg-zinc-50{ - --tw-bg-opacity: 1; - background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); -} - -.bg-zinc-800{ - --tw-bg-opacity: 1; - background-color: rgb(39 39 42 / var(--tw-bg-opacity, 1)); -} - -.bg-zinc-900{ - --tw-bg-opacity: 1; - background-color: rgb(24 24 27 / var(--tw-bg-opacity, 1)); -} - -.bg-opacity-90{ - --tw-bg-opacity: 0.9; -} - -.bg-gradient-to-r{ - background-image: linear-gradient(to right, var(--tw-gradient-stops)); -} - -.bg-gradient-to-t{ - background-image: linear-gradient(to top, var(--tw-gradient-stops)); -} - -.from-black{ - --tw-gradient-from: #000 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.from-zinc-100{ - --tw-gradient-from: #f4f4f5 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(244 244 245 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.from-zinc-500{ - --tw-gradient-from: #71717a var(--tw-gradient-from-position); - --tw-gradient-to: rgb(113 113 122 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.via-zinc-900{ - --tw-gradient-to: rgb(24 24 27 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), #18181b var(--tw-gradient-via-position), var(--tw-gradient-to); -} - -.to-white{ - --tw-gradient-to: #fff var(--tw-gradient-to-position); -} - -.to-zinc-900{ - --tw-gradient-to: #18181b var(--tw-gradient-to-position); -} - -.bg-cover{ - background-size: cover; -} - -.bg-clip-text{ - -webkit-background-clip: text; - background-clip: text; -} - -.fill-current{ - fill: currentColor; -} - -.fill-zinc-300{ - fill: #d4d4d8; -} - -.fill-zinc-400{ - fill: #a1a1aa; -} - -.object-cover{ - -o-object-fit: cover; - object-fit: cover; -} - -.object-left{ - -o-object-position: left; - object-position: left; -} - -.p-1{ - padding: 0.25rem; -} - -.p-4{ - padding: 1rem; -} - -.p-5{ - padding: 1.25rem; -} - -.p-6{ - padding: 1.5rem; -} - -.p-7{ - padding: 1.75rem; -} - -.px-0\.5{ - padding-left: 0.125rem; - padding-right: 0.125rem; -} - -.px-2{ - padding-left: 0.5rem; - padding-right: 0.5rem; -} - -.px-2\.5{ - padding-left: 0.625rem; - padding-right: 0.625rem; -} - -.px-3{ - padding-left: 0.75rem; - padding-right: 0.75rem; -} - -.px-3\.5{ - padding-left: 0.875rem; - padding-right: 0.875rem; -} - -.px-4{ - padding-left: 1rem; - padding-right: 1rem; -} - -.px-5{ - padding-left: 1.25rem; - padding-right: 1.25rem; -} - -.px-6{ - padding-left: 1.5rem; - padding-right: 1.5rem; -} - -.px-7{ - padding-left: 1.75rem; - padding-right: 1.75rem; -} - -.px-8{ - padding-left: 2rem; - padding-right: 2rem; -} - -.py-0\.5{ - padding-top: 0.125rem; - padding-bottom: 0.125rem; -} - -.py-1{ - padding-top: 0.25rem; - padding-bottom: 0.25rem; -} - -.py-12{ - padding-top: 3rem; - padding-bottom: 3rem; -} - -.py-2{ - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} - -.py-3{ - padding-top: 0.75rem; - padding-bottom: 0.75rem; -} - -.py-4{ - padding-top: 1rem; - padding-bottom: 1rem; -} - -.py-5{ - padding-top: 1.25rem; - padding-bottom: 1.25rem; -} - -.py-6{ - padding-top: 1.5rem; - padding-bottom: 1.5rem; -} - -.py-8{ - padding-top: 2rem; - padding-bottom: 2rem; -} - -.py-px{ - padding-top: 1px; - padding-bottom: 1px; -} - -.pb-1{ - padding-bottom: 0.25rem; -} - -.pb-12{ - padding-bottom: 3rem; -} - -.pb-2{ - padding-bottom: 0.5rem; -} - -.pb-3{ - padding-bottom: 0.75rem; -} - -.pb-4{ - padding-bottom: 1rem; -} - -.pb-6{ - padding-bottom: 1.5rem; -} - -.pb-8{ - padding-bottom: 2rem; -} - -.pl-4{ - padding-left: 1rem; -} - -.pr-2{ - padding-right: 0.5rem; -} - -.pr-4{ - padding-right: 1rem; -} - -.pt-0{ - padding-top: 0px; -} - -.pt-2{ - padding-top: 0.5rem; -} - -.pt-32{ - padding-top: 8rem; -} - -.pt-6{ - padding-top: 1.5rem; -} - -.pt-8{ - padding-top: 2rem; -} - -.text-left{ - text-align: left; -} - -.text-center{ - text-align: center; -} - -.align-top{ - vertical-align: top; -} - -.font-inter{ - font-family: Inter, sans-serif; -} - -.font-inter-tight{ - font-family: Inter Tight, sans-serif; -} - -.font-sans{ - font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; -} - -.text-2xl{ - font-size: 1.5rem; - line-height: 1.415; - letter-spacing: -0.017em; -} - -.text-3xl{ - font-size: 2rem; - line-height: 1.3125; - letter-spacing: -0.017em; -} - -.text-4xl{ - font-size: 2.5rem; - line-height: 1.25; - letter-spacing: -0.017em; -} - -.text-\[0\.6rem\]{ - font-size: 0.6rem; -} - -.text-base{ - font-size: 1rem; - line-height: 1.5; - letter-spacing: -0.017em; -} - -.text-lg{ - font-size: 1.125rem; - line-height: 1.5; - letter-spacing: -0.017em; -} - -.text-sm{ - font-size: 0.875rem; - line-height: 1.5715; -} - -.text-xl{ - font-size: 1.25rem; - line-height: 1.5; - letter-spacing: -0.017em; -} - -.text-xs{ - font-size: 0.75rem; - line-height: 1.5; -} - -.font-bold{ - font-weight: 700; -} - -.font-extrabold{ - font-weight: 800; -} - -.font-medium{ - font-weight: 500; -} - -.font-normal{ - font-weight: 400; -} - -.font-semibold{ - font-weight: 600; -} - -.uppercase{ - text-transform: uppercase; -} - -.italic{ - font-style: italic; -} - -.not-italic{ - font-style: normal; -} - -.tabular-nums{ - --tw-numeric-spacing: tabular-nums; - font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); -} - -.leading-none{ - line-height: 1; -} - -.tracking-tight{ - letter-spacing: -0.025em; -} - -.tracking-wide{ - letter-spacing: 0.025em; -} - -.text-blue-600{ - --tw-text-opacity: 1; - color: rgb(37 99 235 / var(--tw-text-opacity, 1)); -} - -.text-gray-400{ - --tw-text-opacity: 1; - color: rgb(156 163 175 / var(--tw-text-opacity, 1)); -} - -.text-gray-400\/70{ - color: rgb(156 163 175 / 0.7); -} - -.text-gray-500{ - --tw-text-opacity: 1; - color: rgb(107 114 128 / var(--tw-text-opacity, 1)); -} - -.text-gray-600{ - --tw-text-opacity: 1; - color: rgb(75 85 99 / var(--tw-text-opacity, 1)); -} - -.text-neutral-100{ - --tw-text-opacity: 1; - color: rgb(245 245 245 / var(--tw-text-opacity, 1)); -} - -.text-neutral-500{ - --tw-text-opacity: 1; - color: rgb(115 115 115 / var(--tw-text-opacity, 1)); -} - -.text-neutral-800{ - --tw-text-opacity: 1; - color: rgb(38 38 38 / var(--tw-text-opacity, 1)); -} - -.text-neutral-900{ - --tw-text-opacity: 1; - color: rgb(23 23 23 / var(--tw-text-opacity, 1)); -} - -.text-transparent{ - color: transparent; -} - -.text-white{ - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity, 1)); -} - -.text-zinc-100{ - --tw-text-opacity: 1; - color: rgb(244 244 245 / var(--tw-text-opacity, 1)); -} - -.text-zinc-200{ - --tw-text-opacity: 1; - color: rgb(228 228 231 / var(--tw-text-opacity, 1)); -} - -.text-zinc-400{ - --tw-text-opacity: 1; - color: rgb(161 161 170 / var(--tw-text-opacity, 1)); -} - -.text-zinc-500{ - --tw-text-opacity: 1; - color: rgb(113 113 122 / var(--tw-text-opacity, 1)); -} - -.text-zinc-600{ - --tw-text-opacity: 1; - color: rgb(82 82 91 / var(--tw-text-opacity, 1)); -} - -.text-zinc-700{ - --tw-text-opacity: 1; - color: rgb(63 63 70 / var(--tw-text-opacity, 1)); -} - -.text-zinc-800{ - --tw-text-opacity: 1; - color: rgb(39 39 42 / var(--tw-text-opacity, 1)); -} - -.text-zinc-900{ - --tw-text-opacity: 1; - color: rgb(24 24 27 / var(--tw-text-opacity, 1)); -} - -.underline{ - text-decoration-line: underline; -} - -.no-underline{ - text-decoration-line: none; -} - -.underline-offset-4{ - text-underline-offset: 4px; -} - -.antialiased{ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.opacity-0{ - opacity: 0; -} - -.opacity-100{ - opacity: 1; -} - -.opacity-60{ - opacity: 0.6; -} - -.opacity-70{ - opacity: 0.7; -} - -.opacity-90{ - opacity: 0.9; -} - -.mix-blend-exclusion{ - mix-blend-mode: exclusion; -} - -.shadow{ - --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-2xl{ - --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); - --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-md{ - --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-sm{ - --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); - --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-zinc-950\/20{ - --tw-shadow-color: rgb(9 9 11 / 0.2); - --tw-shadow: var(--tw-shadow-colored); -} - -.drop-shadow-md{ - --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); -} - -.backdrop-blur-sm{ - --tw-backdrop-blur: blur(4px); - -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); -} - -.transition{ - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.transition-colors{ - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.duration-100{ - transition-duration: 100ms; -} - -.duration-150{ - transition-duration: 150ms; -} - -.duration-200{ - transition-duration: 200ms; -} - -.duration-300{ - transition-duration: 300ms; -} - -.duration-500{ - transition-duration: 500ms; -} - -.duration-700{ - transition-duration: 700ms; -} - -.ease-in{ - transition-timing-function: cubic-bezier(0.4, 0, 1, 1); -} - -.ease-in-out{ - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); -} - -.ease-out{ - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); -} - -@media screen and (prefers-reduced-motion: no-preference){ - @keyframes motion-scale-in{ - 0%{ - scale: var(--motion-origin-scale-x) var(--motion-origin-scale-y); - } - - 100%{ - scale: 1 1; - } - } - - @keyframes motion-scale-out{ - 0%{ - scale: 1 1; - } - - 100%{ - scale: var(--motion-end-scale-x) var(--motion-end-scale-y); - } - } - - @keyframes motion-translate-in{ - 0%{ - translate: var(--motion-origin-translate-x) var(--motion-origin-translate-y); - } - - 100%{ - translate: 0 0; - } - } - - @keyframes motion-translate-out{ - 0%{ - translate: 0 0; - } - - 100%{ - translate: var(--motion-end-translate-x) var(--motion-end-translate-y); - } - } - - @keyframes motion-rotate-in{ - 0%{ - rotate: var(--motion-origin-rotate); - } - - 100%{ - rotate: 0; - } - } - - @keyframes motion-rotate-out{ - 0%{ - rotate: 0; - } - - 100%{ - rotate: var(--motion-end-rotate); - } - } -} - -@keyframes motion-filter-in{ - 0%{ - filter: blur(var(--motion-origin-blur)) grayscale(var(--motion-origin-grayscale)); - } - - 100%{ - filter: blur(0) grayscale(0); - } -} - -@keyframes motion-filter-out{ - 0%{ - filter: blur(0) grayscale(0); - } - - 100%{ - filter: blur(var(--motion-end-blur)) grayscale(var(--motion-end-grayscale)); - } -} - -@keyframes motion-opacity-in{ - 0%{ - opacity: var(--motion-origin-opacity); - } -} - -@keyframes motion-opacity-out{ - 100%{ - opacity: var(--motion-end-opacity); - } -} - -@keyframes motion-background-color-in{ - 0%{ - background-color: var(--motion-origin-background-color); - } -} - -@keyframes motion-background-color-out{ - 100%{ - background-color: var(--motion-end-background-color); - } -} - -@keyframes motion-text-color-in{ - 0%{ - color: var(--motion-origin-text-color); - } -} - -@keyframes motion-text-color-out{ - 100%{ - color: var(--motion-end-text-color); - } -} - -.motion-scale-in-50{ - --motion-origin-scale-x: .5; - --motion-origin-scale-y: .5; - --motion-scale-in-animation: motion-scale-in calc(var(--motion-scale-duration) * var(--motion-scale-perceptual-duration-multiplier)) var(--motion-scale-timing) var(--motion-scale-delay) both; - animation: var(--motion-all-enter-animations); -} - -.motion-opacity-in-0{ - --motion-origin-opacity: 0.001; - --motion-opacity-in-animation: motion-opacity-in calc(var(--motion-opacity-duration) * var(--motion-opacity-perceptual-duration-multiplier)) var(--motion-opacity-timing) var(--motion-opacity-delay) both; - animation: var(--motion-all-enter-animations); -} - -.\[animation-delay\:-7\.5s\]{ - animation-delay: -7.5s; -} - -.\[background\:linear-gradient\(\#2E2E32\2c \#2E2E32\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ - background: linear-gradient(#2E2E32,#2E2E32) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; -} - -.\[background\:linear-gradient\(\#323237\2c \#323237\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ - background: linear-gradient(#323237,#323237) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; -} - -.\[background\:linear-gradient\(theme\(colors\.white\)\2c theme\(colors\.white\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ - background: linear-gradient(#fff,#fff) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; -} - -.\[background\:linear-gradient\(theme\(colors\.white\)\2c theme\(colors\.zinc\.50\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ - background: linear-gradient(#fff,#fafafa) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; -} - -.\[background\:linear-gradient\(theme\(colors\.zinc\.50\)\2c theme\(colors\.zinc\.50\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.300\)\2c theme\(colors\.zinc\.100\)\2c theme\(colors\.zinc\.300\)\)_border-box\]{ - background: linear-gradient(#fafafa,#fafafa) padding-box,linear-gradient(120deg,#d4d4d8,#f4f4f5,#d4d4d8) border-box; -} - -.\[background\:linear-gradient\(theme\(colors\.zinc\.800\)\2c theme\(colors\.zinc\.800\)\)_padding-box\2c linear-gradient\(120deg\2c theme\(colors\.zinc\.700\)\2c theme\(colors\.zinc\.700\/0\)\2c theme\(colors\.zinc\.700\)\)_border-box\]{ - background: linear-gradient(#27272a,#27272a) padding-box,linear-gradient(120deg,#3f3f46,rgb(63 63 70 / 0),#3f3f46) border-box; -} - -.\[mask-image\:_linear-gradient\(to_right\2c transparent_0\2c _black_28\%\2c _black_calc\(100\%-28\%\)\2c transparent_100\%\)\]{ - -webkit-mask-image: linear-gradient(to right,transparent 0, black 28%, black calc(100% - 28%),transparent 100%); - mask-image: linear-gradient(to right,transparent 0, black 28%, black calc(100% - 28%),transparent 100%); -} - -.\[mask-image\:linear-gradient\(to_right\2c transparent_8px\2c _theme\(colors\.white\/\.7\)_64px\2c _theme\(colors\.white\)_50\%\2c _theme\(colors\.white\/\.7\)_calc\(100\%-64px\)\2c _transparent_calc\(100\%-8px\)\)\]{ - -webkit-mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); - mask-image: linear-gradient(to right,transparent 8px, rgb(255 255 255 / .7) 64px, #fff 50%, rgb(255 255 255 / .7) calc(100% - 64px), transparent calc(100% - 8px)); -} - -/* See Alpine.js: https://github.com/alpinejs/alpine#x-cloak */ - -[x-cloak=""] { - display: none; -} - -/* Custom styles */ - -.form-input:focus, -.form-textarea:focus, -.form-multiselect:focus, -.form-select:focus, -.form-checkbox:focus, -.form-radio:focus{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -/* Hamburger button */ - -.hamburger svg > *:nth-child(1), -.hamburger svg > *:nth-child(2), -.hamburger svg > *:nth-child(3) { - transform-origin: center; - transform: rotate(0deg); -} - -.hamburger svg > *:nth-child(1) { - transition: - y 0.1s 0.25s ease-in, - transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), - opacity 0.1s ease-in; -} - -.hamburger svg > *:nth-child(2) { - transition: transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19); -} - -.hamburger svg > *:nth-child(3) { - transition: - y 0.1s 0.25s ease-in, - transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), - width 0.1s 0.25s ease-in; -} - -.hamburger.active svg > *:nth-child(1) { - opacity: 0; - y: 11; - transform: rotate(225deg); - transition: - y 0.1s ease-out, - transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), - opacity 0.1s 0.12s ease-out; -} - -.hamburger.active svg > *:nth-child(2) { - transform: rotate(225deg); - transition: transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1); -} - -.hamburger.active svg > *:nth-child(3) { - y: 11; - transform: rotate(135deg); - transition: - y 0.1s ease-out, - transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), - width 0.1s ease-out; -} - -/* Typography */ - -.h1{ - font-size: 3.25rem; - line-height: 1.2; - letter-spacing: -0.017em; - font-weight: 700; -} - -.h2{ - font-size: 2.5rem; - line-height: 1.25; - letter-spacing: -0.017em; - font-weight: 700; -} - -.h3{ - font-size: 2rem; - line-height: 1.3125; - letter-spacing: -0.017em; - font-weight: 700; -} - -.h4{ - font-size: 1.5rem; - line-height: 1.415; - letter-spacing: -0.017em; - font-weight: 700; -} - -@media (min-width: 768px) { - .h1{ - font-size: 3.75rem; - line-height: 1.1666; - letter-spacing: -0.017em; - } - - .h2{ - font-size: 3.25rem; - line-height: 1.2; - letter-spacing: -0.017em; - } - - .h3{ - font-size: 2.5rem; - line-height: 1.25; - letter-spacing: -0.017em; - } -} - -/* Buttons */ - -.btn, -.btn-sm{ - display: inline-flex; - align-items: center; - justify-content: center; - border-radius: 0.375rem; - border-width: 1px; - border-color: transparent; - font-size: 0.875rem; - line-height: 1.5715; - font-weight: 500; - letter-spacing: 0em; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.btn{ - padding-left: 1rem; - padding-right: 1rem; - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} - -.btn-sm{ - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; -} - -/* Forms */ - -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-results-button, -input[type="search"]::-webkit-search-results-decoration { - -webkit-appearance: none; -} - -.form-input, -.form-textarea, -.form-multiselect, -.form-select, -.form-checkbox, -.form-radio{ - border-width: 1px; - --tw-border-opacity: 1; - border-color: rgb(228 228 231 / var(--tw-border-opacity, 1)); - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); - --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); - --tw-shadow-color: rgb(0 0 0 / 0.05); - --tw-shadow: var(--tw-shadow-colored); -} - -.form-input:focus, -.form-textarea:focus, -.form-multiselect:focus, -.form-select:focus, -.form-checkbox:focus, -.form-radio:focus{ - --tw-border-opacity: 1; - border-color: rgb(161 161 170 / var(--tw-border-opacity, 1)); -} - -.form-input, -.form-textarea, -.form-multiselect, -.form-select, -.form-checkbox{ - border-radius: 0.25rem; -} - -.form-input, -.form-textarea, -.form-multiselect, -.form-select{ - padding-left: 1rem; - padding-right: 1rem; - padding-top: 0.5rem; - padding-bottom: 0.5rem; - font-size: 0.875rem; - line-height: 1.5715; - --tw-text-opacity: 1; - color: rgb(82 82 91 / var(--tw-text-opacity, 1)); -} - -.form-input::-moz-placeholder, .form-textarea::-moz-placeholder{ - --tw-placeholder-opacity: 1; - color: rgb(161 161 170 / var(--tw-placeholder-opacity, 1)); -} - -.form-input::placeholder, -.form-textarea::placeholder{ - --tw-placeholder-opacity: 1; - color: rgb(161 161 170 / var(--tw-placeholder-opacity, 1)); -} - -.form-select{ - padding-right: 2.5rem; -} - -.form-checkbox, -.form-radio{ - --tw-text-opacity: 1; - color: rgb(39 39 42 / var(--tw-text-opacity, 1)); -} - -.form-checkbox{ - border-radius: 0.125rem; -} - -/* Chrome, Safari and Opera */ - -.no-scrollbar::-webkit-scrollbar { - display: none; -} - -.no-scrollbar { - -ms-overflow-style: none; - /* IE and Edge */ - scrollbar-width: none; - /* Firefox */ -} - -.placeholder\:text-neutral-500::-moz-placeholder{ - --tw-text-opacity: 1; - color: rgb(115 115 115 / var(--tw-text-opacity, 1)); -} - -.placeholder\:text-neutral-500::placeholder{ - --tw-text-opacity: 1; - color: rgb(115 115 115 / var(--tw-text-opacity, 1)); -} - -.placeholder\:text-zinc-400::-moz-placeholder{ - --tw-text-opacity: 1; - color: rgb(161 161 170 / var(--tw-text-opacity, 1)); -} - -.placeholder\:text-zinc-400::placeholder{ - --tw-text-opacity: 1; - color: rgb(161 161 170 / var(--tw-text-opacity, 1)); -} - -.before\:pointer-events-none::before{ - content: var(--tw-content); - pointer-events: none; -} - -.before\:absolute::before{ - content: var(--tw-content); - position: absolute; -} - -.before\:inset-0::before{ - content: var(--tw-content); - inset: 0px; -} - -.before\:-top-12::before{ - content: var(--tw-content); - top: -3rem; -} - -.before\:-z-10::before{ - content: var(--tw-content); - z-index: -10; -} - -.before\:h-52::before{ - content: var(--tw-content); - height: 13rem; -} - -.before\:h-80::before{ - content: var(--tw-content); - height: 20rem; -} - -.before\:h-96::before{ - content: var(--tw-content); - height: 24rem; -} - -.before\:w-52::before{ - content: var(--tw-content); - width: 13rem; -} - -.before\:w-96::before{ - content: var(--tw-content); - width: 24rem; -} - -.before\:rounded-full::before{ - content: var(--tw-content); - border-radius: 9999px; -} - -.before\:bg-zinc-900::before{ - content: var(--tw-content); - --tw-bg-opacity: 1; - background-color: rgb(24 24 27 / var(--tw-bg-opacity, 1)); -} - -.before\:bg-gradient-to-b::before{ - content: var(--tw-content); - background-image: linear-gradient(to bottom, var(--tw-gradient-stops)); -} - -.before\:from-zinc-100::before{ - content: var(--tw-content); - --tw-gradient-from: #f4f4f5 var(--tw-gradient-from-position); - --tw-gradient-to: rgb(244 244 245 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.before\:opacity-\[\.08\]::before{ - content: var(--tw-content); - opacity: .08; -} - -.before\:opacity-\[\.15\]::before{ - content: var(--tw-content); - opacity: .15; -} - -.before\:blur-3xl::before{ - content: var(--tw-content); - --tw-blur: blur(64px); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); -} - -.before\:content-\[\'\\0022\'\]::before{ - --tw-content: '\0022'; - content: var(--tw-content); -} - -.after\:pointer-events-none::after{ - content: var(--tw-content); - pointer-events: none; -} - -.after\:absolute::after{ - content: var(--tw-content); - position: absolute; -} - -.after\:right-0::after{ - content: var(--tw-content); - right: 0px; -} - -.after\:top-0::after{ - content: var(--tw-content); - top: 0px; -} - -.after\:top-1\/2::after{ - content: var(--tw-content); - top: 50%; -} - -.after\:hidden::after{ - content: var(--tw-content); - display: none; -} - -.after\:h-8::after{ - content: var(--tw-content); - height: 2rem; -} - -.after\:h-full::after{ - content: var(--tw-content); - height: 100%; -} - -.after\:w-96::after{ - content: var(--tw-content); - width: 24rem; -} - -.after\:w-px::after{ - content: var(--tw-content); - width: 1px; -} - -.after\:-translate-y-1\/2::after{ - content: var(--tw-content); - --tw-translate-y: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.after\:border-l::after{ - content: var(--tw-content); - border-left-width: 1px; -} - -.after\:border-dashed::after{ - content: var(--tw-content); - border-style: dashed; -} - -.after\:border-zinc-300::after{ - content: var(--tw-content); - --tw-border-opacity: 1; - border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); -} - -.after\:bg-gradient-to-l::after{ - content: var(--tw-content); - background-image: linear-gradient(to left, var(--tw-gradient-stops)); -} - -.after\:from-zinc-800::after{ - content: var(--tw-content); - --tw-gradient-from: #27272a var(--tw-gradient-from-position); - --tw-gradient-to: rgb(39 39 42 / 0) var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); -} - -.after\:content-\[\'\\0022\'\]::after{ - --tw-content: '\0022'; - content: var(--tw-content); -} - -.last\:after\:hidden:last-child::after{ - content: var(--tw-content); - display: none; -} - -.hover\:bg-neutral-100:hover{ - --tw-bg-opacity: 1; - background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1)); -} - -.hover\:bg-neutral-800:hover{ - --tw-bg-opacity: 1; - background-color: rgb(38 38 38 / var(--tw-bg-opacity, 1)); -} - -.hover\:bg-neutral-900:hover{ - --tw-bg-opacity: 1; - background-color: rgb(23 23 23 / var(--tw-bg-opacity, 1)); -} - -.hover\:bg-zinc-200:hover{ - --tw-bg-opacity: 1; - background-color: rgb(228 228 231 / var(--tw-bg-opacity, 1)); -} - -.hover\:bg-zinc-50:hover{ - --tw-bg-opacity: 1; - background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1)); -} - -.hover\:bg-zinc-800:hover{ - --tw-bg-opacity: 1; - background-color: rgb(39 39 42 / var(--tw-bg-opacity, 1)); -} - -.hover\:text-neutral-900:hover{ - --tw-text-opacity: 1; - color: rgb(23 23 23 / var(--tw-text-opacity, 1)); -} - -.hover\:text-white:hover{ - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity, 1)); -} - -.hover\:text-zinc-300:hover{ - --tw-text-opacity: 1; - color: rgb(212 212 216 / var(--tw-text-opacity, 1)); -} - -.hover\:text-zinc-800:hover{ - --tw-text-opacity: 1; - color: rgb(39 39 42 / var(--tw-text-opacity, 1)); -} - -.hover\:text-zinc-900:hover{ - --tw-text-opacity: 1; - color: rgb(24 24 27 / var(--tw-text-opacity, 1)); -} - -.hover\:underline:hover{ - text-decoration-line: underline; -} - -.hover\:opacity-100:hover{ - opacity: 1; -} - -.focus\:border-neutral-300:focus{ - --tw-border-opacity: 1; - border-color: rgb(212 212 212 / var(--tw-border-opacity, 1)); -} - -.focus\:border-zinc-300:focus{ - --tw-border-opacity: 1; - border-color: rgb(212 212 216 / var(--tw-border-opacity, 1)); -} - -.focus\:no-underline:focus{ - text-decoration-line: none; -} - -.focus\:outline-none:focus{ - outline: 2px solid transparent; - outline-offset: 2px; -} - -.focus\:ring-2:focus{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus\:ring-neutral-100:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(245 245 245 / var(--tw-ring-opacity, 1)); -} - -.focus\:ring-neutral-400:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(163 163 163 / var(--tw-ring-opacity, 1)); -} - -.focus\:ring-neutral-900:focus{ - --tw-ring-opacity: 1; - --tw-ring-color: rgb(23 23 23 / var(--tw-ring-opacity, 1)); -} - -.focus\:ring-offset-2:focus{ - --tw-ring-offset-width: 2px; -} - -.focus-visible\:outline-none:focus-visible{ - outline: 2px solid transparent; - outline-offset: 2px; -} - -.focus-visible\:ring-2:focus-visible{ - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); -} - -.focus-visible\:ring-offset-2:focus-visible{ - --tw-ring-offset-width: 2px; -} - -.disabled\:pointer-events-none:disabled{ - pointer-events: none; -} - -.disabled\:cursor-not-allowed:disabled{ - cursor: not-allowed; -} - -.disabled\:opacity-50:disabled{ - opacity: 0.5; -} - -.group:hover .group-hover\:w-full{ - width: 100%; -} - -.group:hover .group-hover\:-rotate-6{ - --tw-rotate: -6deg; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.group:hover .group-hover\:scale-150{ - --tw-scale-x: 1.5; - --tw-scale-y: 1.5; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.group:hover .group-hover\:opacity-100{ - opacity: 1; -} - -.group:hover .group-hover\:\[animation-play-state\:paused\]{ - animation-play-state: paused; -} - -.peer:disabled ~ .peer-disabled\:cursor-not-allowed{ - cursor: not-allowed; -} - -.peer:disabled ~ .peer-disabled\:opacity-70{ - opacity: 0.7; -} - -@supports (overflow:clip){ - .supports-\[overflow\:clip\]\:overflow-clip{ - overflow: clip; - } -} - -@media not all and (min-width: 1024px){ - .max-lg\:w-32{ - width: 8rem; - } - - .max-lg\:after\:hidden::after{ - content: var(--tw-content); - display: none; - } -} - -@media not all and (min-width: 640px){ - .max-sm\:order-1{ - order: 1; - } -} - -@media (min-width: 640px){ - .sm\:col-span-2{ - grid-column: span 2 / span 2; - } - - .sm\:col-span-6{ - grid-column: span 6 / span 6; - } - - .sm\:mb-0{ - margin-bottom: 0px; - } - - .sm\:inline-flex{ - display: inline-flex; - } - - .sm\:h-auto{ - height: auto; - } - - .sm\:max-w-lg{ - max-width: 32rem; - } - - .sm\:max-w-none{ - max-width: none; - } - - .sm\:grid-cols-12{ - grid-template-columns: repeat(12, minmax(0, 1fr)); - } - - .sm\:grid-cols-2{ - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .sm\:flex-row{ - flex-direction: row; - } - - .sm\:justify-center{ - justify-content: center; - } - - .sm\:justify-between{ - justify-content: space-between; - } - - .sm\:gap-4{ - gap: 1rem; - } - - .sm\:space-x-2 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(0.5rem * var(--tw-space-x-reverse)); - margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); - } - - .sm\:space-x-4 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(1rem * var(--tw-space-x-reverse)); - margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); - } - - .sm\:space-y-0 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0px * var(--tw-space-y-reverse)); - } - - .sm\:rounded-lg{ - border-radius: 0.5rem; - } - - .sm\:object-contain{ - -o-object-fit: contain; - object-fit: contain; - } - - .sm\:px-6{ - padding-left: 1.5rem; - padding-right: 1.5rem; - } -} - -@media (min-width: 768px){ - .md\:top-6{ - top: 1.5rem; - } - - .md\:col-span-3{ - grid-column: span 3 / span 3; - } - - .md\:-mx-5{ - margin-left: -1.25rem; - margin-right: -1.25rem; - } - - .md\:mb-0{ - margin-bottom: 0px; - } - - .md\:max-w-none{ - max-width: none; - } - - .md\:grid-cols-3{ - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .md\:grid-cols-4{ - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - - .md\:flex-row{ - flex-direction: row; - } - - .md\:justify-start{ - justify-content: flex-start; - } - - .md\:gap-0{ - gap: 0px; - } - - .md\:gap-4{ - gap: 1rem; - } - - .md\:gap-6{ - gap: 1.5rem; - } - - .md\:px-5{ - padding-left: 1.25rem; - padding-right: 1.25rem; - } - - .md\:py-12{ - padding-top: 3rem; - padding-bottom: 3rem; - } - - .md\:py-20{ - padding-top: 5rem; - padding-bottom: 5rem; - } - - .md\:pb-16{ - padding-bottom: 4rem; - } - - .md\:pb-20{ - padding-bottom: 5rem; - } - - .md\:pt-40{ - padding-top: 10rem; - } - - .md\:text-3xl{ - font-size: 2rem; - line-height: 1.3125; - letter-spacing: -0.017em; - } - - .md\:text-4xl{ - font-size: 2.5rem; - line-height: 1.25; - letter-spacing: -0.017em; - } - - .md\:text-5xl{ - font-size: 3.25rem; - line-height: 1.2; - letter-spacing: -0.017em; - } - - .md\:after\:block::after{ - content: var(--tw-content); - display: block; - } -} - -@media (min-width: 1024px){ - .lg\:col-span-2{ - grid-column: span 2 / span 2; - } - - .lg\:col-span-6{ - grid-column: span 6 / span 6; - } - - .lg\:mb-0{ - margin-bottom: 0px; - } - - .lg\:mt-32{ - margin-top: 8rem; - } - - .lg\:block{ - display: block; - } - - .lg\:flex{ - display: flex; - } - - .lg\:h-5{ - height: 1.25rem; - } - - .lg\:min-w-\[524px\]{ - min-width: 524px; - } - - .lg\:max-w-6xl{ - max-width: 72rem; - } - - .lg\:max-w-none{ - max-width: none; - } - - .lg\:grid-cols-3{ - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .lg\:gap-16{ - gap: 4rem; - } - - .lg\:gap-8{ - gap: 2rem; - } - - .lg\:space-x-12 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(3rem * var(--tw-space-x-reverse)); - margin-left: calc(3rem * calc(1 - var(--tw-space-x-reverse))); - } - - .lg\:space-y-0 > :not([hidden]) ~ :not([hidden]){ - --tw-space-y-reverse: 0; - margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0px * var(--tw-space-y-reverse)); - } - - .lg\:p-24{ - padding: 6rem; - } - - .lg\:px-5{ - padding-left: 1.25rem; - padding-right: 1.25rem; - } - - .lg\:text-2xl{ - font-size: 1.5rem; - line-height: 1.415; - letter-spacing: -0.017em; - } - - .lg\:text-3xl{ - font-size: 2rem; - line-height: 1.3125; - letter-spacing: -0.017em; - } - - .lg\:text-xl{ - font-size: 1.25rem; - line-height: 1.5; - letter-spacing: -0.017em; - } -} - -@media (min-width: 1280px){ - .xl\:space-x-24 > :not([hidden]) ~ :not([hidden]){ - --tw-space-x-reverse: 0; - margin-right: calc(6rem * var(--tw-space-x-reverse)); - margin-left: calc(6rem * calc(1 - var(--tw-space-x-reverse))); - } -} - -.\[\&\>div\]\:mx-3>div{ - margin-left: 0.75rem; - margin-right: 0.75rem; -} - -.\[\&_\.active-breadcrumb\]\:font-medium .active-breadcrumb{ - font-weight: 500; -} - -.\[\&_\.active-breadcrumb\]\:text-neutral-600 .active-breadcrumb{ - --tw-text-opacity: 1; - color: rgb(82 82 82 / var(--tw-text-opacity, 1)); -} diff --git a/pkg/webapp/components/globals.css b/pkg/webapp/globals.css similarity index 100% rename from pkg/webapp/components/globals.css rename to pkg/webapp/globals.css diff --git a/pkg/webapp/package.json b/pkg/webapp/package.json index 88e2d0810..0d5f50433 100644 --- a/pkg/webapp/package.json +++ b/pkg/webapp/package.json @@ -2,7 +2,7 @@ "name": "@onsonr/nebula", "version": "0.0.2", "scripts": { - "build": "bunx tailwindcss -i ./components/globals.css -o ./components/styles/styles.css" + "build": "bunx tailwindcss -i ./globals.css -o ./dist/styles.css" }, "dependencies": { "@tailwindcss/forms": "^0.5.7", diff --git a/scripts/init_env.sh b/scripts/ipfs_config.sh similarity index 94% rename from scripts/init_env.sh rename to scripts/ipfs_config.sh index 1617e9d15..c490b5b5f 100755 --- a/scripts/init_env.sh +++ b/scripts/ipfs_config.sh @@ -1,7 +1,5 @@ #!/bin/bash -go install github.com/cosmos/gex@latest -go install github.com/apple/pkl-go/cmd/pkl-gen-go@latest rm -rf ~/.ipfs diff --git a/scripts/tailwindgen.sh b/scripts/tailwindgen.sh new file mode 100755 index 000000000..f3fecc0d7 --- /dev/null +++ b/scripts/tailwindgen.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e + +ROOT_DIR=$(git rev-parse --show-toplevel) +STYLES_DIR=$ROOT_DIR/pkg/webapp +DIST_DIR=$STYLES_DIR/dist +OUT_DIR=$ROOT_DIR/static/css + +cd $STYLES_DIR +bun install +bun run build +mkdir -p $OUT_DIR +mv $DIST_DIR/styles.css $OUT_DIR/styles.css +rm -rf $DIST_DIR +rm -rf $STYLES_DIR/node_modules + diff --git a/scripts/upload_pkl.sh b/scripts/upload_cdn.sh similarity index 77% rename from scripts/upload_pkl.sh rename to scripts/upload_cdn.sh index 425a8fd05..c807933b2 100755 --- a/scripts/upload_pkl.sh +++ b/scripts/upload_cdn.sh @@ -12,3 +12,6 @@ for dir in .out/*/; do done rm -rf .out + +rclone copy $ROOT_DIR/static "r2:nebula" +rm -rf $ROOT_DIR/static From 7a8707e5d0332c4ebbb7da2a777403bc5b45c51d Mon Sep 17 00:00:00 2001 From: "Prad Nukala (aider)" Date: Tue, 26 Nov 2024 13:13:53 -0500 Subject: [PATCH 18/30] refactor: Update Credential table to match WebAuthn Credential Descriptor --- proto/dwn/v1/state.proto | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/proto/dwn/v1/state.proto b/proto/dwn/v1/state.proto index 625ab05cf..0ac1efe51 100644 --- a/proto/dwn/v1/state.proto +++ b/proto/dwn/v1/state.proto @@ -10,12 +10,16 @@ option go_package = "github.com/onsonr/sonr/x/dwn/types"; message Credential { option (cosmos.orm.v1.table) = { id: 1; - primary_key: { fields: "account" } - index: { id: 1 fields: "amount" } + primary_key: { fields: "id" } + index: { id: 1 fields: "type" } }; - bytes account = 1; - uint64 amount = 2; + bytes id = 1; // The credential ID as a byte array + string type = 2; // The credential type (e.g. "public-key") + repeated string transports = 3; // Optional transport hints (usb, nfc, ble, internal) + bytes public_key = 4; // The credential's public key + string attestation_type = 5; // The attestation type used (e.g. "none", "indirect", etc) + uint64 created_at = 6; // Timestamp of when the credential was created } message Profile { From 4a8a15e4d6816ee01568e5e90f708049c3680395 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 26 Nov 2024 13:23:44 -0500 Subject: [PATCH 19/30] feat: add fast reflection methods for Capability and Resource --- api/dwn/v1/genesis.pulsar.go | 1155 ++++++++++++++++++++++- api/dwn/v1/state.cosmos_orm.go | 305 ------ api/dwn/v1/state.pulsar.go | 513 ++++++++-- docs/adrs/adr-1.md | 141 +++ docs/adrs/adr-2.md | 145 +++ docs/adrs/adr-3.md | 91 ++ docs/adrs/adr-4.md | 0 docs/reference/guides/cosmos-orm.md | 329 +++++++ docs/reference/guides/cosmos-sdk.md | 3 + docs/reference/guides/echo-framework.md | 3 + docs/reference/guides/templ-syntax.md | 3 + docs/reference/guides/wa-components.md | 3 + x/dwn/types/genesis.pb.go | 506 +++++++++- x/dwn/types/state.pb.go | 296 +++++- 14 files changed, 3010 insertions(+), 483 deletions(-) delete mode 100644 api/dwn/v1/state.cosmos_orm.go create mode 100644 docs/adrs/adr-1.md create mode 100644 docs/adrs/adr-2.md create mode 100644 docs/adrs/adr-3.md create mode 100644 docs/adrs/adr-4.md create mode 100644 docs/reference/guides/cosmos-orm.md create mode 100644 docs/reference/guides/cosmos-sdk.md create mode 100644 docs/reference/guides/echo-framework.md create mode 100644 docs/reference/guides/templ-syntax.md create mode 100644 docs/reference/guides/wa-components.md diff --git a/api/dwn/v1/genesis.pulsar.go b/api/dwn/v1/genesis.pulsar.go index c4ad51b96..fc3b4762f 100644 --- a/api/dwn/v1/genesis.pulsar.go +++ b/api/dwn/v1/genesis.pulsar.go @@ -992,6 +992,974 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { } } +var ( + md_Capability protoreflect.MessageDescriptor + fd_Capability_name protoreflect.FieldDescriptor + fd_Capability_description protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_genesis_proto_init() + md_Capability = File_dwn_v1_genesis_proto.Messages().ByName("Capability") + fd_Capability_name = md_Capability.Fields().ByName("name") + fd_Capability_description = md_Capability.Fields().ByName("description") +} + +var _ protoreflect.Message = (*fastReflection_Capability)(nil) + +type fastReflection_Capability Capability + +func (x *Capability) ProtoReflect() protoreflect.Message { + return (*fastReflection_Capability)(x) +} + +func (x *Capability) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_genesis_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Capability_messageType fastReflection_Capability_messageType +var _ protoreflect.MessageType = fastReflection_Capability_messageType{} + +type fastReflection_Capability_messageType struct{} + +func (x fastReflection_Capability_messageType) Zero() protoreflect.Message { + return (*fastReflection_Capability)(nil) +} +func (x fastReflection_Capability_messageType) New() protoreflect.Message { + return new(fastReflection_Capability) +} +func (x fastReflection_Capability_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Capability +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Capability) Descriptor() protoreflect.MessageDescriptor { + return md_Capability +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Capability) Type() protoreflect.MessageType { + return _fastReflection_Capability_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Capability) New() protoreflect.Message { + return new(fastReflection_Capability) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Capability) Interface() protoreflect.ProtoMessage { + return (*Capability)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Capability) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Name != "" { + value := protoreflect.ValueOfString(x.Name) + if !f(fd_Capability_name, value) { + return + } + } + if x.Description != "" { + value := protoreflect.ValueOfString(x.Description) + if !f(fd_Capability_description, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Capability) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.Capability.name": + return x.Name != "" + case "dwn.v1.Capability.description": + return x.Description != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) + } + panic(fmt.Errorf("message dwn.v1.Capability does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Capability) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.Capability.name": + x.Name = "" + case "dwn.v1.Capability.description": + x.Description = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) + } + panic(fmt.Errorf("message dwn.v1.Capability does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Capability) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.Capability.name": + value := x.Name + return protoreflect.ValueOfString(value) + case "dwn.v1.Capability.description": + value := x.Description + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) + } + panic(fmt.Errorf("message dwn.v1.Capability does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Capability) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.Capability.name": + x.Name = value.Interface().(string) + case "dwn.v1.Capability.description": + x.Description = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) + } + panic(fmt.Errorf("message dwn.v1.Capability does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Capability) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Capability.name": + panic(fmt.Errorf("field name of message dwn.v1.Capability is not mutable")) + case "dwn.v1.Capability.description": + panic(fmt.Errorf("field description of message dwn.v1.Capability is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) + } + panic(fmt.Errorf("message dwn.v1.Capability does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Capability) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Capability.name": + return protoreflect.ValueOfString("") + case "dwn.v1.Capability.description": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) + } + panic(fmt.Errorf("message dwn.v1.Capability does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Capability) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.Capability", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Capability) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Capability) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Capability) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Capability) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Capability) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Name) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Description) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Capability) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Description) > 0 { + i -= len(x.Description) + copy(dAtA[i:], x.Description) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Description))) + i-- + dAtA[i] = 0x12 + } + if len(x.Name) > 0 { + i -= len(x.Name) + copy(dAtA[i:], x.Name) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Capability) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Capability: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Capability: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_Resource protoreflect.MessageDescriptor + fd_Resource_name protoreflect.FieldDescriptor + fd_Resource_description protoreflect.FieldDescriptor +) + +func init() { + file_dwn_v1_genesis_proto_init() + md_Resource = File_dwn_v1_genesis_proto.Messages().ByName("Resource") + fd_Resource_name = md_Resource.Fields().ByName("name") + fd_Resource_description = md_Resource.Fields().ByName("description") +} + +var _ protoreflect.Message = (*fastReflection_Resource)(nil) + +type fastReflection_Resource Resource + +func (x *Resource) ProtoReflect() protoreflect.Message { + return (*fastReflection_Resource)(x) +} + +func (x *Resource) slowProtoReflect() protoreflect.Message { + mi := &file_dwn_v1_genesis_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Resource_messageType fastReflection_Resource_messageType +var _ protoreflect.MessageType = fastReflection_Resource_messageType{} + +type fastReflection_Resource_messageType struct{} + +func (x fastReflection_Resource_messageType) Zero() protoreflect.Message { + return (*fastReflection_Resource)(nil) +} +func (x fastReflection_Resource_messageType) New() protoreflect.Message { + return new(fastReflection_Resource) +} +func (x fastReflection_Resource_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Resource +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Resource) Descriptor() protoreflect.MessageDescriptor { + return md_Resource +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Resource) Type() protoreflect.MessageType { + return _fastReflection_Resource_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Resource) New() protoreflect.Message { + return new(fastReflection_Resource) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Resource) Interface() protoreflect.ProtoMessage { + return (*Resource)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Resource) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Name != "" { + value := protoreflect.ValueOfString(x.Name) + if !f(fd_Resource_name, value) { + return + } + } + if x.Description != "" { + value := protoreflect.ValueOfString(x.Description) + if !f(fd_Resource_description, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Resource) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "dwn.v1.Resource.name": + return x.Name != "" + case "dwn.v1.Resource.description": + return x.Description != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) + } + panic(fmt.Errorf("message dwn.v1.Resource does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Resource) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "dwn.v1.Resource.name": + x.Name = "" + case "dwn.v1.Resource.description": + x.Description = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) + } + panic(fmt.Errorf("message dwn.v1.Resource does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Resource) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "dwn.v1.Resource.name": + value := x.Name + return protoreflect.ValueOfString(value) + case "dwn.v1.Resource.description": + value := x.Description + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) + } + panic(fmt.Errorf("message dwn.v1.Resource does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Resource) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "dwn.v1.Resource.name": + x.Name = value.Interface().(string) + case "dwn.v1.Resource.description": + x.Description = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) + } + panic(fmt.Errorf("message dwn.v1.Resource does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Resource) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Resource.name": + panic(fmt.Errorf("field name of message dwn.v1.Resource is not mutable")) + case "dwn.v1.Resource.description": + panic(fmt.Errorf("field description of message dwn.v1.Resource is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) + } + panic(fmt.Errorf("message dwn.v1.Resource does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Resource) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "dwn.v1.Resource.name": + return protoreflect.ValueOfString("") + case "dwn.v1.Resource.description": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) + } + panic(fmt.Errorf("message dwn.v1.Resource does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Resource) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in dwn.v1.Resource", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Resource) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Resource) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Resource) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Resource) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Resource) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Name) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Description) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Resource) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Description) > 0 { + i -= len(x.Description) + copy(dAtA[i:], x.Description) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Description))) + i-- + dAtA[i] = 0x12 + } + if len(x.Name) > 0 { + i -= len(x.Name) + copy(dAtA[i:], x.Name) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Resource) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Resource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Resource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + var ( md_Schema protoreflect.MessageDescriptor fd_Schema_version protoreflect.FieldDescriptor @@ -1030,7 +1998,7 @@ func (x *Schema) ProtoReflect() protoreflect.Message { } func (x *Schema) slowProtoReflect() protoreflect.Message { - mi := &file_dwn_v1_genesis_proto_msgTypes[2] + mi := &file_dwn_v1_genesis_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2074,6 +3042,95 @@ func (x *Params) GetSchema() *Schema { return nil } +// Capability reprensents the available capabilities of a decentralized web node +type Capability struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *Capability) Reset() { + *x = Capability{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_genesis_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Capability) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Capability) ProtoMessage() {} + +// Deprecated: Use Capability.ProtoReflect.Descriptor instead. +func (*Capability) Descriptor() ([]byte, []int) { + return file_dwn_v1_genesis_proto_rawDescGZIP(), []int{2} +} + +func (x *Capability) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Capability) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +// Resource reprensents the available resources of a decentralized web node +type Resource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *Resource) Reset() { + *x = Resource{} + if protoimpl.UnsafeEnabled { + mi := &file_dwn_v1_genesis_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Resource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Resource) ProtoMessage() {} + +// Deprecated: Use Resource.ProtoReflect.Descriptor instead. +func (*Resource) Descriptor() ([]byte, []int) { + return file_dwn_v1_genesis_proto_rawDescGZIP(), []int{3} +} + +func (x *Resource) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Resource) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +// Schema is the Database Model for Decentralized Web Nodes type Schema struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2094,7 +3151,7 @@ type Schema struct { func (x *Schema) Reset() { *x = Schema{} if protoimpl.UnsafeEnabled { - mi := &file_dwn_v1_genesis_proto_msgTypes[2] + mi := &file_dwn_v1_genesis_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2108,7 +3165,7 @@ func (*Schema) ProtoMessage() {} // Deprecated: Use Schema.ProtoReflect.Descriptor instead. func (*Schema) Descriptor() ([]byte, []int) { - return file_dwn_v1_genesis_proto_rawDescGZIP(), []int{2} + return file_dwn_v1_genesis_proto_rawDescGZIP(), []int{4} } func (x *Schema) GetVersion() int32 { @@ -2203,31 +3260,39 @@ var file_dwn_v1_genesis_proto_rawDesc = []byte{ 0x0e, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x19, 0x98, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x22, 0xf8, 0x01, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x10, 0x0a, - 0x03, 0x64, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, - 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, - 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x68, - 0x61, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x68, - 0x61, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x7c, 0x0a, - 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, - 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, - 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, - 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, - 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, - 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x6d, 0x73, 0x22, 0x42, 0x0a, 0x0a, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x40, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf8, 0x01, 0x0a, 0x06, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x73, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x64, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x6b, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x6b, 0x65, 0x79, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6b, 0x65, 0x79, 0x73, 0x68, 0x61, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x42, 0x7c, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, + 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, + 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x77, + 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, + 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2242,15 +3307,17 @@ func file_dwn_v1_genesis_proto_rawDescGZIP() []byte { return file_dwn_v1_genesis_proto_rawDescData } -var file_dwn_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_dwn_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_dwn_v1_genesis_proto_goTypes = []interface{}{ (*GenesisState)(nil), // 0: dwn.v1.GenesisState (*Params)(nil), // 1: dwn.v1.Params - (*Schema)(nil), // 2: dwn.v1.Schema + (*Capability)(nil), // 2: dwn.v1.Capability + (*Resource)(nil), // 3: dwn.v1.Resource + (*Schema)(nil), // 4: dwn.v1.Schema } var file_dwn_v1_genesis_proto_depIdxs = []int32{ 1, // 0: dwn.v1.GenesisState.params:type_name -> dwn.v1.Params - 2, // 1: dwn.v1.Params.schema:type_name -> dwn.v1.Schema + 4, // 1: dwn.v1.Params.schema:type_name -> dwn.v1.Schema 2, // [2:2] is the sub-list for method output_type 2, // [2:2] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name @@ -2289,6 +3356,30 @@ func file_dwn_v1_genesis_proto_init() { } } file_dwn_v1_genesis_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Capability); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_genesis_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Resource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dwn_v1_genesis_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Schema); i { case 0: return &v.state @@ -2307,7 +3398,7 @@ func file_dwn_v1_genesis_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_dwn_v1_genesis_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/api/dwn/v1/state.cosmos_orm.go b/api/dwn/v1/state.cosmos_orm.go deleted file mode 100644 index a6aa6c240..000000000 --- a/api/dwn/v1/state.cosmos_orm.go +++ /dev/null @@ -1,305 +0,0 @@ -// Code generated by protoc-gen-go-cosmos-orm. DO NOT EDIT. - -package dwnv1 - -import ( - context "context" - ormlist "cosmossdk.io/orm/model/ormlist" - ormtable "cosmossdk.io/orm/model/ormtable" - ormerrors "cosmossdk.io/orm/types/ormerrors" -) - -type CredentialTable interface { - Insert(ctx context.Context, credential *Credential) error - Update(ctx context.Context, credential *Credential) error - Save(ctx context.Context, credential *Credential) error - Delete(ctx context.Context, credential *Credential) error - Has(ctx context.Context, account []byte) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, account []byte) (*Credential, error) - List(ctx context.Context, prefixKey CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) - ListRange(ctx context.Context, from, to CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) - DeleteBy(ctx context.Context, prefixKey CredentialIndexKey) error - DeleteRange(ctx context.Context, from, to CredentialIndexKey) error - - doNotImplement() -} - -type CredentialIterator struct { - ormtable.Iterator -} - -func (i CredentialIterator) Value() (*Credential, error) { - var credential Credential - err := i.UnmarshalMessage(&credential) - return &credential, err -} - -type CredentialIndexKey interface { - id() uint32 - values() []interface{} - credentialIndexKey() -} - -// primary key starting index.. -type CredentialPrimaryKey = CredentialAccountIndexKey - -type CredentialAccountIndexKey struct { - vs []interface{} -} - -func (x CredentialAccountIndexKey) id() uint32 { return 0 } -func (x CredentialAccountIndexKey) values() []interface{} { return x.vs } -func (x CredentialAccountIndexKey) credentialIndexKey() {} - -func (this CredentialAccountIndexKey) WithAccount(account []byte) CredentialAccountIndexKey { - this.vs = []interface{}{account} - return this -} - -type CredentialAmountIndexKey struct { - vs []interface{} -} - -func (x CredentialAmountIndexKey) id() uint32 { return 1 } -func (x CredentialAmountIndexKey) values() []interface{} { return x.vs } -func (x CredentialAmountIndexKey) credentialIndexKey() {} - -func (this CredentialAmountIndexKey) WithAmount(amount uint64) CredentialAmountIndexKey { - this.vs = []interface{}{amount} - return this -} - -type credentialTable struct { - table ormtable.Table -} - -func (this credentialTable) Insert(ctx context.Context, credential *Credential) error { - return this.table.Insert(ctx, credential) -} - -func (this credentialTable) Update(ctx context.Context, credential *Credential) error { - return this.table.Update(ctx, credential) -} - -func (this credentialTable) Save(ctx context.Context, credential *Credential) error { - return this.table.Save(ctx, credential) -} - -func (this credentialTable) Delete(ctx context.Context, credential *Credential) error { - return this.table.Delete(ctx, credential) -} - -func (this credentialTable) Has(ctx context.Context, account []byte) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, account) -} - -func (this credentialTable) Get(ctx context.Context, account []byte) (*Credential, error) { - var credential Credential - found, err := this.table.PrimaryKey().Get(ctx, &credential, account) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &credential, nil -} - -func (this credentialTable) List(ctx context.Context, prefixKey CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return CredentialIterator{it}, err -} - -func (this credentialTable) ListRange(ctx context.Context, from, to CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return CredentialIterator{it}, err -} - -func (this credentialTable) DeleteBy(ctx context.Context, prefixKey CredentialIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this credentialTable) DeleteRange(ctx context.Context, from, to CredentialIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this credentialTable) doNotImplement() {} - -var _ CredentialTable = credentialTable{} - -func NewCredentialTable(db ormtable.Schema) (CredentialTable, error) { - table := db.GetTable(&Credential{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Credential{}).ProtoReflect().Descriptor().FullName())) - } - return credentialTable{table}, nil -} - -type ProfileTable interface { - Insert(ctx context.Context, profile *Profile) error - Update(ctx context.Context, profile *Profile) error - Save(ctx context.Context, profile *Profile) error - Delete(ctx context.Context, profile *Profile) error - Has(ctx context.Context, account []byte) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, account []byte) (*Profile, error) - List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) - ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) - DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error - DeleteRange(ctx context.Context, from, to ProfileIndexKey) error - - doNotImplement() -} - -type ProfileIterator struct { - ormtable.Iterator -} - -func (i ProfileIterator) Value() (*Profile, error) { - var profile Profile - err := i.UnmarshalMessage(&profile) - return &profile, err -} - -type ProfileIndexKey interface { - id() uint32 - values() []interface{} - profileIndexKey() -} - -// primary key starting index.. -type ProfilePrimaryKey = ProfileAccountIndexKey - -type ProfileAccountIndexKey struct { - vs []interface{} -} - -func (x ProfileAccountIndexKey) id() uint32 { return 0 } -func (x ProfileAccountIndexKey) values() []interface{} { return x.vs } -func (x ProfileAccountIndexKey) profileIndexKey() {} - -func (this ProfileAccountIndexKey) WithAccount(account []byte) ProfileAccountIndexKey { - this.vs = []interface{}{account} - return this -} - -type ProfileAmountIndexKey struct { - vs []interface{} -} - -func (x ProfileAmountIndexKey) id() uint32 { return 1 } -func (x ProfileAmountIndexKey) values() []interface{} { return x.vs } -func (x ProfileAmountIndexKey) profileIndexKey() {} - -func (this ProfileAmountIndexKey) WithAmount(amount uint64) ProfileAmountIndexKey { - this.vs = []interface{}{amount} - return this -} - -type profileTable struct { - table ormtable.Table -} - -func (this profileTable) Insert(ctx context.Context, profile *Profile) error { - return this.table.Insert(ctx, profile) -} - -func (this profileTable) Update(ctx context.Context, profile *Profile) error { - return this.table.Update(ctx, profile) -} - -func (this profileTable) Save(ctx context.Context, profile *Profile) error { - return this.table.Save(ctx, profile) -} - -func (this profileTable) Delete(ctx context.Context, profile *Profile) error { - return this.table.Delete(ctx, profile) -} - -func (this profileTable) Has(ctx context.Context, account []byte) (found bool, err error) { - return this.table.PrimaryKey().Has(ctx, account) -} - -func (this profileTable) Get(ctx context.Context, account []byte) (*Profile, error) { - var profile Profile - found, err := this.table.PrimaryKey().Get(ctx, &profile, account) - if err != nil { - return nil, err - } - if !found { - return nil, ormerrors.NotFound - } - return &profile, nil -} - -func (this profileTable) List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { - it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) - return ProfileIterator{it}, err -} - -func (this profileTable) ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { - it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) - return ProfileIterator{it}, err -} - -func (this profileTable) DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error { - return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) -} - -func (this profileTable) DeleteRange(ctx context.Context, from, to ProfileIndexKey) error { - return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) -} - -func (this profileTable) doNotImplement() {} - -var _ ProfileTable = profileTable{} - -func NewProfileTable(db ormtable.Schema) (ProfileTable, error) { - table := db.GetTable(&Profile{}) - if table == nil { - return nil, ormerrors.TableNotFound.Wrap(string((&Profile{}).ProtoReflect().Descriptor().FullName())) - } - return profileTable{table}, nil -} - -type StateStore interface { - CredentialTable() CredentialTable - ProfileTable() ProfileTable - - doNotImplement() -} - -type stateStore struct { - credential CredentialTable - profile ProfileTable -} - -func (x stateStore) CredentialTable() CredentialTable { - return x.credential -} - -func (x stateStore) ProfileTable() ProfileTable { - return x.profile -} - -func (stateStore) doNotImplement() {} - -var _ StateStore = stateStore{} - -func NewStateStore(db ormtable.Schema) (StateStore, error) { - credentialTable, err := NewCredentialTable(db) - if err != nil { - return nil, err - } - - profileTable, err := NewProfileTable(db) - if err != nil { - return nil, err - } - - return stateStore{ - credentialTable, - profileTable, - }, nil -} diff --git a/api/dwn/v1/state.pulsar.go b/api/dwn/v1/state.pulsar.go index eba069b68..58b193c4f 100644 --- a/api/dwn/v1/state.pulsar.go +++ b/api/dwn/v1/state.pulsar.go @@ -13,17 +13,71 @@ import ( sync "sync" ) +var _ protoreflect.List = (*_Credential_3_list)(nil) + +type _Credential_3_list struct { + list *[]string +} + +func (x *_Credential_3_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Credential_3_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Credential_3_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Credential_3_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Credential_3_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Credential at list field Transports as it is not of Message kind")) +} + +func (x *_Credential_3_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Credential_3_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Credential_3_list) IsValid() bool { + return x.list != nil +} + var ( - md_Credential protoreflect.MessageDescriptor - fd_Credential_account protoreflect.FieldDescriptor - fd_Credential_amount protoreflect.FieldDescriptor + md_Credential protoreflect.MessageDescriptor + fd_Credential_id protoreflect.FieldDescriptor + fd_Credential_type protoreflect.FieldDescriptor + fd_Credential_transports protoreflect.FieldDescriptor + fd_Credential_public_key protoreflect.FieldDescriptor + fd_Credential_attestation_type protoreflect.FieldDescriptor + fd_Credential_created_at protoreflect.FieldDescriptor ) func init() { file_dwn_v1_state_proto_init() md_Credential = File_dwn_v1_state_proto.Messages().ByName("Credential") - fd_Credential_account = md_Credential.Fields().ByName("account") - fd_Credential_amount = md_Credential.Fields().ByName("amount") + fd_Credential_id = md_Credential.Fields().ByName("id") + fd_Credential_type = md_Credential.Fields().ByName("type") + fd_Credential_transports = md_Credential.Fields().ByName("transports") + fd_Credential_public_key = md_Credential.Fields().ByName("public_key") + fd_Credential_attestation_type = md_Credential.Fields().ByName("attestation_type") + fd_Credential_created_at = md_Credential.Fields().ByName("created_at") } var _ protoreflect.Message = (*fastReflection_Credential)(nil) @@ -91,15 +145,39 @@ func (x *fastReflection_Credential) Interface() protoreflect.ProtoMessage { // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_Credential) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if len(x.Account) != 0 { - value := protoreflect.ValueOfBytes(x.Account) - if !f(fd_Credential_account, value) { + if len(x.Id) != 0 { + value := protoreflect.ValueOfBytes(x.Id) + if !f(fd_Credential_id, value) { return } } - if x.Amount != uint64(0) { - value := protoreflect.ValueOfUint64(x.Amount) - if !f(fd_Credential_amount, value) { + if x.Type_ != "" { + value := protoreflect.ValueOfString(x.Type_) + if !f(fd_Credential_type, value) { + return + } + } + if len(x.Transports) != 0 { + value := protoreflect.ValueOfList(&_Credential_3_list{list: &x.Transports}) + if !f(fd_Credential_transports, value) { + return + } + } + if len(x.PublicKey) != 0 { + value := protoreflect.ValueOfBytes(x.PublicKey) + if !f(fd_Credential_public_key, value) { + return + } + } + if x.AttestationType != "" { + value := protoreflect.ValueOfString(x.AttestationType) + if !f(fd_Credential_attestation_type, value) { + return + } + } + if x.CreatedAt != uint64(0) { + value := protoreflect.ValueOfUint64(x.CreatedAt) + if !f(fd_Credential_created_at, value) { return } } @@ -118,10 +196,18 @@ func (x *fastReflection_Credential) Range(f func(protoreflect.FieldDescriptor, p // a repeated field is populated if it is non-empty. func (x *fastReflection_Credential) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "dwn.v1.Credential.account": - return len(x.Account) != 0 - case "dwn.v1.Credential.amount": - return x.Amount != uint64(0) + case "dwn.v1.Credential.id": + return len(x.Id) != 0 + case "dwn.v1.Credential.type": + return x.Type_ != "" + case "dwn.v1.Credential.transports": + return len(x.Transports) != 0 + case "dwn.v1.Credential.public_key": + return len(x.PublicKey) != 0 + case "dwn.v1.Credential.attestation_type": + return x.AttestationType != "" + case "dwn.v1.Credential.created_at": + return x.CreatedAt != uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) @@ -138,10 +224,18 @@ func (x *fastReflection_Credential) Has(fd protoreflect.FieldDescriptor) bool { // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Credential) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "dwn.v1.Credential.account": - x.Account = nil - case "dwn.v1.Credential.amount": - x.Amount = uint64(0) + case "dwn.v1.Credential.id": + x.Id = nil + case "dwn.v1.Credential.type": + x.Type_ = "" + case "dwn.v1.Credential.transports": + x.Transports = nil + case "dwn.v1.Credential.public_key": + x.PublicKey = nil + case "dwn.v1.Credential.attestation_type": + x.AttestationType = "" + case "dwn.v1.Credential.created_at": + x.CreatedAt = uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) @@ -158,11 +252,26 @@ func (x *fastReflection_Credential) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_Credential) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "dwn.v1.Credential.account": - value := x.Account + case "dwn.v1.Credential.id": + value := x.Id return protoreflect.ValueOfBytes(value) - case "dwn.v1.Credential.amount": - value := x.Amount + case "dwn.v1.Credential.type": + value := x.Type_ + return protoreflect.ValueOfString(value) + case "dwn.v1.Credential.transports": + if len(x.Transports) == 0 { + return protoreflect.ValueOfList(&_Credential_3_list{}) + } + listValue := &_Credential_3_list{list: &x.Transports} + return protoreflect.ValueOfList(listValue) + case "dwn.v1.Credential.public_key": + value := x.PublicKey + return protoreflect.ValueOfBytes(value) + case "dwn.v1.Credential.attestation_type": + value := x.AttestationType + return protoreflect.ValueOfString(value) + case "dwn.v1.Credential.created_at": + value := x.CreatedAt return protoreflect.ValueOfUint64(value) default: if descriptor.IsExtension() { @@ -184,10 +293,20 @@ func (x *fastReflection_Credential) Get(descriptor protoreflect.FieldDescriptor) // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Credential) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "dwn.v1.Credential.account": - x.Account = value.Bytes() - case "dwn.v1.Credential.amount": - x.Amount = value.Uint() + case "dwn.v1.Credential.id": + x.Id = value.Bytes() + case "dwn.v1.Credential.type": + x.Type_ = value.Interface().(string) + case "dwn.v1.Credential.transports": + lv := value.List() + clv := lv.(*_Credential_3_list) + x.Transports = *clv.list + case "dwn.v1.Credential.public_key": + x.PublicKey = value.Bytes() + case "dwn.v1.Credential.attestation_type": + x.AttestationType = value.Interface().(string) + case "dwn.v1.Credential.created_at": + x.CreatedAt = value.Uint() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) @@ -208,10 +327,22 @@ func (x *fastReflection_Credential) Set(fd protoreflect.FieldDescriptor, value p // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Credential) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "dwn.v1.Credential.account": - panic(fmt.Errorf("field account of message dwn.v1.Credential is not mutable")) - case "dwn.v1.Credential.amount": - panic(fmt.Errorf("field amount of message dwn.v1.Credential is not mutable")) + case "dwn.v1.Credential.transports": + if x.Transports == nil { + x.Transports = []string{} + } + value := &_Credential_3_list{list: &x.Transports} + return protoreflect.ValueOfList(value) + case "dwn.v1.Credential.id": + panic(fmt.Errorf("field id of message dwn.v1.Credential is not mutable")) + case "dwn.v1.Credential.type": + panic(fmt.Errorf("field type of message dwn.v1.Credential is not mutable")) + case "dwn.v1.Credential.public_key": + panic(fmt.Errorf("field public_key of message dwn.v1.Credential is not mutable")) + case "dwn.v1.Credential.attestation_type": + panic(fmt.Errorf("field attestation_type of message dwn.v1.Credential is not mutable")) + case "dwn.v1.Credential.created_at": + panic(fmt.Errorf("field created_at of message dwn.v1.Credential is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Credential")) @@ -225,9 +356,18 @@ func (x *fastReflection_Credential) Mutable(fd protoreflect.FieldDescriptor) pro // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_Credential) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "dwn.v1.Credential.account": + case "dwn.v1.Credential.id": return protoreflect.ValueOfBytes(nil) - case "dwn.v1.Credential.amount": + case "dwn.v1.Credential.type": + return protoreflect.ValueOfString("") + case "dwn.v1.Credential.transports": + list := []string{} + return protoreflect.ValueOfList(&_Credential_3_list{list: &list}) + case "dwn.v1.Credential.public_key": + return protoreflect.ValueOfBytes(nil) + case "dwn.v1.Credential.attestation_type": + return protoreflect.ValueOfString("") + case "dwn.v1.Credential.created_at": return protoreflect.ValueOfUint64(uint64(0)) default: if fd.IsExtension() { @@ -298,12 +438,30 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { var n int var l int _ = l - l = len(x.Account) + l = len(x.Id) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if x.Amount != 0 { - n += 1 + runtime.Sov(uint64(x.Amount)) + l = len(x.Type_) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.Transports) > 0 { + for _, s := range x.Transports { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + l = len(x.PublicKey) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.AttestationType) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.CreatedAt != 0 { + n += 1 + runtime.Sov(uint64(x.CreatedAt)) } if x.unknownFields != nil { n += len(x.unknownFields) @@ -334,15 +492,45 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if x.Amount != 0 { - i = runtime.EncodeVarint(dAtA, i, uint64(x.Amount)) + if x.CreatedAt != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.CreatedAt)) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x30 } - if len(x.Account) > 0 { - i -= len(x.Account) - copy(dAtA[i:], x.Account) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Account))) + if len(x.AttestationType) > 0 { + i -= len(x.AttestationType) + copy(dAtA[i:], x.AttestationType) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.AttestationType))) + i-- + dAtA[i] = 0x2a + } + if len(x.PublicKey) > 0 { + i -= len(x.PublicKey) + copy(dAtA[i:], x.PublicKey) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicKey))) + i-- + dAtA[i] = 0x22 + } + if len(x.Transports) > 0 { + for iNdEx := len(x.Transports) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Transports[iNdEx]) + copy(dAtA[i:], x.Transports[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Transports[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(x.Type_) > 0 { + i -= len(x.Type_) + copy(dAtA[i:], x.Type_) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Type_))) + i-- + dAtA[i] = 0x12 + } + if len(x.Id) > 0 { + i -= len(x.Id) + copy(dAtA[i:], x.Id) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Id))) i-- dAtA[i] = 0xa } @@ -397,7 +585,7 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { switch fieldNum { case 1: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -424,16 +612,16 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Account = append(x.Account[:0], dAtA[iNdEx:postIndex]...) - if x.Account == nil { - x.Account = []byte{} + x.Id = append(x.Id[:0], dAtA[iNdEx:postIndex]...) + if x.Id == nil { + x.Id = []byte{} } iNdEx = postIndex case 2: - if wireType != 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Type_", wireType) } - x.Amount = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -443,7 +631,137 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - x.Amount |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Type_ = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Transports", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Transports = append(x.Transports, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PublicKey = append(x.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if x.PublicKey == nil { + x.PublicKey = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AttestationType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.AttestationType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CreatedAt", wireType) + } + x.CreatedAt = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.CreatedAt |= uint64(b&0x7F) << shift if b < 0x80 { break } @@ -971,8 +1289,12 @@ type Credential struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Account []byte `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` - Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The credential ID as a byte array + Type_ string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // The credential type (e.g. "public-key") + Transports []string `protobuf:"bytes,3,rep,name=transports,proto3" json:"transports,omitempty"` // Optional transport hints (usb, nfc, ble, internal) + PublicKey []byte `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` // The credential's public key + AttestationType string `protobuf:"bytes,5,opt,name=attestation_type,json=attestationType,proto3" json:"attestation_type,omitempty"` // The attestation type used (e.g. "none", "indirect", etc) + CreatedAt uint64 `protobuf:"varint,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp of when the credential was created } func (x *Credential) Reset() { @@ -995,16 +1317,44 @@ func (*Credential) Descriptor() ([]byte, []int) { return file_dwn_v1_state_proto_rawDescGZIP(), []int{0} } -func (x *Credential) GetAccount() []byte { +func (x *Credential) GetId() []byte { if x != nil { - return x.Account + return x.Id } return nil } -func (x *Credential) GetAmount() uint64 { +func (x *Credential) GetType_() string { if x != nil { - return x.Amount + return x.Type_ + } + return "" +} + +func (x *Credential) GetTransports() []string { + if x != nil { + return x.Transports + } + return nil +} + +func (x *Credential) GetPublicKey() []byte { + if x != nil { + return x.PublicKey + } + return nil +} + +func (x *Credential) GetAttestationType() string { + if x != nil { + return x.AttestationType + } + return "" +} + +func (x *Credential) GetCreatedAt() uint64 { + if x != nil { + return x.CreatedAt } return 0 } @@ -1058,27 +1408,34 @@ var file_dwn_v1_state_proto_rawDesc = []byte{ 0x0a, 0x12, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x09, 0x0a, - 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x10, 0x01, 0x18, 0x01, 0x22, 0x5c, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x09, 0x0a, 0x07, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x10, 0x01, 0x18, 0x02, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, - 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, - 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x77, 0x6e, - 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, - 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x5c, 0x56, - 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, 0x3a, 0x56, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd3, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x3a, 0x18, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x12, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x12, + 0x08, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x10, 0x01, 0x18, 0x01, 0x22, 0x5c, 0x0a, 0x07, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, + 0x0a, 0x09, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x01, 0x18, 0x02, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, + 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, + 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, + 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, + 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/docs/adrs/adr-1.md b/docs/adrs/adr-1.md new file mode 100644 index 000000000..e687d0d40 --- /dev/null +++ b/docs/adrs/adr-1.md @@ -0,0 +1,141 @@ +# `x/did` + +The Decentralized Identity module is responsible for managing native Sonr Accounts, their derived wallets, and associated user identification information. + +## State + +The DID module maintains several key state structures: + +### Controller State + +The Controller state represents a Sonr DWN Vault. It includes: +- Unique identifier (number) +- DID +- Sonr address +- Ethereum address +- Bitcoin address +- Public key +- Keyshares pointer +- Claimed block +- Creation block + +### Assertion State + +The Assertion state includes: +- DID +- Controller +- Subject +- Public key +- Assertion type +- Accumulator (metadata) +- Creation block + +### Authentication State + +The Authentication state includes: +- DID +- Controller +- Subject +- Public key +- Credential ID +- Metadata +- Creation block + +### Verification State + +The Verification state includes: +- DID +- Controller +- DID method +- Issuer +- Subject +- Public key +- Verification type +- Metadata +- Creation block + +## State Transitions + +State transitions are triggered by the following messages: +- LinkAssertion +- LinkAuthentication +- UnlinkAssertion +- UnlinkAuthentication +- ExecuteTx +- UpdateParams + +## Messages + +The DID module defines the following messages: + +1. MsgLinkAuthentication +2. MsgLinkAssertion +3. MsgExecuteTx +4. MsgUnlinkAssertion +5. MsgUnlinkAuthentication +6. MsgUpdateParams + +Each message triggers specific state machine behaviors related to managing DIDs, authentications, assertions, and module parameters. + +## Query + +The DID module provides the following query endpoints: + +1. Params: Query all parameters of the module +2. Resolve: Query the DID document by its ID +3. Sign: Sign a message with the DID document +4. Verify: Verify a message with the DID document + +## Params + +The module parameters include: +- Allowed public keys (map of KeyInfo) +- Conveyance preference +- Attestation formats + +## Client + +The module provides gRPC and REST endpoints for all defined messages and queries. + +## Future Improvements + +Potential future improvements could include: +1. Enhanced privacy features for DID operations +2. Integration with more blockchain networks +3. Support for additional key types and cryptographic algorithms +4. Improved revocation mechanisms for credentials and assertions + +## Tests + +Acceptance tests should cover all major functionality, including: +- Creating and managing DIDs +- Linking and unlinking assertions and authentications +- Executing transactions with DIDs +- Querying and resolving DIDs +- Parameter updates + +## Appendix + +### Account + +An Account represents a user's identity within the Sonr ecosystem. It includes information such as the user's public key, associated wallets, and other identification details. + +### Decentralized Identifier (DID) + +A Decentralized Identifier (DID) is a unique identifier that is created, owned, and controlled by the user. It is used to establish a secure and verifiable digital identity. + +### Verifiable Credential (VC) + +A Verifiable Credential (VC) is a digital statement that can be cryptographically verified. It contains claims about a subject (e.g., a user) and is issued by a trusted authority. + +### Key Types + +The module supports various key types, including: +- Role +- Algorithm (e.g., ES256, EdDSA, ES256K) +- Encoding (e.g., hex, base64, multibase) +- Curve (e.g., P256, P384, P521, X25519, X448, Ed25519, Ed448, secp256k1) + +### JSON Web Key (JWK) + +The module supports JSON Web Keys (JWK) for representing cryptographic keys, including properties such as key type (kty), curve (crv), and coordinates (x, y) for EC and OKP keys, as well as modulus (n) and exponent (e) for RSA keys. diff --git a/docs/adrs/adr-2.md b/docs/adrs/adr-2.md new file mode 100644 index 000000000..ecca8c15a --- /dev/null +++ b/docs/adrs/adr-2.md @@ -0,0 +1,145 @@ +# `x/dwn` + +The DWN module is responsible for the management of IPFS deployed Decentralized Web Nodes (DWNs) and their associated data. + +## Concepts + +The DWN module introduces several key concepts: + +1. Decentralized Web Node (DWN): A distributed network for storing and sharing data. +2. Schema: A structure defining the format of various data types in the dwn. +3. IPFS Integration: The module can interact with IPFS for decentralized data storage. + +## State + +The DWN module maintains the following state: + +### DWN State + +The DWN state is stored using the following structure: + +```protobuf +message DWN { + uint64 id = 1; + string alias = 2; + string cid = 3; + string resolver = 4; +} +``` + +This state is indexed by ID, alias, and CID for efficient querying. + +### Params State + +The module parameters are stored in the following structure: + +```protobuf +message Params { + bool ipfs_active = 1; + bool local_registration_enabled = 2; + Schema schema = 4; +} +``` + +### Schema State + +The Schema state defines the structure for various data types: + +```protobuf +message Schema { + int32 version = 1; + string account = 2; + string asset = 3; + string chain = 4; + string credential = 5; + string did = 6; + string jwk = 7; + string grant = 8; + string keyshare = 9; + string profile = 10; +} +``` + +## State Transitions + +State transitions in the DWN module are primarily triggered by: + +1. Updating module parameters +2. Allocating new dwns +3. Syncing DID documents + +## Messages + +The DWN module defines the following message: + +1. `MsgUpdateParams`: Used to update the module parameters. + +```protobuf +message MsgUpdateParams { + string authority = 1; + Params params = 2; +} +``` + +## Begin Block + +No specific begin-block operations are defined for this module. + +## End Block + +No specific end-block operations are defined for this module. + +## Hooks + +The DWN module does not define any hooks. + +## Events + +The DWN module does not explicitly define any events. However, standard Cosmos SDK events may be emitted during state transitions. + +## Client + +The DWN module provides the following gRPC query endpoints: + +1. `Params`: Queries all parameters of the module. +2. `Schema`: Queries the DID document schema. +3. `Allocate`: Initializes a Target DWN available for claims. +4. `Sync`: Queries the DID document by its ID and returns required information. + +## Params + +The module parameters include: + +- `ipfs_active` (bool): Indicates if IPFS integration is active. +- `local_registration_enabled` (bool): Indicates if local registration is enabled. +- `schema` (Schema): Defines the structure for various data types in the dwn. + +## Future Improvements + +Potential future improvements could include: + +1. Enhanced IPFS integration features. +2. Additional authentication mechanisms beyond WebAuthn. +3. Improved DID document management and querying capabilities. + +## Tests + +Acceptance tests should cover: + +1. Parameter updates +2. DWN state management +3. Schema queries +4. DWN allocation process +5. DID document syncing + +## Appendix + +| Concept | Description | +| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Decentralized Web Node (DWN) | A decentralized, distributed, and secure network of nodes that store and share data. It is a decentralized alternative to traditional web hosting services. | +| Decentralized Identifier (DID) | A unique identifier that is created, owned, and controlled by the user. It is used to establish a secure and verifiable digital identity. | +| HTMX (Hypertext Markup Language eXtensions) | A set of extensions to HTML that allow for the creation of interactive web pages. It is used to enhance the user experience and provide additional functionality to web applications. | +| IPFS (InterPlanetary File System) | A decentralized, peer-to-peer network for storing and sharing data. It is a distributed file system that allows for the creation and sharing of content across a network of nodes. | +| WebAuthn (Web Authentication) | A set of APIs that allow websites to request user authentication using biometric or non-biometric factors. | +| WebAssembly (Web Assembly) | A binary instruction format for a stack-based virtual machine. | +| Verifiable Credential (VC) | A digital statement that can be cryptographically verified. | diff --git a/docs/adrs/adr-3.md b/docs/adrs/adr-3.md new file mode 100644 index 000000000..079760c07 --- /dev/null +++ b/docs/adrs/adr-3.md @@ -0,0 +1,91 @@ +# `x/svc` + +The svc module is responsible for managing the registration and authorization of services within the Sonr ecosystem. It provides a secure and verifiable mechanism for registering and authorizing services using Decentralized Identifiers (DIDs). + +## Concepts + +- **Service**: A decentralized svc on the Sonr Blockchain with properties such as ID, authority, origin, name, description, category, tags, and expiry height. +- **Profile**: Represents a DID alias with properties like ID, subject, origin, and controller. +- **Metadata**: Contains information about a svc, including name, description, category, icon, and tags. + +### Dependencies + +- [x/did](https://github.com/onsonr/sonr/tree/master/x/did) +- [x/group](https://github.com/onsonr/sonr/tree/master/x/group) +- [x/nft](https://github.com/onsonr/sonr/tree/master/x/nft) + +## State + +The module uses the following state structures: + +### Metadata + +Stores information about services: + +- Primary key: `id` (auto-increment) +- Unique index: `origin` +- Fields: id, origin, name, description, category, icon (URI), tags + +### Profile + +Stores DID alias information: + +- Primary key: `id` +- Unique index: `subject,origin` +- Fields: id, subject, origin, controller + +## Messages + +### MsgUpdateParams + +Updates the module parameters. Can only be executed by the governance account. + +### MsgRegisterService + +Registers a new svc on the blockchain. Requires a valid TXT record in DNS for the origin. + +## Params + +The module has the following parameters: + +- `categories`: List of allowed svc categories +- `types`: List of allowed svc types + +## Query + +The module provides the following query: + +### Params + +Retrieves all parameters of the module. + +## Client + +### gRPC + +The module provides a gRPC Query svc with the following RPC: + +- `Params`: Get all parameters of the module + +### CLI + +(TODO: Add CLI commands for interacting with the module) + +## Events + +(TODO: List and describe event tags used by the module) + +## Future Improvements + +- Implement svc discovery mechanisms +- Add support for svc reputation and rating systems +- Enhance svc metadata with more detailed information +- Implement svc update and deactivation functionality + +## Tests + +(TODO: Add acceptance tests for the module) + +## Appendix + +This module is part of the Sonr blockchain project and interacts with other modules such as DID and NFT modules to provide a comprehensive decentralized svc ecosystem. diff --git a/docs/adrs/adr-4.md b/docs/adrs/adr-4.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/reference/guides/cosmos-orm.md b/docs/reference/guides/cosmos-orm.md new file mode 100644 index 000000000..65627bf76 --- /dev/null +++ b/docs/reference/guides/cosmos-orm.md @@ -0,0 +1,329 @@ +# ORM + +The Cosmos SDK ORM is a state management library that provides a rich, but opinionated set of tools for managing a +module's state. It provides support for: + +- type safe management of state +- multipart keys +- secondary indexes +- unique indexes +- easy prefix and range queries +- automatic genesis import/export +- automatic query services for clients, including support for light client proofs (still in development) +- indexing state data in external databases (still in development) + +## Design and Philosophy + +The ORM's data model is inspired by the relational data model found in SQL databases. The core abstraction is a table +with a primary key and optional secondary indexes. + +Because the Cosmos SDK uses protobuf as its encoding layer, ORM tables are defined directly in .proto files using +protobuf options. Each table is defined by a single protobuf `message` type and a schema of multiple tables is +represented by a single .proto file. + +Table structure is specified in the same file where messages are defined in order to make it easy to focus on better +design of the state layer. Because blockchain state layout is part of the public API for clients (TODO: link to docs on +light client proofs), it is important to think about the state layout as being part of the public API of a module. +Changing the state layout actually breaks clients, so it is ideal to think through it carefully up front and to aim for +a design that will eliminate or minimize breaking changes down the road. Also, good design of state enables building +more performant and sophisticated applications. Providing users with a set of tools inspired by relational databases +which have a long history of database design best practices and allowing schema to be specified declaratively in a +single place are design choices the ORM makes to enable better design and more durable APIs. + +Also, by only supporting the table abstraction as opposed to key-value pair maps, it is easy to add to new +columns/fields to any data structure without causing a breaking change and the data structures can easily be indexed in +any off-the-shelf SQL database for more sophisticated queries. + +The encoding of fields in keys is designed to support ordered iteration for all protobuf primitive field types +except for `bytes` as well as the well-known types `google.protobuf.Timestamp` and `google.protobuf.Duration`. Encodings +are optimized for storage space when it makes sense (see the documentation in `cosmos/orm/v1/orm.proto` for more details) +and table rows do not use extra storage space to store key fields in the value. + +We recommend that users of the ORM attempt to follow database design best practices such as +[normalization](https://en.wikipedia.org/wiki/Database_normalization) (at least 1NF). +For instance, defining `repeated` fields in a table is considered an anti-pattern because breaks first normal form (1NF). +Although we support `repeated` fields in tables, they cannot be used as key fields for this reason. This may seem +restrictive but years of best practice (and also experience in the SDK) have shown that following this pattern +leads to easier to maintain schemas. + +To illustrate the motivation for these principles with an example from the SDK, historically balances were stored +as a mapping from account -> map of denom to amount. This did not scale well because an account with 100 token balances +needed to be encoded/decoded every time a single coin balance changed. Now balances are stored as account,denom -> amount +as in the example above. With the ORM's data model, if we wanted to add a new field to `Balance` such as +`unlocked_balance` (if vesting accounts were redesigned in this way), it would be easy to add it to this table without +requiring a data migration. Because of the ORM's optimizations, the account and denom are only stored in the key part +of storage and not in the value leading to both a flexible data model and efficient usage of storage. + +## Defining Tables + +To define a table: + +1. create a .proto file to describe the module's state (naming it `state.proto` is recommended for consistency), + and import "cosmos/orm/v1/orm.proto", ex: + +```protobuf +syntax = "proto3"; +package bank_example; + +import "cosmos/orm/v1/orm.proto"; +``` + +2. define a `message` for the table, ex: + +```protobuf +message Balance { + bytes account = 1; + string denom = 2; + uint64 balance = 3; +} +``` + +3. add the `cosmos.orm.v1.table` option to the table and give the table an `id` unique within this .proto file: + +```protobuf +message Balance { + option (cosmos.orm.v1.table) = { + id: 1 + }; + + bytes account = 1; + string denom = 2; + uint64 balance = 3; +} +``` + +4. define the primary key field or fields, as a comma-separated list of the fields from the message which should make + up the primary key: + +```protobuf +message Balance { + option (cosmos.orm.v1.table) = { + id: 1 + primary_key: { fields: "account,denom" } + }; + + bytes account = 1; + string denom = 2; + uint64 balance = 3; +} +``` + +5. add any desired secondary indexes by specifying an `id` unique within the table and a comma-separate list of the + index fields: + +```protobuf +message Balance { + option (cosmos.orm.v1.table) = { + id: 1; + primary_key: { fields: "account,denom" } + index: { id: 1 fields: "denom" } // this allows querying for the accounts which own a denom + }; + + bytes account = 1; + string denom = 2; + uint64 amount = 3; +} +``` + +### Auto-incrementing Primary Keys + +A common pattern in SDK modules and in database design is to define tables with a single integer `id` field with an +automatically generated primary key. In the ORM we can do this by setting the `auto_increment` option to `true` on the +primary key, ex: + +```protobuf +message Account { + option (cosmos.orm.v1.table) = { + id: 2; + primary_key: { fields: "id", auto_increment: true } + }; + + uint64 id = 1; + bytes address = 2; +} +``` + +### Unique Indexes + +A unique index can be added by setting the `unique` option to `true` on an index, ex: + +```protobuf +message Account { + option (cosmos.orm.v1.table) = { + id: 2; + primary_key: { fields: "id", auto_increment: true } + index: {id: 1, fields: "address", unique: true} + }; + + uint64 id = 1; + bytes address = 2; +} +``` + +### Singletons + +The ORM also supports a special type of table with only one row called a `singleton`. This can be used for storing +module parameters. Singletons only need to define a unique `id` and that cannot conflict with the id of other +tables or singletons in the same .proto file. Ex: + +```protobuf +message Params { + option (cosmos.orm.v1.singleton) = { + id: 3; + }; + + google.protobuf.Duration voting_period = 1; + uint64 min_threshold = 2; +} +``` + +## Running Codegen + +NOTE: the ORM will only work with protobuf code that implements the [google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf) +API. That means it will not work with code generated using gogo-proto. + +To install the ORM's code generator, run: + +```shell +go install cosmossdk.io/orm/cmd/protoc-gen-go-cosmos-orm@latest +``` + +The recommended way to run the code generator is to use [buf build](https://docs.buf.build/build/usage). +This is an example `buf.gen.yaml` that runs `protoc-gen-go`, `protoc-gen-go-grpc` and `protoc-gen-go-cosmos-orm` +using buf managed mode: + +```yaml +version: v1 +managed: + enabled: true + go_package_prefix: + default: foo.bar/api # the go package prefix of your package + override: + buf.build/cosmos/cosmos-sdk: cosmossdk.io/api # required to import the Cosmos SDK api module +plugins: + - name: go + out: . + opt: paths=source_relative + - name: go-grpc + out: . + opt: paths=source_relative + - name: go-cosmos-orm + out: . + opt: paths=source_relative +``` + +## Using the ORM in a module + +### Initialization + +To use the ORM in a module, first create a `ModuleSchemaDescriptor`. This tells the ORM which .proto files have defined +an ORM schema and assigns them all a unique non-zero id. Ex: + +```go +var MyModuleSchema = &ormv1alpha1.ModuleSchemaDescriptor{ + SchemaFile: []*ormv1alpha1.ModuleSchemaDescriptor_FileEntry{ + { + Id: 1, + ProtoFileName: mymodule.File_my_module_state_proto.Path(), + }, + }, +} +``` + +In the ORM generated code for a file named `state.proto`, there should be an interface `StateStore` that got generated +with a constructor `NewStateStore` that takes a parameter of type `ormdb.ModuleDB`. Add a reference to `StateStore` +to your module's keeper struct. Ex: + +```go +type Keeper struct { + db StateStore +} +``` + +Then instantiate the `StateStore` instance via an `ormdb.ModuleDB` that is instantiated from the `SchemaDescriptor` +above and one or more store services from `cosmossdk.io/core/store`. Ex: + +```go +func NewKeeper(storeService store.KVStoreService) (*Keeper, error) { + modDb, err := ormdb.NewModuleDB(MyModuleSchema, ormdb.ModuleDBOptions{KVStoreService: storeService}) + if err != nil { + return nil, err + } + db, err := NewStateStore(modDb) + if err != nil { + return nil, err + } + return Keeper{db: db}, nil +} +``` + +### Using the generated code + +The generated code for the ORM contains methods for inserting, updating, deleting and querying table entries. +For each table in a .proto file, there is a type-safe table interface implemented in generated code. For instance, +for a table named `Balance` there should be a `BalanceTable` interface that looks like this: + +```go +type BalanceTable interface { + Insert(ctx context.Context, balance *Balance) error + Update(ctx context.Context, balance *Balance) error + Save(ctx context.Context, balance *Balance) error + Delete(ctx context.Context, balance *Balance) error + Has(ctx context.Context, account []byte, denom string) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, account []byte, denom string) (*Balance, error) + List(ctx context.Context, prefixKey BalanceIndexKey, opts ...ormlist.Option) (BalanceIterator, error) + ListRange(ctx context.Context, from, to BalanceIndexKey, opts ...ormlist.Option) (BalanceIterator, error) + DeleteBy(ctx context.Context, prefixKey BalanceIndexKey) error + DeleteRange(ctx context.Context, from, to BalanceIndexKey) error + + doNotImplement() +} +``` + +This `BalanceTable` should be accessible from the `StateStore` interface (assuming our file is named `state.proto`) +via a `BalanceTable()` accessor method. If all the above example tables/singletons were in the same `state.proto`, +then `StateStore` would get generated like this: + +```go +type BankStore interface { + BalanceTable() BalanceTable + AccountTable() AccountTable + ParamsTable() ParamsTable + + doNotImplement() +} +``` + +So to work with the `BalanceTable` in a keeper method we could use code like this: + +```go +func (k keeper) AddBalance(ctx context.Context, acct []byte, denom string, amount uint64) error { + balance, err := k.db.BalanceTable().Get(ctx, acct, denom) + if err != nil && !ormerrors.IsNotFound(err) { + return err + } + + if balance == nil { + balance = &Balance{ + Account: acct, + Denom: denom, + Amount: amount, + } + } else { + balance.Amount = balance.Amount + amount + } + + return k.db.BalanceTable().Save(ctx, balance) +} +``` + +`List` methods take `IndexKey` parameters. For instance, `BalanceTable.List` takes `BalanceIndexKey`. `BalanceIndexKey` +let's represent index keys for the different indexes (primary and secondary) on the `Balance` table. The primary key +in the `Balance` table gets a struct `BalanceAccountDenomIndexKey` and the first index gets an index key `BalanceDenomIndexKey`. +If we wanted to list all the denoms and amounts that an account holds, we would use `BalanceAccountDenomIndexKey` +with a `List` query just on the account prefix. Ex: + +```go +it, err := keeper.db.BalanceTable().List(ctx, BalanceAccountDenomIndexKey{}.WithAccount(acct)) +``` diff --git a/docs/reference/guides/cosmos-sdk.md b/docs/reference/guides/cosmos-sdk.md new file mode 100644 index 000000000..dea85ad75 --- /dev/null +++ b/docs/reference/guides/cosmos-sdk.md @@ -0,0 +1,3 @@ +# Cosmos SDK + +The Cosmos SDK is a modular framework for building blockchain applications. Sonr is built on top of the Cosmos SDK, which provides a robust and secure foundation for building decentralized applications. diff --git a/docs/reference/guides/echo-framework.md b/docs/reference/guides/echo-framework.md new file mode 100644 index 000000000..232447377 --- /dev/null +++ b/docs/reference/guides/echo-framework.md @@ -0,0 +1,3 @@ +# Echo Framework + +The Echo Framework is a web framework for building RESTful APIs in Go. It provides a simple and intuitive way to define routes, handle requests, and return responses. It uses `net/http` underneath to provide minimal external dependencies. diff --git a/docs/reference/guides/templ-syntax.md b/docs/reference/guides/templ-syntax.md new file mode 100644 index 000000000..b9a22c881 --- /dev/null +++ b/docs/reference/guides/templ-syntax.md @@ -0,0 +1,3 @@ +# Templ Syntax + +Templ is a template engine for Go that provides a simple and intuitive way to generate dynamic content. diff --git a/docs/reference/guides/wa-components.md b/docs/reference/guides/wa-components.md new file mode 100644 index 000000000..3753d379e --- /dev/null +++ b/docs/reference/guides/wa-components.md @@ -0,0 +1,3 @@ +# WebAwesome Components + +WebAwesome Components is a collection of reusable web components for building web applications. It provides a set of pre-built components that can be easily integrated into your web application. diff --git a/x/dwn/types/genesis.pb.go b/x/dwn/types/genesis.pb.go index 430981ca0..969bc9fc8 100644 --- a/x/dwn/types/genesis.pb.go +++ b/x/dwn/types/genesis.pb.go @@ -130,6 +130,113 @@ func (m *Params) GetSchema() *Schema { return nil } +// Capability reprensents the available capabilities of a decentralized web node +type Capability struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *Capability) Reset() { *m = Capability{} } +func (m *Capability) String() string { return proto.CompactTextString(m) } +func (*Capability) ProtoMessage() {} +func (*Capability) Descriptor() ([]byte, []int) { + return fileDescriptor_8e7492a25d5871dc, []int{2} +} +func (m *Capability) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Capability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Capability.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 *Capability) XXX_Merge(src proto.Message) { + xxx_messageInfo_Capability.Merge(m, src) +} +func (m *Capability) XXX_Size() int { + return m.Size() +} +func (m *Capability) XXX_DiscardUnknown() { + xxx_messageInfo_Capability.DiscardUnknown(m) +} + +var xxx_messageInfo_Capability proto.InternalMessageInfo + +func (m *Capability) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Capability) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +// Resource reprensents the available resources of a decentralized web node +type Resource struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *Resource) Reset() { *m = Resource{} } +func (m *Resource) String() string { return proto.CompactTextString(m) } +func (*Resource) ProtoMessage() {} +func (*Resource) Descriptor() ([]byte, []int) { + return fileDescriptor_8e7492a25d5871dc, []int{3} +} +func (m *Resource) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Resource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Resource.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 *Resource) XXX_Merge(src proto.Message) { + xxx_messageInfo_Resource.Merge(m, src) +} +func (m *Resource) XXX_Size() int { + return m.Size() +} +func (m *Resource) XXX_DiscardUnknown() { + xxx_messageInfo_Resource.DiscardUnknown(m) +} + +var xxx_messageInfo_Resource proto.InternalMessageInfo + +func (m *Resource) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Resource) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +// Schema is the Database Model for Decentralized Web Nodes type Schema struct { Version int32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` @@ -147,7 +254,7 @@ func (m *Schema) Reset() { *m = Schema{} } func (m *Schema) String() string { return proto.CompactTextString(m) } func (*Schema) ProtoMessage() {} func (*Schema) Descriptor() ([]byte, []int) { - return fileDescriptor_8e7492a25d5871dc, []int{2} + return fileDescriptor_8e7492a25d5871dc, []int{4} } func (m *Schema) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -249,40 +356,45 @@ func (m *Schema) GetProfile() string { func init() { proto.RegisterType((*GenesisState)(nil), "dwn.v1.GenesisState") proto.RegisterType((*Params)(nil), "dwn.v1.Params") + proto.RegisterType((*Capability)(nil), "dwn.v1.Capability") + proto.RegisterType((*Resource)(nil), "dwn.v1.Resource") proto.RegisterType((*Schema)(nil), "dwn.v1.Schema") } func init() { proto.RegisterFile("dwn/v1/genesis.proto", fileDescriptor_8e7492a25d5871dc) } var fileDescriptor_8e7492a25d5871dc = []byte{ - // 431 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x92, 0x31, 0x6f, 0x13, 0x31, - 0x1c, 0xc5, 0xef, 0x68, 0x73, 0x4d, 0xdc, 0x0a, 0x81, 0x95, 0xc1, 0x64, 0xb8, 0xa0, 0x0c, 0x08, - 0x21, 0x74, 0xa7, 0xc2, 0x86, 0xb2, 0x50, 0x09, 0xb1, 0xa2, 0xeb, 0xc6, 0x12, 0x39, 0xbe, 0x7f, - 0x2f, 0x6e, 0x2e, 0xf6, 0xc9, 0x76, 0x2e, 0xf4, 0x2b, 0x30, 0x31, 0x32, 0x76, 0x66, 0xe2, 0x63, - 0x74, 0xec, 0xc8, 0x84, 0x50, 0x32, 0xc0, 0x47, 0x60, 0x44, 0xfe, 0xfb, 0x8a, 0xd2, 0xc5, 0xf2, - 0xfb, 0xbd, 0xe7, 0xa7, 0x37, 0x98, 0x0c, 0xcb, 0x8d, 0xca, 0xdb, 0xd3, 0xbc, 0x02, 0x05, 0x56, - 0xda, 0xac, 0x31, 0xda, 0x69, 0x9a, 0x94, 0x1b, 0x95, 0xb5, 0xa7, 0xa3, 0x61, 0xa5, 0x2b, 0x8d, - 0x28, 0xf7, 0xb7, 0xe0, 0x8e, 0x1e, 0xf3, 0x95, 0x54, 0x3a, 0xc7, 0x33, 0xa0, 0xc9, 0x94, 0x9c, - 0xbc, 0x0f, 0x0d, 0xe7, 0x8e, 0x3b, 0xa0, 0x2f, 0x49, 0xd2, 0x70, 0xc3, 0x57, 0x96, 0xc5, 0x4f, - 0xe3, 0xe7, 0xc7, 0xaf, 0x1e, 0x66, 0xa1, 0x31, 0xfb, 0x80, 0xf4, 0xec, 0xf0, 0xe6, 0xe7, 0x38, - 0x2a, 0xba, 0xcc, 0xe4, 0x5b, 0x4c, 0x92, 0x60, 0xd0, 0x31, 0x39, 0x96, 0xcd, 0x85, 0x9d, 0x71, - 0xe1, 0x64, 0x0b, 0xf8, 0xba, 0x5f, 0x10, 0x8f, 0xde, 0x22, 0xa1, 0x53, 0x32, 0xaa, 0xb5, 0xe0, - 0xf5, 0xcc, 0x40, 0x25, 0xad, 0x33, 0xdc, 0x49, 0xad, 0x66, 0xa0, 0xf8, 0xbc, 0x86, 0x92, 0x3d, - 0xc0, 0x3c, 0xc3, 0x44, 0xb1, 0x17, 0x78, 0x17, 0x7c, 0xfa, 0x8c, 0x24, 0x56, 0x2c, 0x60, 0xc5, - 0xd9, 0xe1, 0xfd, 0x5d, 0xe7, 0x48, 0x8b, 0xce, 0x7d, 0xf3, 0xe4, 0xeb, 0xf5, 0x38, 0xfa, 0x73, - 0x3d, 0x8e, 0x3f, 0xff, 0xfe, 0xfe, 0xe2, 0xa4, 0xe5, 0xeb, 0xda, 0xe5, 0xdd, 0xd8, 0xbf, 0x31, - 0x49, 0x42, 0x9a, 0x32, 0x72, 0xd4, 0x82, 0xb1, 0x52, 0x2b, 0x1c, 0xda, 0x2b, 0xee, 0xa4, 0x77, - 0xb8, 0x10, 0x7a, 0xad, 0x1c, 0x4e, 0x1a, 0x14, 0x77, 0x92, 0x0e, 0x49, 0x8f, 0x5b, 0x0b, 0x8e, - 0x1d, 0x20, 0x0f, 0xc2, 0x53, 0xb1, 0xe0, 0x52, 0xe1, 0xac, 0x41, 0x11, 0x04, 0x4d, 0x09, 0x11, - 0x06, 0x4a, 0x50, 0x4e, 0xf2, 0x9a, 0xf5, 0xd0, 0xda, 0x23, 0xf4, 0x11, 0x39, 0x28, 0x65, 0xc9, - 0x12, 0x34, 0xfc, 0xd5, 0x93, 0xcb, 0xcd, 0x92, 0x1d, 0x05, 0x72, 0xb9, 0x59, 0xfa, 0xe6, 0xca, - 0x70, 0xe5, 0x58, 0x3f, 0x34, 0xa3, 0xa0, 0x23, 0xd2, 0x5f, 0xc2, 0x95, 0x5d, 0x70, 0x03, 0x6c, - 0x80, 0xc6, 0x7f, 0xed, 0xb7, 0x37, 0x46, 0x5f, 0xc8, 0x1a, 0x18, 0x09, 0xdb, 0x3b, 0x79, 0x36, - 0xbd, 0xd9, 0xa6, 0xf1, 0xed, 0x36, 0x8d, 0x7f, 0x6d, 0xd3, 0xf8, 0xcb, 0x2e, 0x8d, 0x6e, 0x77, - 0x69, 0xf4, 0x63, 0x97, 0x46, 0x1f, 0x27, 0x95, 0x74, 0x8b, 0xf5, 0x3c, 0x13, 0x7a, 0x95, 0x6b, - 0x65, 0xb5, 0x32, 0x39, 0x1e, 0x9f, 0x72, 0xff, 0xbf, 0xdc, 0x55, 0x03, 0x76, 0x9e, 0xe0, 0x57, - 0x79, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xdd, 0xa9, 0xd7, 0xe1, 0x73, 0x02, 0x00, 0x00, + // 478 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x31, 0x8f, 0xd3, 0x30, + 0x1c, 0xc5, 0x13, 0xae, 0xcd, 0xb5, 0xff, 0x9e, 0x10, 0x58, 0x1d, 0x4c, 0x87, 0xf4, 0xd4, 0x01, + 0x21, 0x84, 0x12, 0x1d, 0x6c, 0xa8, 0x03, 0x14, 0x21, 0x56, 0x94, 0xdb, 0x58, 0x2a, 0xd7, 0xf1, + 0xa5, 0xbe, 0x26, 0x76, 0x64, 0xbb, 0x29, 0xfd, 0x0a, 0x4c, 0x8c, 0x8c, 0x37, 0x33, 0xf1, 0x31, + 0x6e, 0xbc, 0x91, 0x09, 0xa1, 0x76, 0x80, 0x8f, 0xc0, 0x88, 0x6c, 0xe7, 0x50, 0x59, 0x6f, 0xb1, + 0xfe, 0xef, 0xf7, 0xfe, 0x79, 0x79, 0xb2, 0x0c, 0xc3, 0x7c, 0x23, 0xd2, 0xe6, 0x2c, 0x2d, 0x98, + 0x60, 0x9a, 0xeb, 0xa4, 0x56, 0xd2, 0x48, 0x14, 0xe5, 0x1b, 0x91, 0x34, 0x67, 0xa3, 0x61, 0x21, + 0x0b, 0xe9, 0x50, 0x6a, 0x27, 0xef, 0x8e, 0x1e, 0x92, 0x8a, 0x0b, 0x99, 0xba, 0xd3, 0xa3, 0xc9, + 0x14, 0x4e, 0xde, 0xf9, 0x84, 0x73, 0x43, 0x0c, 0x43, 0xcf, 0x20, 0xaa, 0x89, 0x22, 0x95, 0xc6, + 0xe1, 0x69, 0xf8, 0x64, 0xf0, 0xfc, 0x7e, 0xe2, 0x13, 0x93, 0xf7, 0x8e, 0xce, 0x3a, 0xd7, 0x3f, + 0xc6, 0x41, 0xd6, 0xee, 0x4c, 0xbe, 0x86, 0x10, 0x79, 0x03, 0x8d, 0x61, 0xc0, 0xeb, 0x0b, 0x3d, + 0x27, 0xd4, 0xf0, 0x86, 0xb9, 0xaf, 0x7b, 0x19, 0x58, 0xf4, 0xda, 0x11, 0x34, 0x85, 0x51, 0x29, + 0x29, 0x29, 0xe7, 0x8a, 0x15, 0x5c, 0x1b, 0x45, 0x0c, 0x97, 0x62, 0xce, 0x04, 0x59, 0x94, 0x2c, + 0xc7, 0xf7, 0xdc, 0x3e, 0x76, 0x1b, 0xd9, 0xc1, 0xc2, 0x5b, 0xef, 0xa3, 0xc7, 0x10, 0x69, 0xba, + 0x64, 0x15, 0xc1, 0x9d, 0xff, 0x7b, 0x9d, 0x3b, 0x9a, 0xb5, 0xee, 0xcb, 0x47, 0x5f, 0xae, 0xc6, + 0xc1, 0xef, 0xab, 0x71, 0xf8, 0xe9, 0xd7, 0xb7, 0xa7, 0x27, 0x0d, 0x59, 0x97, 0x26, 0x6d, 0xcb, + 0xce, 0x00, 0xde, 0x90, 0x9a, 0x2c, 0x78, 0xc9, 0xcd, 0x16, 0x21, 0xe8, 0x08, 0x52, 0xf9, 0xa2, + 0xfd, 0xcc, 0xcd, 0xe8, 0x14, 0x06, 0x39, 0xd3, 0x54, 0xf1, 0xda, 0xfe, 0xda, 0x75, 0xea, 0x67, + 0x87, 0x68, 0xf2, 0x0a, 0x7a, 0x19, 0xd3, 0x72, 0xad, 0x28, 0xbb, 0x63, 0xc2, 0x9f, 0x10, 0x22, + 0xdf, 0x19, 0x61, 0x38, 0x6e, 0x98, 0xd2, 0x76, 0xd1, 0x66, 0x74, 0xb3, 0x5b, 0x69, 0x1d, 0x42, + 0xa9, 0x5c, 0x0b, 0xd3, 0x46, 0xdc, 0x4a, 0x34, 0x84, 0x2e, 0xd1, 0x9a, 0x19, 0x7c, 0xe4, 0xb8, + 0x17, 0x96, 0xd2, 0x25, 0xe1, 0xc2, 0x5d, 0x4e, 0x3f, 0xf3, 0x02, 0xc5, 0x00, 0x54, 0xb1, 0x9c, + 0x09, 0xc3, 0x49, 0x89, 0xbb, 0xce, 0x3a, 0x20, 0xe8, 0x01, 0x1c, 0xe5, 0x3c, 0xc7, 0x91, 0x33, + 0xec, 0x68, 0xc9, 0xe5, 0x66, 0x85, 0x8f, 0x3d, 0xb9, 0xdc, 0xac, 0x6c, 0x72, 0xa1, 0x88, 0x30, + 0xb8, 0xe7, 0x93, 0x9d, 0x40, 0x23, 0xe8, 0xad, 0xd8, 0x56, 0x2f, 0x89, 0x62, 0xb8, 0xef, 0x8c, + 0x7f, 0xda, 0x76, 0xaf, 0x95, 0xbc, 0xe0, 0x25, 0xc3, 0xe0, 0xbb, 0xb7, 0x72, 0x36, 0xbd, 0xde, + 0xc5, 0xe1, 0xcd, 0x2e, 0x0e, 0x7f, 0xee, 0xe2, 0xf0, 0xf3, 0x3e, 0x0e, 0x6e, 0xf6, 0x71, 0xf0, + 0x7d, 0x1f, 0x07, 0x1f, 0x26, 0x05, 0x37, 0xcb, 0xf5, 0x22, 0xa1, 0xb2, 0x4a, 0xa5, 0xd0, 0x52, + 0xa8, 0xd4, 0x1d, 0x1f, 0x53, 0xfb, 0xca, 0xcd, 0xb6, 0x66, 0x7a, 0x11, 0xb9, 0x07, 0xfb, 0xe2, + 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfa, 0x30, 0xe3, 0x96, 0xf9, 0x02, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -403,6 +515,80 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Capability) 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 *Capability) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Capability) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Resource) 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 *Resource) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Resource) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Schema) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -535,6 +721,40 @@ func (m *Params) Size() (n int) { return n } +func (m *Capability) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func (m *Resource) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + func (m *Schema) Size() (n int) { if m == nil { return 0 @@ -798,6 +1018,234 @@ func (m *Params) Unmarshal(dAtA []byte) error { } return nil } +func (m *Capability) 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 ErrIntOverflowGenesis + } + 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: Capability: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Capability: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Resource) 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 ErrIntOverflowGenesis + } + 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: Resource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Resource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Schema) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/dwn/types/state.pb.go b/x/dwn/types/state.pb.go index 50a481acf..d84aba9ef 100644 --- a/x/dwn/types/state.pb.go +++ b/x/dwn/types/state.pb.go @@ -24,8 +24,12 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Credential struct { - Account []byte `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` - Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Transports []string `protobuf:"bytes,3,rep,name=transports,proto3" json:"transports,omitempty"` + PublicKey []byte `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + AttestationType string `protobuf:"bytes,5,opt,name=attestation_type,json=attestationType,proto3" json:"attestation_type,omitempty"` + CreatedAt uint64 `protobuf:"varint,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` } func (m *Credential) Reset() { *m = Credential{} } @@ -61,16 +65,44 @@ func (m *Credential) XXX_DiscardUnknown() { var xxx_messageInfo_Credential proto.InternalMessageInfo -func (m *Credential) GetAccount() []byte { +func (m *Credential) GetId() []byte { if m != nil { - return m.Account + return m.Id } return nil } -func (m *Credential) GetAmount() uint64 { +func (m *Credential) GetType() string { if m != nil { - return m.Amount + return m.Type + } + return "" +} + +func (m *Credential) GetTransports() []string { + if m != nil { + return m.Transports + } + return nil +} + +func (m *Credential) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *Credential) GetAttestationType() string { + if m != nil { + return m.AttestationType + } + return "" +} + +func (m *Credential) GetCreatedAt() uint64 { + if m != nil { + return m.CreatedAt } return 0 } @@ -135,21 +167,29 @@ func init() { func init() { proto.RegisterFile("dwn/v1/state.proto", fileDescriptor_040a9b061177db90) } var fileDescriptor_040a9b061177db90 = []byte{ - // 219 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4a, 0x29, 0xcf, 0xd3, - 0x2f, 0x33, 0xd4, 0x2f, 0x2e, 0x49, 0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, - 0x4b, 0x29, 0xcf, 0xd3, 0x2b, 0x33, 0x94, 0x12, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0xcf, - 0x2f, 0xca, 0x05, 0x29, 0xc9, 0x2f, 0xca, 0x85, 0x28, 0x50, 0x8a, 0xe7, 0xe2, 0x72, 0x2e, 0x4a, - 0x4d, 0x49, 0xcd, 0x2b, 0xc9, 0x4c, 0xcc, 0x11, 0x92, 0xe0, 0x62, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, - 0xcd, 0x2b, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x09, 0x82, 0x71, 0x85, 0xc4, 0xb8, 0xd8, 0x12, - 0x73, 0xc1, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x2c, 0x41, 0x50, 0x9e, 0x95, 0xfc, 0xa7, 0x79, 0x97, - 0xfb, 0x98, 0x25, 0xb9, 0x38, 0xe1, 0x3a, 0x85, 0xb8, 0x60, 0x4a, 0x05, 0x18, 0x25, 0x18, 0x95, - 0x62, 0xb8, 0xd8, 0x03, 0x8a, 0xf2, 0xd3, 0x32, 0x73, 0x52, 0xa9, 0x6f, 0x3a, 0x93, 0x93, 0xcd, - 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, - 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x29, 0xa5, 0x67, 0x96, 0x64, 0x94, - 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xe7, 0xe7, 0x15, 0xe7, 0xe7, 0x15, 0xe9, 0x83, 0x89, 0x0a, - 0x7d, 0x50, 0x30, 0x95, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0xc3, 0xc0, 0x18, 0x10, 0x00, - 0x00, 0xff, 0xff, 0x14, 0x0b, 0x56, 0x1c, 0x3a, 0x01, 0x00, 0x00, + // 342 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x91, 0xb1, 0x4e, 0xeb, 0x30, + 0x18, 0x85, 0xeb, 0x34, 0x37, 0xbd, 0xf9, 0x75, 0x75, 0x6f, 0xe5, 0xe1, 0x62, 0x90, 0x1a, 0xa2, + 0x4e, 0x61, 0x69, 0x54, 0xb1, 0x55, 0x2c, 0xc0, 0xc8, 0x82, 0x22, 0x26, 0x84, 0x54, 0xb9, 0x89, + 0x01, 0x8b, 0xc6, 0x8e, 0xec, 0xbf, 0x2d, 0x7d, 0x09, 0xc4, 0x13, 0xf0, 0x3c, 0x8c, 0x95, 0xba, + 0x30, 0xa2, 0xf6, 0x0d, 0x78, 0x02, 0x14, 0xb7, 0x45, 0x5d, 0x2c, 0x9f, 0xe3, 0xe3, 0xcf, 0xc7, + 0x36, 0xd0, 0x62, 0xa6, 0xd2, 0x69, 0x3f, 0xb5, 0xc8, 0x51, 0xf4, 0x2a, 0xa3, 0x51, 0xd3, 0xa0, + 0x98, 0xa9, 0xde, 0xb4, 0x7f, 0x74, 0x90, 0x6b, 0x5b, 0x6a, 0x9b, 0x6a, 0x53, 0xd6, 0x11, 0x6d, + 0xca, 0x4d, 0xa0, 0xbb, 0x24, 0x00, 0x97, 0x46, 0x14, 0x42, 0xa1, 0xe4, 0x63, 0xfa, 0x17, 0x3c, + 0x59, 0x30, 0x12, 0x93, 0xe4, 0x4f, 0xe6, 0xc9, 0x82, 0x52, 0xf0, 0x71, 0x5e, 0x09, 0xe6, 0xc5, + 0x24, 0x09, 0x33, 0x37, 0xa7, 0x11, 0x00, 0x1a, 0xae, 0x6c, 0xa5, 0x0d, 0x5a, 0xd6, 0x8c, 0x9b, + 0x49, 0x98, 0xed, 0x39, 0xb4, 0x03, 0x50, 0x4d, 0x46, 0x63, 0x99, 0x0f, 0x9f, 0xc4, 0x9c, 0xf9, + 0x8e, 0x15, 0x6e, 0x9c, 0x2b, 0x31, 0xa7, 0x27, 0xd0, 0xe6, 0x88, 0xa2, 0x6e, 0x29, 0xb5, 0x1a, + 0x3a, 0xfc, 0x2f, 0x87, 0xff, 0xb7, 0xe7, 0xdf, 0xd4, 0x27, 0x75, 0x00, 0x72, 0x23, 0x38, 0x8a, + 0x62, 0xc8, 0x91, 0x05, 0x31, 0x49, 0xfc, 0x2c, 0xdc, 0x3a, 0xe7, 0x38, 0x60, 0x5f, 0x6f, 0xcb, + 0x97, 0x26, 0x05, 0xbf, 0x2e, 0x4d, 0x7f, 0x6f, 0xaa, 0xb6, 0x09, 0x23, 0xdd, 0x3b, 0x68, 0x5d, + 0x1b, 0x7d, 0x2f, 0xc7, 0x82, 0x32, 0x68, 0xf1, 0x3c, 0xd7, 0x13, 0x85, 0xdb, 0x6b, 0xed, 0x24, + 0xfd, 0x0f, 0x01, 0x2f, 0xdd, 0x82, 0xe7, 0xc8, 0x5b, 0x35, 0x38, 0x76, 0xd8, 0x43, 0x08, 0x7f, + 0x76, 0x52, 0xd8, 0x45, 0xdb, 0x84, 0x79, 0x17, 0x67, 0xef, 0xab, 0x88, 0x2c, 0x56, 0x11, 0xf9, + 0x5c, 0x45, 0xe4, 0x75, 0x1d, 0x35, 0x16, 0xeb, 0xa8, 0xf1, 0xb1, 0x8e, 0x1a, 0xb7, 0xdd, 0x07, + 0x89, 0x8f, 0x93, 0x51, 0x2f, 0xd7, 0x65, 0xaa, 0x95, 0xd5, 0xca, 0xa4, 0x6e, 0x78, 0x4e, 0xeb, + 0xbf, 0xa9, 0xeb, 0xd9, 0x51, 0xe0, 0x1e, 0xfe, 0xf4, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x23, 0x73, + 0xed, 0xc6, 0xaf, 0x01, 0x00, 0x00, } func (m *Credential) Marshal() (dAtA []byte, err error) { @@ -172,15 +212,45 @@ func (m *Credential) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Amount != 0 { - i = encodeVarintState(dAtA, i, uint64(m.Amount)) + if m.CreatedAt != 0 { + i = encodeVarintState(dAtA, i, uint64(m.CreatedAt)) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x30 } - if len(m.Account) > 0 { - i -= len(m.Account) - copy(dAtA[i:], m.Account) - i = encodeVarintState(dAtA, i, uint64(len(m.Account))) + if len(m.AttestationType) > 0 { + i -= len(m.AttestationType) + copy(dAtA[i:], m.AttestationType) + i = encodeVarintState(dAtA, i, uint64(len(m.AttestationType))) + i-- + dAtA[i] = 0x2a + } + if len(m.PublicKey) > 0 { + i -= len(m.PublicKey) + copy(dAtA[i:], m.PublicKey) + i = encodeVarintState(dAtA, i, uint64(len(m.PublicKey))) + i-- + dAtA[i] = 0x22 + } + if len(m.Transports) > 0 { + for iNdEx := len(m.Transports) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Transports[iNdEx]) + copy(dAtA[i:], m.Transports[iNdEx]) + i = encodeVarintState(dAtA, i, uint64(len(m.Transports[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Type) > 0 { + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintState(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0x12 + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintState(dAtA, i, uint64(len(m.Id))) i-- dAtA[i] = 0xa } @@ -239,12 +309,30 @@ func (m *Credential) Size() (n int) { } var l int _ = l - l = len(m.Account) + l = len(m.Id) if l > 0 { n += 1 + l + sovState(uint64(l)) } - if m.Amount != 0 { - n += 1 + sovState(uint64(m.Amount)) + l = len(m.Type) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + if len(m.Transports) > 0 { + for _, s := range m.Transports { + l = len(s) + n += 1 + l + sovState(uint64(l)) + } + } + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + l = len(m.AttestationType) + if l > 0 { + n += 1 + l + sovState(uint64(l)) + } + if m.CreatedAt != 0 { + n += 1 + sovState(uint64(m.CreatedAt)) } return n } @@ -302,7 +390,7 @@ func (m *Credential) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -329,16 +417,16 @@ func (m *Credential) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Account = append(m.Account[:0], dAtA[iNdEx:postIndex]...) - if m.Account == nil { - m.Account = []byte{} + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} } iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - m.Amount = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowState @@ -348,7 +436,137 @@ func (m *Credential) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Amount |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Transports", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + 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 ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Transports = append(m.Transports, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthState + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.PublicKey == nil { + m.PublicKey = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AttestationType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + 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 ErrInvalidLengthState + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthState + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AttestationType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CreatedAt", wireType) + } + m.CreatedAt = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowState + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CreatedAt |= uint64(b&0x7F) << shift if b < 0x80 { break } From 93770d481a4b4d540b85a0532ccce3e687ae2f72 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 26 Nov 2024 14:17:58 -0500 Subject: [PATCH 20/30] fix: update devbox lockfile --- .gitignore | 1 + devbox.lock | 54 ---- docs/adrs/adr-1.md | 141 ---------- docs/adrs/adr-2.md | 145 ----------- docs/adrs/adr-3.md | 91 ------- docs/adrs/adr-4.md | 0 docs/reference/guides/cosmos-orm.md | 329 ------------------------ docs/reference/guides/cosmos-sdk.md | 3 - docs/reference/guides/echo-framework.md | 3 - docs/reference/guides/templ-syntax.md | 3 - docs/reference/guides/wa-components.md | 3 - go.mod | 3 +- go.sum | 2 - 13 files changed, 2 insertions(+), 776 deletions(-) delete mode 100644 docs/adrs/adr-1.md delete mode 100644 docs/adrs/adr-2.md delete mode 100644 docs/adrs/adr-3.md delete mode 100644 docs/adrs/adr-4.md delete mode 100644 docs/reference/guides/cosmos-orm.md delete mode 100644 docs/reference/guides/cosmos-sdk.md delete mode 100644 docs/reference/guides/echo-framework.md delete mode 100644 docs/reference/guides/templ-syntax.md delete mode 100644 docs/reference/guides/wa-components.md diff --git a/.gitignore b/.gitignore index 912ee974f..cc5d07498 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ dist **/.haptic static pkg/webapp/dist +.agent # Test binary *.test diff --git a/devbox.lock b/devbox.lock index 86b5293ce..073867ef6 100644 --- a/devbox.lock +++ b/devbox.lock @@ -144,60 +144,6 @@ "store_path": "/nix/store/1bnivwijzrnzx5h0hd5rywwy8rlhxmw5-gum-0.14.5" } } - }, - "ipfs@latest": { - "last_modified": "2023-02-24T09:01:09Z", - "resolved": "github:NixOS/nixpkgs/7d0ed7f2e5aea07ab22ccb338d27fbe347ed2f11#ipfs", - "source": "devbox-search", - "version": "0.17.0" - }, - "templ@latest": { - "last_modified": "2024-10-13T23:44:06Z", - "resolved": "github:NixOS/nixpkgs/d4f247e89f6e10120f911e2e2d2254a050d0f732#templ", - "source": "devbox-search", - "version": "0.2.778", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/n7bmbwk126kiclzi317yprpnc6rkn0jv-templ-0.2.778", - "default": true - } - ], - "store_path": "/nix/store/n7bmbwk126kiclzi317yprpnc6rkn0jv-templ-0.2.778" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/9fi535j2qw60x28vb5wlcz989z2wz959-templ-0.2.778", - "default": true - } - ], - "store_path": "/nix/store/9fi535j2qw60x28vb5wlcz989z2wz959-templ-0.2.778" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/6r17bj68ahbf41xlk87pilbhj394anyy-templ-0.2.778", - "default": true - } - ], - "store_path": "/nix/store/6r17bj68ahbf41xlk87pilbhj394anyy-templ-0.2.778" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/6c1sqrhl7a68npksq7jicsa310qj9k1q-templ-0.2.778", - "default": true - } - ], - "store_path": "/nix/store/6c1sqrhl7a68npksq7jicsa310qj9k1q-templ-0.2.778" - } - } } } } diff --git a/docs/adrs/adr-1.md b/docs/adrs/adr-1.md deleted file mode 100644 index e687d0d40..000000000 --- a/docs/adrs/adr-1.md +++ /dev/null @@ -1,141 +0,0 @@ -# `x/did` - -The Decentralized Identity module is responsible for managing native Sonr Accounts, their derived wallets, and associated user identification information. - -## State - -The DID module maintains several key state structures: - -### Controller State - -The Controller state represents a Sonr DWN Vault. It includes: -- Unique identifier (number) -- DID -- Sonr address -- Ethereum address -- Bitcoin address -- Public key -- Keyshares pointer -- Claimed block -- Creation block - -### Assertion State - -The Assertion state includes: -- DID -- Controller -- Subject -- Public key -- Assertion type -- Accumulator (metadata) -- Creation block - -### Authentication State - -The Authentication state includes: -- DID -- Controller -- Subject -- Public key -- Credential ID -- Metadata -- Creation block - -### Verification State - -The Verification state includes: -- DID -- Controller -- DID method -- Issuer -- Subject -- Public key -- Verification type -- Metadata -- Creation block - -## State Transitions - -State transitions are triggered by the following messages: -- LinkAssertion -- LinkAuthentication -- UnlinkAssertion -- UnlinkAuthentication -- ExecuteTx -- UpdateParams - -## Messages - -The DID module defines the following messages: - -1. MsgLinkAuthentication -2. MsgLinkAssertion -3. MsgExecuteTx -4. MsgUnlinkAssertion -5. MsgUnlinkAuthentication -6. MsgUpdateParams - -Each message triggers specific state machine behaviors related to managing DIDs, authentications, assertions, and module parameters. - -## Query - -The DID module provides the following query endpoints: - -1. Params: Query all parameters of the module -2. Resolve: Query the DID document by its ID -3. Sign: Sign a message with the DID document -4. Verify: Verify a message with the DID document - -## Params - -The module parameters include: -- Allowed public keys (map of KeyInfo) -- Conveyance preference -- Attestation formats - -## Client - -The module provides gRPC and REST endpoints for all defined messages and queries. - -## Future Improvements - -Potential future improvements could include: -1. Enhanced privacy features for DID operations -2. Integration with more blockchain networks -3. Support for additional key types and cryptographic algorithms -4. Improved revocation mechanisms for credentials and assertions - -## Tests - -Acceptance tests should cover all major functionality, including: -- Creating and managing DIDs -- Linking and unlinking assertions and authentications -- Executing transactions with DIDs -- Querying and resolving DIDs -- Parameter updates - -## Appendix - -### Account - -An Account represents a user's identity within the Sonr ecosystem. It includes information such as the user's public key, associated wallets, and other identification details. - -### Decentralized Identifier (DID) - -A Decentralized Identifier (DID) is a unique identifier that is created, owned, and controlled by the user. It is used to establish a secure and verifiable digital identity. - -### Verifiable Credential (VC) - -A Verifiable Credential (VC) is a digital statement that can be cryptographically verified. It contains claims about a subject (e.g., a user) and is issued by a trusted authority. - -### Key Types - -The module supports various key types, including: -- Role -- Algorithm (e.g., ES256, EdDSA, ES256K) -- Encoding (e.g., hex, base64, multibase) -- Curve (e.g., P256, P384, P521, X25519, X448, Ed25519, Ed448, secp256k1) - -### JSON Web Key (JWK) - -The module supports JSON Web Keys (JWK) for representing cryptographic keys, including properties such as key type (kty), curve (crv), and coordinates (x, y) for EC and OKP keys, as well as modulus (n) and exponent (e) for RSA keys. diff --git a/docs/adrs/adr-2.md b/docs/adrs/adr-2.md deleted file mode 100644 index ecca8c15a..000000000 --- a/docs/adrs/adr-2.md +++ /dev/null @@ -1,145 +0,0 @@ -# `x/dwn` - -The DWN module is responsible for the management of IPFS deployed Decentralized Web Nodes (DWNs) and their associated data. - -## Concepts - -The DWN module introduces several key concepts: - -1. Decentralized Web Node (DWN): A distributed network for storing and sharing data. -2. Schema: A structure defining the format of various data types in the dwn. -3. IPFS Integration: The module can interact with IPFS for decentralized data storage. - -## State - -The DWN module maintains the following state: - -### DWN State - -The DWN state is stored using the following structure: - -```protobuf -message DWN { - uint64 id = 1; - string alias = 2; - string cid = 3; - string resolver = 4; -} -``` - -This state is indexed by ID, alias, and CID for efficient querying. - -### Params State - -The module parameters are stored in the following structure: - -```protobuf -message Params { - bool ipfs_active = 1; - bool local_registration_enabled = 2; - Schema schema = 4; -} -``` - -### Schema State - -The Schema state defines the structure for various data types: - -```protobuf -message Schema { - int32 version = 1; - string account = 2; - string asset = 3; - string chain = 4; - string credential = 5; - string did = 6; - string jwk = 7; - string grant = 8; - string keyshare = 9; - string profile = 10; -} -``` - -## State Transitions - -State transitions in the DWN module are primarily triggered by: - -1. Updating module parameters -2. Allocating new dwns -3. Syncing DID documents - -## Messages - -The DWN module defines the following message: - -1. `MsgUpdateParams`: Used to update the module parameters. - -```protobuf -message MsgUpdateParams { - string authority = 1; - Params params = 2; -} -``` - -## Begin Block - -No specific begin-block operations are defined for this module. - -## End Block - -No specific end-block operations are defined for this module. - -## Hooks - -The DWN module does not define any hooks. - -## Events - -The DWN module does not explicitly define any events. However, standard Cosmos SDK events may be emitted during state transitions. - -## Client - -The DWN module provides the following gRPC query endpoints: - -1. `Params`: Queries all parameters of the module. -2. `Schema`: Queries the DID document schema. -3. `Allocate`: Initializes a Target DWN available for claims. -4. `Sync`: Queries the DID document by its ID and returns required information. - -## Params - -The module parameters include: - -- `ipfs_active` (bool): Indicates if IPFS integration is active. -- `local_registration_enabled` (bool): Indicates if local registration is enabled. -- `schema` (Schema): Defines the structure for various data types in the dwn. - -## Future Improvements - -Potential future improvements could include: - -1. Enhanced IPFS integration features. -2. Additional authentication mechanisms beyond WebAuthn. -3. Improved DID document management and querying capabilities. - -## Tests - -Acceptance tests should cover: - -1. Parameter updates -2. DWN state management -3. Schema queries -4. DWN allocation process -5. DID document syncing - -## Appendix - -| Concept | Description | -| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Decentralized Web Node (DWN) | A decentralized, distributed, and secure network of nodes that store and share data. It is a decentralized alternative to traditional web hosting services. | -| Decentralized Identifier (DID) | A unique identifier that is created, owned, and controlled by the user. It is used to establish a secure and verifiable digital identity. | -| HTMX (Hypertext Markup Language eXtensions) | A set of extensions to HTML that allow for the creation of interactive web pages. It is used to enhance the user experience and provide additional functionality to web applications. | -| IPFS (InterPlanetary File System) | A decentralized, peer-to-peer network for storing and sharing data. It is a distributed file system that allows for the creation and sharing of content across a network of nodes. | -| WebAuthn (Web Authentication) | A set of APIs that allow websites to request user authentication using biometric or non-biometric factors. | -| WebAssembly (Web Assembly) | A binary instruction format for a stack-based virtual machine. | -| Verifiable Credential (VC) | A digital statement that can be cryptographically verified. | diff --git a/docs/adrs/adr-3.md b/docs/adrs/adr-3.md deleted file mode 100644 index 079760c07..000000000 --- a/docs/adrs/adr-3.md +++ /dev/null @@ -1,91 +0,0 @@ -# `x/svc` - -The svc module is responsible for managing the registration and authorization of services within the Sonr ecosystem. It provides a secure and verifiable mechanism for registering and authorizing services using Decentralized Identifiers (DIDs). - -## Concepts - -- **Service**: A decentralized svc on the Sonr Blockchain with properties such as ID, authority, origin, name, description, category, tags, and expiry height. -- **Profile**: Represents a DID alias with properties like ID, subject, origin, and controller. -- **Metadata**: Contains information about a svc, including name, description, category, icon, and tags. - -### Dependencies - -- [x/did](https://github.com/onsonr/sonr/tree/master/x/did) -- [x/group](https://github.com/onsonr/sonr/tree/master/x/group) -- [x/nft](https://github.com/onsonr/sonr/tree/master/x/nft) - -## State - -The module uses the following state structures: - -### Metadata - -Stores information about services: - -- Primary key: `id` (auto-increment) -- Unique index: `origin` -- Fields: id, origin, name, description, category, icon (URI), tags - -### Profile - -Stores DID alias information: - -- Primary key: `id` -- Unique index: `subject,origin` -- Fields: id, subject, origin, controller - -## Messages - -### MsgUpdateParams - -Updates the module parameters. Can only be executed by the governance account. - -### MsgRegisterService - -Registers a new svc on the blockchain. Requires a valid TXT record in DNS for the origin. - -## Params - -The module has the following parameters: - -- `categories`: List of allowed svc categories -- `types`: List of allowed svc types - -## Query - -The module provides the following query: - -### Params - -Retrieves all parameters of the module. - -## Client - -### gRPC - -The module provides a gRPC Query svc with the following RPC: - -- `Params`: Get all parameters of the module - -### CLI - -(TODO: Add CLI commands for interacting with the module) - -## Events - -(TODO: List and describe event tags used by the module) - -## Future Improvements - -- Implement svc discovery mechanisms -- Add support for svc reputation and rating systems -- Enhance svc metadata with more detailed information -- Implement svc update and deactivation functionality - -## Tests - -(TODO: Add acceptance tests for the module) - -## Appendix - -This module is part of the Sonr blockchain project and interacts with other modules such as DID and NFT modules to provide a comprehensive decentralized svc ecosystem. diff --git a/docs/adrs/adr-4.md b/docs/adrs/adr-4.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/reference/guides/cosmos-orm.md b/docs/reference/guides/cosmos-orm.md deleted file mode 100644 index 65627bf76..000000000 --- a/docs/reference/guides/cosmos-orm.md +++ /dev/null @@ -1,329 +0,0 @@ -# ORM - -The Cosmos SDK ORM is a state management library that provides a rich, but opinionated set of tools for managing a -module's state. It provides support for: - -- type safe management of state -- multipart keys -- secondary indexes -- unique indexes -- easy prefix and range queries -- automatic genesis import/export -- automatic query services for clients, including support for light client proofs (still in development) -- indexing state data in external databases (still in development) - -## Design and Philosophy - -The ORM's data model is inspired by the relational data model found in SQL databases. The core abstraction is a table -with a primary key and optional secondary indexes. - -Because the Cosmos SDK uses protobuf as its encoding layer, ORM tables are defined directly in .proto files using -protobuf options. Each table is defined by a single protobuf `message` type and a schema of multiple tables is -represented by a single .proto file. - -Table structure is specified in the same file where messages are defined in order to make it easy to focus on better -design of the state layer. Because blockchain state layout is part of the public API for clients (TODO: link to docs on -light client proofs), it is important to think about the state layout as being part of the public API of a module. -Changing the state layout actually breaks clients, so it is ideal to think through it carefully up front and to aim for -a design that will eliminate or minimize breaking changes down the road. Also, good design of state enables building -more performant and sophisticated applications. Providing users with a set of tools inspired by relational databases -which have a long history of database design best practices and allowing schema to be specified declaratively in a -single place are design choices the ORM makes to enable better design and more durable APIs. - -Also, by only supporting the table abstraction as opposed to key-value pair maps, it is easy to add to new -columns/fields to any data structure without causing a breaking change and the data structures can easily be indexed in -any off-the-shelf SQL database for more sophisticated queries. - -The encoding of fields in keys is designed to support ordered iteration for all protobuf primitive field types -except for `bytes` as well as the well-known types `google.protobuf.Timestamp` and `google.protobuf.Duration`. Encodings -are optimized for storage space when it makes sense (see the documentation in `cosmos/orm/v1/orm.proto` for more details) -and table rows do not use extra storage space to store key fields in the value. - -We recommend that users of the ORM attempt to follow database design best practices such as -[normalization](https://en.wikipedia.org/wiki/Database_normalization) (at least 1NF). -For instance, defining `repeated` fields in a table is considered an anti-pattern because breaks first normal form (1NF). -Although we support `repeated` fields in tables, they cannot be used as key fields for this reason. This may seem -restrictive but years of best practice (and also experience in the SDK) have shown that following this pattern -leads to easier to maintain schemas. - -To illustrate the motivation for these principles with an example from the SDK, historically balances were stored -as a mapping from account -> map of denom to amount. This did not scale well because an account with 100 token balances -needed to be encoded/decoded every time a single coin balance changed. Now balances are stored as account,denom -> amount -as in the example above. With the ORM's data model, if we wanted to add a new field to `Balance` such as -`unlocked_balance` (if vesting accounts were redesigned in this way), it would be easy to add it to this table without -requiring a data migration. Because of the ORM's optimizations, the account and denom are only stored in the key part -of storage and not in the value leading to both a flexible data model and efficient usage of storage. - -## Defining Tables - -To define a table: - -1. create a .proto file to describe the module's state (naming it `state.proto` is recommended for consistency), - and import "cosmos/orm/v1/orm.proto", ex: - -```protobuf -syntax = "proto3"; -package bank_example; - -import "cosmos/orm/v1/orm.proto"; -``` - -2. define a `message` for the table, ex: - -```protobuf -message Balance { - bytes account = 1; - string denom = 2; - uint64 balance = 3; -} -``` - -3. add the `cosmos.orm.v1.table` option to the table and give the table an `id` unique within this .proto file: - -```protobuf -message Balance { - option (cosmos.orm.v1.table) = { - id: 1 - }; - - bytes account = 1; - string denom = 2; - uint64 balance = 3; -} -``` - -4. define the primary key field or fields, as a comma-separated list of the fields from the message which should make - up the primary key: - -```protobuf -message Balance { - option (cosmos.orm.v1.table) = { - id: 1 - primary_key: { fields: "account,denom" } - }; - - bytes account = 1; - string denom = 2; - uint64 balance = 3; -} -``` - -5. add any desired secondary indexes by specifying an `id` unique within the table and a comma-separate list of the - index fields: - -```protobuf -message Balance { - option (cosmos.orm.v1.table) = { - id: 1; - primary_key: { fields: "account,denom" } - index: { id: 1 fields: "denom" } // this allows querying for the accounts which own a denom - }; - - bytes account = 1; - string denom = 2; - uint64 amount = 3; -} -``` - -### Auto-incrementing Primary Keys - -A common pattern in SDK modules and in database design is to define tables with a single integer `id` field with an -automatically generated primary key. In the ORM we can do this by setting the `auto_increment` option to `true` on the -primary key, ex: - -```protobuf -message Account { - option (cosmos.orm.v1.table) = { - id: 2; - primary_key: { fields: "id", auto_increment: true } - }; - - uint64 id = 1; - bytes address = 2; -} -``` - -### Unique Indexes - -A unique index can be added by setting the `unique` option to `true` on an index, ex: - -```protobuf -message Account { - option (cosmos.orm.v1.table) = { - id: 2; - primary_key: { fields: "id", auto_increment: true } - index: {id: 1, fields: "address", unique: true} - }; - - uint64 id = 1; - bytes address = 2; -} -``` - -### Singletons - -The ORM also supports a special type of table with only one row called a `singleton`. This can be used for storing -module parameters. Singletons only need to define a unique `id` and that cannot conflict with the id of other -tables or singletons in the same .proto file. Ex: - -```protobuf -message Params { - option (cosmos.orm.v1.singleton) = { - id: 3; - }; - - google.protobuf.Duration voting_period = 1; - uint64 min_threshold = 2; -} -``` - -## Running Codegen - -NOTE: the ORM will only work with protobuf code that implements the [google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf) -API. That means it will not work with code generated using gogo-proto. - -To install the ORM's code generator, run: - -```shell -go install cosmossdk.io/orm/cmd/protoc-gen-go-cosmos-orm@latest -``` - -The recommended way to run the code generator is to use [buf build](https://docs.buf.build/build/usage). -This is an example `buf.gen.yaml` that runs `protoc-gen-go`, `protoc-gen-go-grpc` and `protoc-gen-go-cosmos-orm` -using buf managed mode: - -```yaml -version: v1 -managed: - enabled: true - go_package_prefix: - default: foo.bar/api # the go package prefix of your package - override: - buf.build/cosmos/cosmos-sdk: cosmossdk.io/api # required to import the Cosmos SDK api module -plugins: - - name: go - out: . - opt: paths=source_relative - - name: go-grpc - out: . - opt: paths=source_relative - - name: go-cosmos-orm - out: . - opt: paths=source_relative -``` - -## Using the ORM in a module - -### Initialization - -To use the ORM in a module, first create a `ModuleSchemaDescriptor`. This tells the ORM which .proto files have defined -an ORM schema and assigns them all a unique non-zero id. Ex: - -```go -var MyModuleSchema = &ormv1alpha1.ModuleSchemaDescriptor{ - SchemaFile: []*ormv1alpha1.ModuleSchemaDescriptor_FileEntry{ - { - Id: 1, - ProtoFileName: mymodule.File_my_module_state_proto.Path(), - }, - }, -} -``` - -In the ORM generated code for a file named `state.proto`, there should be an interface `StateStore` that got generated -with a constructor `NewStateStore` that takes a parameter of type `ormdb.ModuleDB`. Add a reference to `StateStore` -to your module's keeper struct. Ex: - -```go -type Keeper struct { - db StateStore -} -``` - -Then instantiate the `StateStore` instance via an `ormdb.ModuleDB` that is instantiated from the `SchemaDescriptor` -above and one or more store services from `cosmossdk.io/core/store`. Ex: - -```go -func NewKeeper(storeService store.KVStoreService) (*Keeper, error) { - modDb, err := ormdb.NewModuleDB(MyModuleSchema, ormdb.ModuleDBOptions{KVStoreService: storeService}) - if err != nil { - return nil, err - } - db, err := NewStateStore(modDb) - if err != nil { - return nil, err - } - return Keeper{db: db}, nil -} -``` - -### Using the generated code - -The generated code for the ORM contains methods for inserting, updating, deleting and querying table entries. -For each table in a .proto file, there is a type-safe table interface implemented in generated code. For instance, -for a table named `Balance` there should be a `BalanceTable` interface that looks like this: - -```go -type BalanceTable interface { - Insert(ctx context.Context, balance *Balance) error - Update(ctx context.Context, balance *Balance) error - Save(ctx context.Context, balance *Balance) error - Delete(ctx context.Context, balance *Balance) error - Has(ctx context.Context, account []byte, denom string) (found bool, err error) - // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. - Get(ctx context.Context, account []byte, denom string) (*Balance, error) - List(ctx context.Context, prefixKey BalanceIndexKey, opts ...ormlist.Option) (BalanceIterator, error) - ListRange(ctx context.Context, from, to BalanceIndexKey, opts ...ormlist.Option) (BalanceIterator, error) - DeleteBy(ctx context.Context, prefixKey BalanceIndexKey) error - DeleteRange(ctx context.Context, from, to BalanceIndexKey) error - - doNotImplement() -} -``` - -This `BalanceTable` should be accessible from the `StateStore` interface (assuming our file is named `state.proto`) -via a `BalanceTable()` accessor method. If all the above example tables/singletons were in the same `state.proto`, -then `StateStore` would get generated like this: - -```go -type BankStore interface { - BalanceTable() BalanceTable - AccountTable() AccountTable - ParamsTable() ParamsTable - - doNotImplement() -} -``` - -So to work with the `BalanceTable` in a keeper method we could use code like this: - -```go -func (k keeper) AddBalance(ctx context.Context, acct []byte, denom string, amount uint64) error { - balance, err := k.db.BalanceTable().Get(ctx, acct, denom) - if err != nil && !ormerrors.IsNotFound(err) { - return err - } - - if balance == nil { - balance = &Balance{ - Account: acct, - Denom: denom, - Amount: amount, - } - } else { - balance.Amount = balance.Amount + amount - } - - return k.db.BalanceTable().Save(ctx, balance) -} -``` - -`List` methods take `IndexKey` parameters. For instance, `BalanceTable.List` takes `BalanceIndexKey`. `BalanceIndexKey` -let's represent index keys for the different indexes (primary and secondary) on the `Balance` table. The primary key -in the `Balance` table gets a struct `BalanceAccountDenomIndexKey` and the first index gets an index key `BalanceDenomIndexKey`. -If we wanted to list all the denoms and amounts that an account holds, we would use `BalanceAccountDenomIndexKey` -with a `List` query just on the account prefix. Ex: - -```go -it, err := keeper.db.BalanceTable().List(ctx, BalanceAccountDenomIndexKey{}.WithAccount(acct)) -``` diff --git a/docs/reference/guides/cosmos-sdk.md b/docs/reference/guides/cosmos-sdk.md deleted file mode 100644 index dea85ad75..000000000 --- a/docs/reference/guides/cosmos-sdk.md +++ /dev/null @@ -1,3 +0,0 @@ -# Cosmos SDK - -The Cosmos SDK is a modular framework for building blockchain applications. Sonr is built on top of the Cosmos SDK, which provides a robust and secure foundation for building decentralized applications. diff --git a/docs/reference/guides/echo-framework.md b/docs/reference/guides/echo-framework.md deleted file mode 100644 index 232447377..000000000 --- a/docs/reference/guides/echo-framework.md +++ /dev/null @@ -1,3 +0,0 @@ -# Echo Framework - -The Echo Framework is a web framework for building RESTful APIs in Go. It provides a simple and intuitive way to define routes, handle requests, and return responses. It uses `net/http` underneath to provide minimal external dependencies. diff --git a/docs/reference/guides/templ-syntax.md b/docs/reference/guides/templ-syntax.md deleted file mode 100644 index b9a22c881..000000000 --- a/docs/reference/guides/templ-syntax.md +++ /dev/null @@ -1,3 +0,0 @@ -# Templ Syntax - -Templ is a template engine for Go that provides a simple and intuitive way to generate dynamic content. diff --git a/docs/reference/guides/wa-components.md b/docs/reference/guides/wa-components.md deleted file mode 100644 index 3753d379e..000000000 --- a/docs/reference/guides/wa-components.md +++ /dev/null @@ -1,3 +0,0 @@ -# WebAwesome Components - -WebAwesome Components is a collection of reusable web components for building web applications. It provides a set of pre-built components that can be easily integrated into your web application. diff --git a/go.mod b/go.mod index 0328bce87..1f8645d49 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,6 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 github.com/ecies/go/v2 v2.0.9 - github.com/ethereum/go-ethereum v1.14.6 github.com/go-webauthn/webauthn v0.11.2 github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang/protobuf v1.5.4 @@ -144,6 +143,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/emicklei/dot v1.6.1 // indirect + github.com/ethereum/go-ethereum v1.14.6 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -188,7 +188,6 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect - github.com/holiman/uint256 v1.2.4 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/iancoleman/orderedmap v0.3.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect diff --git a/go.sum b/go.sum index 25b4a6d83..25044d5c5 100644 --- a/go.sum +++ b/go.sum @@ -1561,8 +1561,6 @@ github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8 github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= -github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= From f89260bacd520b11d48c6d6a41b4b74d3cd6b7e3 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 26 Nov 2024 20:51:58 -0500 Subject: [PATCH 21/30] feat: add support for parent field and resources list in Capability message --- api/dwn/v1/genesis.pulsar.go | 333 ++++++++++++++++++++++++++------- api/dwn/v1/state.cosmos_orm.go | 292 +++++++++++++++++++++++++++++ api/dwn/v1/state.pulsar.go | 90 ++++----- proto/dwn/v1/genesis.proto | 8 +- proto/dwn/v1/state.proto | 3 +- x/dwn/keeper/keeper.go | 1 - x/dwn/types/genesis.go | 31 +++ x/dwn/types/genesis.pb.go | 215 +++++++++++++++------ x/dwn/types/state.pb.go | 64 +++---- 9 files changed, 838 insertions(+), 199 deletions(-) create mode 100644 api/dwn/v1/state.cosmos_orm.go diff --git a/api/dwn/v1/genesis.pulsar.go b/api/dwn/v1/genesis.pulsar.go index fc3b4762f..cb51912b1 100644 --- a/api/dwn/v1/genesis.pulsar.go +++ b/api/dwn/v1/genesis.pulsar.go @@ -992,17 +992,67 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { } } +var _ protoreflect.List = (*_Capability_4_list)(nil) + +type _Capability_4_list struct { + list *[]string +} + +func (x *_Capability_4_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Capability_4_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Capability_4_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Capability_4_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Capability_4_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Capability at list field Resources as it is not of Message kind")) +} + +func (x *_Capability_4_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Capability_4_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Capability_4_list) IsValid() bool { + return x.list != nil +} + var ( md_Capability protoreflect.MessageDescriptor fd_Capability_name protoreflect.FieldDescriptor + fd_Capability_parent protoreflect.FieldDescriptor fd_Capability_description protoreflect.FieldDescriptor + fd_Capability_resources protoreflect.FieldDescriptor ) func init() { file_dwn_v1_genesis_proto_init() md_Capability = File_dwn_v1_genesis_proto.Messages().ByName("Capability") fd_Capability_name = md_Capability.Fields().ByName("name") + fd_Capability_parent = md_Capability.Fields().ByName("parent") fd_Capability_description = md_Capability.Fields().ByName("description") + fd_Capability_resources = md_Capability.Fields().ByName("resources") } var _ protoreflect.Message = (*fastReflection_Capability)(nil) @@ -1076,12 +1126,24 @@ func (x *fastReflection_Capability) Range(f func(protoreflect.FieldDescriptor, p return } } + if x.Parent != "" { + value := protoreflect.ValueOfString(x.Parent) + if !f(fd_Capability_parent, value) { + return + } + } if x.Description != "" { value := protoreflect.ValueOfString(x.Description) if !f(fd_Capability_description, value) { return } } + if len(x.Resources) != 0 { + value := protoreflect.ValueOfList(&_Capability_4_list{list: &x.Resources}) + if !f(fd_Capability_resources, value) { + return + } + } } // Has reports whether a field is populated. @@ -1099,8 +1161,12 @@ func (x *fastReflection_Capability) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { case "dwn.v1.Capability.name": return x.Name != "" + case "dwn.v1.Capability.parent": + return x.Parent != "" case "dwn.v1.Capability.description": return x.Description != "" + case "dwn.v1.Capability.resources": + return len(x.Resources) != 0 default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) @@ -1119,8 +1185,12 @@ func (x *fastReflection_Capability) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { case "dwn.v1.Capability.name": x.Name = "" + case "dwn.v1.Capability.parent": + x.Parent = "" case "dwn.v1.Capability.description": x.Description = "" + case "dwn.v1.Capability.resources": + x.Resources = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) @@ -1140,9 +1210,18 @@ func (x *fastReflection_Capability) Get(descriptor protoreflect.FieldDescriptor) case "dwn.v1.Capability.name": value := x.Name return protoreflect.ValueOfString(value) + case "dwn.v1.Capability.parent": + value := x.Parent + return protoreflect.ValueOfString(value) case "dwn.v1.Capability.description": value := x.Description return protoreflect.ValueOfString(value) + case "dwn.v1.Capability.resources": + if len(x.Resources) == 0 { + return protoreflect.ValueOfList(&_Capability_4_list{}) + } + listValue := &_Capability_4_list{list: &x.Resources} + return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) @@ -1165,8 +1244,14 @@ func (x *fastReflection_Capability) Set(fd protoreflect.FieldDescriptor, value p switch fd.FullName() { case "dwn.v1.Capability.name": x.Name = value.Interface().(string) + case "dwn.v1.Capability.parent": + x.Parent = value.Interface().(string) case "dwn.v1.Capability.description": x.Description = value.Interface().(string) + case "dwn.v1.Capability.resources": + lv := value.List() + clv := lv.(*_Capability_4_list) + x.Resources = *clv.list default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) @@ -1187,8 +1272,16 @@ func (x *fastReflection_Capability) Set(fd protoreflect.FieldDescriptor, value p // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Capability) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "dwn.v1.Capability.resources": + if x.Resources == nil { + x.Resources = []string{} + } + value := &_Capability_4_list{list: &x.Resources} + return protoreflect.ValueOfList(value) case "dwn.v1.Capability.name": panic(fmt.Errorf("field name of message dwn.v1.Capability is not mutable")) + case "dwn.v1.Capability.parent": + panic(fmt.Errorf("field parent of message dwn.v1.Capability is not mutable")) case "dwn.v1.Capability.description": panic(fmt.Errorf("field description of message dwn.v1.Capability is not mutable")) default: @@ -1206,8 +1299,13 @@ func (x *fastReflection_Capability) NewField(fd protoreflect.FieldDescriptor) pr switch fd.FullName() { case "dwn.v1.Capability.name": return protoreflect.ValueOfString("") + case "dwn.v1.Capability.parent": + return protoreflect.ValueOfString("") case "dwn.v1.Capability.description": return protoreflect.ValueOfString("") + case "dwn.v1.Capability.resources": + list := []string{} + return protoreflect.ValueOfList(&_Capability_4_list{list: &list}) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Capability")) @@ -1281,10 +1379,20 @@ func (x *fastReflection_Capability) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + l = len(x.Parent) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } l = len(x.Description) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + if len(x.Resources) > 0 { + for _, s := range x.Resources { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -1314,11 +1422,27 @@ func (x *fastReflection_Capability) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.Resources) > 0 { + for iNdEx := len(x.Resources) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Resources[iNdEx]) + copy(dAtA[i:], x.Resources[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Resources[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } if len(x.Description) > 0 { i -= len(x.Description) copy(dAtA[i:], x.Description) i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Description))) i-- + dAtA[i] = 0x1a + } + if len(x.Parent) > 0 { + i -= len(x.Parent) + copy(dAtA[i:], x.Parent) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Parent))) + i-- dAtA[i] = 0x12 } if len(x.Name) > 0 { @@ -1410,6 +1534,38 @@ func (x *fastReflection_Capability) ProtoMethods() *protoiface.Methods { x.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Parent", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Parent = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) } @@ -1441,6 +1597,38 @@ func (x *fastReflection_Capability) ProtoMethods() *protoiface.Methods { } x.Description = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Resources = append(x.Resources, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -1477,16 +1665,16 @@ func (x *fastReflection_Capability) ProtoMethods() *protoiface.Methods { } var ( - md_Resource protoreflect.MessageDescriptor - fd_Resource_name protoreflect.FieldDescriptor - fd_Resource_description protoreflect.FieldDescriptor + md_Resource protoreflect.MessageDescriptor + fd_Resource_kind protoreflect.FieldDescriptor + fd_Resource_template protoreflect.FieldDescriptor ) func init() { file_dwn_v1_genesis_proto_init() md_Resource = File_dwn_v1_genesis_proto.Messages().ByName("Resource") - fd_Resource_name = md_Resource.Fields().ByName("name") - fd_Resource_description = md_Resource.Fields().ByName("description") + fd_Resource_kind = md_Resource.Fields().ByName("kind") + fd_Resource_template = md_Resource.Fields().ByName("template") } var _ protoreflect.Message = (*fastReflection_Resource)(nil) @@ -1554,15 +1742,15 @@ func (x *fastReflection_Resource) Interface() protoreflect.ProtoMessage { // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_Resource) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if x.Name != "" { - value := protoreflect.ValueOfString(x.Name) - if !f(fd_Resource_name, value) { + if x.Kind != "" { + value := protoreflect.ValueOfString(x.Kind) + if !f(fd_Resource_kind, value) { return } } - if x.Description != "" { - value := protoreflect.ValueOfString(x.Description) - if !f(fd_Resource_description, value) { + if x.Template != "" { + value := protoreflect.ValueOfString(x.Template) + if !f(fd_Resource_template, value) { return } } @@ -1581,10 +1769,10 @@ func (x *fastReflection_Resource) Range(f func(protoreflect.FieldDescriptor, pro // a repeated field is populated if it is non-empty. func (x *fastReflection_Resource) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "dwn.v1.Resource.name": - return x.Name != "" - case "dwn.v1.Resource.description": - return x.Description != "" + case "dwn.v1.Resource.kind": + return x.Kind != "" + case "dwn.v1.Resource.template": + return x.Template != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) @@ -1601,10 +1789,10 @@ func (x *fastReflection_Resource) Has(fd protoreflect.FieldDescriptor) bool { // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Resource) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "dwn.v1.Resource.name": - x.Name = "" - case "dwn.v1.Resource.description": - x.Description = "" + case "dwn.v1.Resource.kind": + x.Kind = "" + case "dwn.v1.Resource.template": + x.Template = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) @@ -1621,11 +1809,11 @@ func (x *fastReflection_Resource) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_Resource) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "dwn.v1.Resource.name": - value := x.Name + case "dwn.v1.Resource.kind": + value := x.Kind return protoreflect.ValueOfString(value) - case "dwn.v1.Resource.description": - value := x.Description + case "dwn.v1.Resource.template": + value := x.Template return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { @@ -1647,10 +1835,10 @@ func (x *fastReflection_Resource) Get(descriptor protoreflect.FieldDescriptor) p // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Resource) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "dwn.v1.Resource.name": - x.Name = value.Interface().(string) - case "dwn.v1.Resource.description": - x.Description = value.Interface().(string) + case "dwn.v1.Resource.kind": + x.Kind = value.Interface().(string) + case "dwn.v1.Resource.template": + x.Template = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) @@ -1671,10 +1859,10 @@ func (x *fastReflection_Resource) Set(fd protoreflect.FieldDescriptor, value pro // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Resource) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "dwn.v1.Resource.name": - panic(fmt.Errorf("field name of message dwn.v1.Resource is not mutable")) - case "dwn.v1.Resource.description": - panic(fmt.Errorf("field description of message dwn.v1.Resource is not mutable")) + case "dwn.v1.Resource.kind": + panic(fmt.Errorf("field kind of message dwn.v1.Resource is not mutable")) + case "dwn.v1.Resource.template": + panic(fmt.Errorf("field template of message dwn.v1.Resource is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: dwn.v1.Resource")) @@ -1688,9 +1876,9 @@ func (x *fastReflection_Resource) Mutable(fd protoreflect.FieldDescriptor) proto // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_Resource) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "dwn.v1.Resource.name": + case "dwn.v1.Resource.kind": return protoreflect.ValueOfString("") - case "dwn.v1.Resource.description": + case "dwn.v1.Resource.template": return protoreflect.ValueOfString("") default: if fd.IsExtension() { @@ -1761,11 +1949,11 @@ func (x *fastReflection_Resource) ProtoMethods() *protoiface.Methods { var n int var l int _ = l - l = len(x.Name) + l = len(x.Kind) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - l = len(x.Description) + l = len(x.Template) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } @@ -1798,17 +1986,17 @@ func (x *fastReflection_Resource) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if len(x.Description) > 0 { - i -= len(x.Description) - copy(dAtA[i:], x.Description) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Description))) + if len(x.Template) > 0 { + i -= len(x.Template) + copy(dAtA[i:], x.Template) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Template))) i-- dAtA[i] = 0x12 } - if len(x.Name) > 0 { - i -= len(x.Name) - copy(dAtA[i:], x.Name) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) + if len(x.Kind) > 0 { + i -= len(x.Kind) + copy(dAtA[i:], x.Kind) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Kind))) i-- dAtA[i] = 0xa } @@ -1863,7 +2051,7 @@ func (x *fastReflection_Resource) ProtoMethods() *protoiface.Methods { switch fieldNum { case 1: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1891,11 +2079,11 @@ func (x *fastReflection_Resource) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Name = string(dAtA[iNdEx:postIndex]) + x.Kind = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1923,7 +2111,7 @@ func (x *fastReflection_Resource) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Description = string(dAtA[iNdEx:postIndex]) + x.Template = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -3048,8 +3236,10 @@ type Capability struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Parent string `protobuf:"bytes,2,opt,name=parent,proto3" json:"parent,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Resources []string `protobuf:"bytes,4,rep,name=resources,proto3" json:"resources,omitempty"` } func (x *Capability) Reset() { @@ -3079,6 +3269,13 @@ func (x *Capability) GetName() string { return "" } +func (x *Capability) GetParent() string { + if x != nil { + return x.Parent + } + return "" +} + func (x *Capability) GetDescription() string { if x != nil { return x.Description @@ -3086,14 +3283,21 @@ func (x *Capability) GetDescription() string { return "" } +func (x *Capability) GetResources() []string { + if x != nil { + return x.Resources + } + return nil +} + // Resource reprensents the available resources of a decentralized web node type Resource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Template string `protobuf:"bytes,2,opt,name=template,proto3" json:"template,omitempty"` } func (x *Resource) Reset() { @@ -3116,16 +3320,16 @@ func (*Resource) Descriptor() ([]byte, []int) { return file_dwn_v1_genesis_proto_rawDescGZIP(), []int{3} } -func (x *Resource) GetName() string { +func (x *Resource) GetKind() string { if x != nil { - return x.Name + return x.Kind } return "" } -func (x *Resource) GetDescription() string { +func (x *Resource) GetTemplate() string { if x != nil { - return x.Description + return x.Template } return "" } @@ -3260,15 +3464,18 @@ var file_dwn_v1_genesis_proto_rawDesc = []byte{ 0x0e, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x19, 0x98, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x0c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x22, 0x42, 0x0a, 0x0a, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x6d, 0x73, 0x22, 0x78, 0x0a, 0x0a, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x40, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf8, 0x01, 0x0a, 0x06, 0x53, 0x63, 0x68, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, + 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x3a, 0x0a, 0x08, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x08, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0xf8, 0x01, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, diff --git a/api/dwn/v1/state.cosmos_orm.go b/api/dwn/v1/state.cosmos_orm.go new file mode 100644 index 000000000..5eff57db7 --- /dev/null +++ b/api/dwn/v1/state.cosmos_orm.go @@ -0,0 +1,292 @@ +// Code generated by protoc-gen-go-cosmos-orm. DO NOT EDIT. + +package dwnv1 + +import ( + context "context" + ormlist "cosmossdk.io/orm/model/ormlist" + ormtable "cosmossdk.io/orm/model/ormtable" + ormerrors "cosmossdk.io/orm/types/ormerrors" +) + +type CredentialTable interface { + Insert(ctx context.Context, credential *Credential) error + Update(ctx context.Context, credential *Credential) error + Save(ctx context.Context, credential *Credential) error + Delete(ctx context.Context, credential *Credential) error + Has(ctx context.Context, id []byte) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, id []byte) (*Credential, error) + List(ctx context.Context, prefixKey CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) + ListRange(ctx context.Context, from, to CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) + DeleteBy(ctx context.Context, prefixKey CredentialIndexKey) error + DeleteRange(ctx context.Context, from, to CredentialIndexKey) error + + doNotImplement() +} + +type CredentialIterator struct { + ormtable.Iterator +} + +func (i CredentialIterator) Value() (*Credential, error) { + var credential Credential + err := i.UnmarshalMessage(&credential) + return &credential, err +} + +type CredentialIndexKey interface { + id() uint32 + values() []interface{} + credentialIndexKey() +} + +// primary key starting index.. +type CredentialPrimaryKey = CredentialIdIndexKey + +type CredentialIdIndexKey struct { + vs []interface{} +} + +func (x CredentialIdIndexKey) id() uint32 { return 0 } +func (x CredentialIdIndexKey) values() []interface{} { return x.vs } +func (x CredentialIdIndexKey) credentialIndexKey() {} + +func (this CredentialIdIndexKey) WithId(id []byte) CredentialIdIndexKey { + this.vs = []interface{}{id} + return this +} + +type credentialTable struct { + table ormtable.Table +} + +func (this credentialTable) Insert(ctx context.Context, credential *Credential) error { + return this.table.Insert(ctx, credential) +} + +func (this credentialTable) Update(ctx context.Context, credential *Credential) error { + return this.table.Update(ctx, credential) +} + +func (this credentialTable) Save(ctx context.Context, credential *Credential) error { + return this.table.Save(ctx, credential) +} + +func (this credentialTable) Delete(ctx context.Context, credential *Credential) error { + return this.table.Delete(ctx, credential) +} + +func (this credentialTable) Has(ctx context.Context, id []byte) (found bool, err error) { + return this.table.PrimaryKey().Has(ctx, id) +} + +func (this credentialTable) Get(ctx context.Context, id []byte) (*Credential, error) { + var credential Credential + found, err := this.table.PrimaryKey().Get(ctx, &credential, id) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &credential, nil +} + +func (this credentialTable) List(ctx context.Context, prefixKey CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) { + it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) + return CredentialIterator{it}, err +} + +func (this credentialTable) ListRange(ctx context.Context, from, to CredentialIndexKey, opts ...ormlist.Option) (CredentialIterator, error) { + it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) + return CredentialIterator{it}, err +} + +func (this credentialTable) DeleteBy(ctx context.Context, prefixKey CredentialIndexKey) error { + return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) +} + +func (this credentialTable) DeleteRange(ctx context.Context, from, to CredentialIndexKey) error { + return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) +} + +func (this credentialTable) doNotImplement() {} + +var _ CredentialTable = credentialTable{} + +func NewCredentialTable(db ormtable.Schema) (CredentialTable, error) { + table := db.GetTable(&Credential{}) + if table == nil { + return nil, ormerrors.TableNotFound.Wrap(string((&Credential{}).ProtoReflect().Descriptor().FullName())) + } + return credentialTable{table}, nil +} + +type ProfileTable interface { + Insert(ctx context.Context, profile *Profile) error + Update(ctx context.Context, profile *Profile) error + Save(ctx context.Context, profile *Profile) error + Delete(ctx context.Context, profile *Profile) error + Has(ctx context.Context, account []byte) (found bool, err error) + // Get returns nil and an error which responds true to ormerrors.IsNotFound() if the record was not found. + Get(ctx context.Context, account []byte) (*Profile, error) + List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) + ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) + DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error + DeleteRange(ctx context.Context, from, to ProfileIndexKey) error + + doNotImplement() +} + +type ProfileIterator struct { + ormtable.Iterator +} + +func (i ProfileIterator) Value() (*Profile, error) { + var profile Profile + err := i.UnmarshalMessage(&profile) + return &profile, err +} + +type ProfileIndexKey interface { + id() uint32 + values() []interface{} + profileIndexKey() +} + +// primary key starting index.. +type ProfilePrimaryKey = ProfileAccountIndexKey + +type ProfileAccountIndexKey struct { + vs []interface{} +} + +func (x ProfileAccountIndexKey) id() uint32 { return 0 } +func (x ProfileAccountIndexKey) values() []interface{} { return x.vs } +func (x ProfileAccountIndexKey) profileIndexKey() {} + +func (this ProfileAccountIndexKey) WithAccount(account []byte) ProfileAccountIndexKey { + this.vs = []interface{}{account} + return this +} + +type ProfileAmountIndexKey struct { + vs []interface{} +} + +func (x ProfileAmountIndexKey) id() uint32 { return 1 } +func (x ProfileAmountIndexKey) values() []interface{} { return x.vs } +func (x ProfileAmountIndexKey) profileIndexKey() {} + +func (this ProfileAmountIndexKey) WithAmount(amount uint64) ProfileAmountIndexKey { + this.vs = []interface{}{amount} + return this +} + +type profileTable struct { + table ormtable.Table +} + +func (this profileTable) Insert(ctx context.Context, profile *Profile) error { + return this.table.Insert(ctx, profile) +} + +func (this profileTable) Update(ctx context.Context, profile *Profile) error { + return this.table.Update(ctx, profile) +} + +func (this profileTable) Save(ctx context.Context, profile *Profile) error { + return this.table.Save(ctx, profile) +} + +func (this profileTable) Delete(ctx context.Context, profile *Profile) error { + return this.table.Delete(ctx, profile) +} + +func (this profileTable) Has(ctx context.Context, account []byte) (found bool, err error) { + return this.table.PrimaryKey().Has(ctx, account) +} + +func (this profileTable) Get(ctx context.Context, account []byte) (*Profile, error) { + var profile Profile + found, err := this.table.PrimaryKey().Get(ctx, &profile, account) + if err != nil { + return nil, err + } + if !found { + return nil, ormerrors.NotFound + } + return &profile, nil +} + +func (this profileTable) List(ctx context.Context, prefixKey ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { + it, err := this.table.GetIndexByID(prefixKey.id()).List(ctx, prefixKey.values(), opts...) + return ProfileIterator{it}, err +} + +func (this profileTable) ListRange(ctx context.Context, from, to ProfileIndexKey, opts ...ormlist.Option) (ProfileIterator, error) { + it, err := this.table.GetIndexByID(from.id()).ListRange(ctx, from.values(), to.values(), opts...) + return ProfileIterator{it}, err +} + +func (this profileTable) DeleteBy(ctx context.Context, prefixKey ProfileIndexKey) error { + return this.table.GetIndexByID(prefixKey.id()).DeleteBy(ctx, prefixKey.values()...) +} + +func (this profileTable) DeleteRange(ctx context.Context, from, to ProfileIndexKey) error { + return this.table.GetIndexByID(from.id()).DeleteRange(ctx, from.values(), to.values()) +} + +func (this profileTable) doNotImplement() {} + +var _ ProfileTable = profileTable{} + +func NewProfileTable(db ormtable.Schema) (ProfileTable, error) { + table := db.GetTable(&Profile{}) + if table == nil { + return nil, ormerrors.TableNotFound.Wrap(string((&Profile{}).ProtoReflect().Descriptor().FullName())) + } + return profileTable{table}, nil +} + +type StateStore interface { + CredentialTable() CredentialTable + ProfileTable() ProfileTable + + doNotImplement() +} + +type stateStore struct { + credential CredentialTable + profile ProfileTable +} + +func (x stateStore) CredentialTable() CredentialTable { + return x.credential +} + +func (x stateStore) ProfileTable() ProfileTable { + return x.profile +} + +func (stateStore) doNotImplement() {} + +var _ StateStore = stateStore{} + +func NewStateStore(db ormtable.Schema) (StateStore, error) { + credentialTable, err := NewCredentialTable(db) + if err != nil { + return nil, err + } + + profileTable, err := NewProfileTable(db) + if err != nil { + return nil, err + } + + return stateStore{ + credentialTable, + profileTable, + }, nil +} diff --git a/api/dwn/v1/state.pulsar.go b/api/dwn/v1/state.pulsar.go index 58b193c4f..57b079fcd 100644 --- a/api/dwn/v1/state.pulsar.go +++ b/api/dwn/v1/state.pulsar.go @@ -62,7 +62,7 @@ func (x *_Credential_3_list) IsValid() bool { var ( md_Credential protoreflect.MessageDescriptor fd_Credential_id protoreflect.FieldDescriptor - fd_Credential_type protoreflect.FieldDescriptor + fd_Credential_kind protoreflect.FieldDescriptor fd_Credential_transports protoreflect.FieldDescriptor fd_Credential_public_key protoreflect.FieldDescriptor fd_Credential_attestation_type protoreflect.FieldDescriptor @@ -73,7 +73,7 @@ func init() { file_dwn_v1_state_proto_init() md_Credential = File_dwn_v1_state_proto.Messages().ByName("Credential") fd_Credential_id = md_Credential.Fields().ByName("id") - fd_Credential_type = md_Credential.Fields().ByName("type") + fd_Credential_kind = md_Credential.Fields().ByName("kind") fd_Credential_transports = md_Credential.Fields().ByName("transports") fd_Credential_public_key = md_Credential.Fields().ByName("public_key") fd_Credential_attestation_type = md_Credential.Fields().ByName("attestation_type") @@ -151,9 +151,9 @@ func (x *fastReflection_Credential) Range(f func(protoreflect.FieldDescriptor, p return } } - if x.Type_ != "" { - value := protoreflect.ValueOfString(x.Type_) - if !f(fd_Credential_type, value) { + if x.Kind != "" { + value := protoreflect.ValueOfString(x.Kind) + if !f(fd_Credential_kind, value) { return } } @@ -198,8 +198,8 @@ func (x *fastReflection_Credential) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { case "dwn.v1.Credential.id": return len(x.Id) != 0 - case "dwn.v1.Credential.type": - return x.Type_ != "" + case "dwn.v1.Credential.kind": + return x.Kind != "" case "dwn.v1.Credential.transports": return len(x.Transports) != 0 case "dwn.v1.Credential.public_key": @@ -226,8 +226,8 @@ func (x *fastReflection_Credential) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { case "dwn.v1.Credential.id": x.Id = nil - case "dwn.v1.Credential.type": - x.Type_ = "" + case "dwn.v1.Credential.kind": + x.Kind = "" case "dwn.v1.Credential.transports": x.Transports = nil case "dwn.v1.Credential.public_key": @@ -255,8 +255,8 @@ func (x *fastReflection_Credential) Get(descriptor protoreflect.FieldDescriptor) case "dwn.v1.Credential.id": value := x.Id return protoreflect.ValueOfBytes(value) - case "dwn.v1.Credential.type": - value := x.Type_ + case "dwn.v1.Credential.kind": + value := x.Kind return protoreflect.ValueOfString(value) case "dwn.v1.Credential.transports": if len(x.Transports) == 0 { @@ -295,8 +295,8 @@ func (x *fastReflection_Credential) Set(fd protoreflect.FieldDescriptor, value p switch fd.FullName() { case "dwn.v1.Credential.id": x.Id = value.Bytes() - case "dwn.v1.Credential.type": - x.Type_ = value.Interface().(string) + case "dwn.v1.Credential.kind": + x.Kind = value.Interface().(string) case "dwn.v1.Credential.transports": lv := value.List() clv := lv.(*_Credential_3_list) @@ -335,8 +335,8 @@ func (x *fastReflection_Credential) Mutable(fd protoreflect.FieldDescriptor) pro return protoreflect.ValueOfList(value) case "dwn.v1.Credential.id": panic(fmt.Errorf("field id of message dwn.v1.Credential is not mutable")) - case "dwn.v1.Credential.type": - panic(fmt.Errorf("field type of message dwn.v1.Credential is not mutable")) + case "dwn.v1.Credential.kind": + panic(fmt.Errorf("field kind of message dwn.v1.Credential is not mutable")) case "dwn.v1.Credential.public_key": panic(fmt.Errorf("field public_key of message dwn.v1.Credential is not mutable")) case "dwn.v1.Credential.attestation_type": @@ -358,7 +358,7 @@ func (x *fastReflection_Credential) NewField(fd protoreflect.FieldDescriptor) pr switch fd.FullName() { case "dwn.v1.Credential.id": return protoreflect.ValueOfBytes(nil) - case "dwn.v1.Credential.type": + case "dwn.v1.Credential.kind": return protoreflect.ValueOfString("") case "dwn.v1.Credential.transports": list := []string{} @@ -442,7 +442,7 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - l = len(x.Type_) + l = len(x.Kind) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } @@ -520,10 +520,10 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { dAtA[i] = 0x1a } } - if len(x.Type_) > 0 { - i -= len(x.Type_) - copy(dAtA[i:], x.Type_) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Type_))) + if len(x.Kind) > 0 { + i -= len(x.Kind) + copy(dAtA[i:], x.Kind) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Kind))) i-- dAtA[i] = 0x12 } @@ -619,7 +619,7 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { iNdEx = postIndex case 2: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Type_", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -647,7 +647,7 @@ func (x *fastReflection_Credential) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Type_ = string(dAtA[iNdEx:postIndex]) + x.Kind = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { @@ -1290,7 +1290,7 @@ type Credential struct { unknownFields protoimpl.UnknownFields Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The credential ID as a byte array - Type_ string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // The credential type (e.g. "public-key") + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` // The credential type (e.g. "public-key") Transports []string `protobuf:"bytes,3,rep,name=transports,proto3" json:"transports,omitempty"` // Optional transport hints (usb, nfc, ble, internal) PublicKey []byte `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` // The credential's public key AttestationType string `protobuf:"bytes,5,opt,name=attestation_type,json=attestationType,proto3" json:"attestation_type,omitempty"` // The attestation type used (e.g. "none", "indirect", etc) @@ -1324,9 +1324,9 @@ func (x *Credential) GetId() []byte { return nil } -func (x *Credential) GetType_() string { +func (x *Credential) GetKind() string { if x != nil { - return x.Type_ + return x.Kind } return "" } @@ -1408,10 +1408,10 @@ var file_dwn_v1_state_proto_rawDesc = []byte{ 0x0a, 0x12, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd3, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc9, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x6e, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, @@ -1420,22 +1420,22 @@ var file_dwn_v1_state_proto_rawDesc = []byte{ 0x09, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x3a, 0x18, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x12, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x12, - 0x08, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x10, 0x01, 0x18, 0x01, 0x22, 0x5c, 0x0a, 0x07, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x1f, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, - 0x0a, 0x09, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x01, 0x18, 0x02, 0x42, 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, - 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, - 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, - 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, - 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x3a, 0x0e, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x08, 0x0a, 0x04, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x22, 0x5c, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x1f, + 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x19, 0x0a, 0x09, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x01, 0x18, 0x02, 0x42, + 0x7a, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x77, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x72, 0x2f, 0x73, + 0x6f, 0x6e, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x77, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x64, + 0x77, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x44, 0x77, 0x6e, + 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x44, 0x77, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x44, + 0x77, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x07, 0x44, 0x77, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/proto/dwn/v1/genesis.proto b/proto/dwn/v1/genesis.proto index 86bce0067..5e5a5306d 100644 --- a/proto/dwn/v1/genesis.proto +++ b/proto/dwn/v1/genesis.proto @@ -26,13 +26,15 @@ message Params { // Capability reprensents the available capabilities of a decentralized web node message Capability { string name = 1; - string description = 2; + string parent = 2; + string description = 3; + repeated string resources = 4; } // Resource reprensents the available resources of a decentralized web node message Resource { - string name = 1; - string description = 2; + string kind = 1; + string template = 2; } // Schema is the Database Model for Decentralized Web Nodes diff --git a/proto/dwn/v1/state.proto b/proto/dwn/v1/state.proto index 0ac1efe51..00b865640 100644 --- a/proto/dwn/v1/state.proto +++ b/proto/dwn/v1/state.proto @@ -11,11 +11,10 @@ message Credential { option (cosmos.orm.v1.table) = { id: 1; primary_key: { fields: "id" } - index: { id: 1 fields: "type" } }; bytes id = 1; // The credential ID as a byte array - string type = 2; // The credential type (e.g. "public-key") + string kind = 2; // The credential type (e.g. "public-key") repeated string transports = 3; // Optional transport hints (usb, nfc, ble, internal) bytes public_key = 4; // The credential's public key string attestation_type = 5; // The attestation type used (e.g. "none", "indirect", etc) diff --git a/x/dwn/keeper/keeper.go b/x/dwn/keeper/keeper.go index 363ca49bf..0357613c1 100644 --- a/x/dwn/keeper/keeper.go +++ b/x/dwn/keeper/keeper.go @@ -81,7 +81,6 @@ func (k Keeper) Logger() log.Logger { // InitGenesis initializes the module's state from a genesis state. func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { - if err := data.Params.Validate(); err != nil { return err } diff --git a/x/dwn/types/genesis.go b/x/dwn/types/genesis.go index e1e8ab313..58200b59f 100644 --- a/x/dwn/types/genesis.go +++ b/x/dwn/types/genesis.go @@ -1,5 +1,36 @@ package types +// Define capability hierarchy for smart account operations +const ( + // Root capabilities + CAP_OWNER = "OWNER" // Full account control + CAP_OPERATOR = "OPERATOR" // Can perform operations + CAP_OBSERVER = "OBSERVER" // Can view account state + + // Operation capabilities + CAP_EXECUTE = "EXECUTE" // Can execute transactions + CAP_PROPOSE = "PROPOSE" // Can propose transactions + CAP_SIGN = "SIGN" // Can sign transactions + + // Policy capabilities + CAP_SET_POLICY = "SET_POLICY" // Can modify account policies + CAP_SET_THRESHOLD = "SET_THRESHOLD" // Can modify signing threshold + + // Recovery capabilities + CAP_RECOVER = "RECOVER" // Can initiate recovery + CAP_SOCIAL = "SOCIAL" // Can act as social recovery +) + +// Resource types for smart account operations +type ResourceType string + +const ( + RES_ACCOUNT = "account" + RES_TRANSACTION = "tx" + RES_POLICY = "policy" + RES_RECOVERY = "recovery" +) + // DefaultIndex is the default global index const DefaultIndex uint64 = 1 diff --git a/x/dwn/types/genesis.pb.go b/x/dwn/types/genesis.pb.go index 969bc9fc8..2a34727a0 100644 --- a/x/dwn/types/genesis.pb.go +++ b/x/dwn/types/genesis.pb.go @@ -132,8 +132,10 @@ func (m *Params) GetSchema() *Schema { // Capability reprensents the available capabilities of a decentralized web node type Capability struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Parent string `protobuf:"bytes,2,opt,name=parent,proto3" json:"parent,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Resources []string `protobuf:"bytes,4,rep,name=resources,proto3" json:"resources,omitempty"` } func (m *Capability) Reset() { *m = Capability{} } @@ -176,6 +178,13 @@ func (m *Capability) GetName() string { return "" } +func (m *Capability) GetParent() string { + if m != nil { + return m.Parent + } + return "" +} + func (m *Capability) GetDescription() string { if m != nil { return m.Description @@ -183,10 +192,17 @@ func (m *Capability) GetDescription() string { return "" } +func (m *Capability) GetResources() []string { + if m != nil { + return m.Resources + } + return nil +} + // Resource reprensents the available resources of a decentralized web node type Resource struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Template string `protobuf:"bytes,2,opt,name=template,proto3" json:"template,omitempty"` } func (m *Resource) Reset() { *m = Resource{} } @@ -222,16 +238,16 @@ func (m *Resource) XXX_DiscardUnknown() { var xxx_messageInfo_Resource proto.InternalMessageInfo -func (m *Resource) GetName() string { +func (m *Resource) GetKind() string { if m != nil { - return m.Name + return m.Kind } return "" } -func (m *Resource) GetDescription() string { +func (m *Resource) GetTemplate() string { if m != nil { - return m.Description + return m.Template } return "" } @@ -364,37 +380,40 @@ func init() { func init() { proto.RegisterFile("dwn/v1/genesis.proto", fileDescriptor_8e7492a25d5871dc) } var fileDescriptor_8e7492a25d5871dc = []byte{ - // 478 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x31, 0x8f, 0xd3, 0x30, - 0x1c, 0xc5, 0x13, 0xae, 0xcd, 0xb5, 0xff, 0x9e, 0x10, 0x58, 0x1d, 0x4c, 0x87, 0xf4, 0xd4, 0x01, - 0x21, 0x84, 0x12, 0x1d, 0x6c, 0xa8, 0x03, 0x14, 0x21, 0x56, 0x94, 0xdb, 0x58, 0x2a, 0xd7, 0xf1, - 0xa5, 0xbe, 0x26, 0x76, 0x64, 0xbb, 0x29, 0xfd, 0x0a, 0x4c, 0x8c, 0x8c, 0x37, 0x33, 0xf1, 0x31, - 0x6e, 0xbc, 0x91, 0x09, 0xa1, 0x76, 0x80, 0x8f, 0xc0, 0x88, 0x6c, 0xe7, 0x50, 0x59, 0x6f, 0xb1, - 0xfe, 0xef, 0xf7, 0xfe, 0x79, 0x79, 0xb2, 0x0c, 0xc3, 0x7c, 0x23, 0xd2, 0xe6, 0x2c, 0x2d, 0x98, - 0x60, 0x9a, 0xeb, 0xa4, 0x56, 0xd2, 0x48, 0x14, 0xe5, 0x1b, 0x91, 0x34, 0x67, 0xa3, 0x61, 0x21, - 0x0b, 0xe9, 0x50, 0x6a, 0x27, 0xef, 0x8e, 0x1e, 0x92, 0x8a, 0x0b, 0x99, 0xba, 0xd3, 0xa3, 0xc9, - 0x14, 0x4e, 0xde, 0xf9, 0x84, 0x73, 0x43, 0x0c, 0x43, 0xcf, 0x20, 0xaa, 0x89, 0x22, 0x95, 0xc6, - 0xe1, 0x69, 0xf8, 0x64, 0xf0, 0xfc, 0x7e, 0xe2, 0x13, 0x93, 0xf7, 0x8e, 0xce, 0x3a, 0xd7, 0x3f, - 0xc6, 0x41, 0xd6, 0xee, 0x4c, 0xbe, 0x86, 0x10, 0x79, 0x03, 0x8d, 0x61, 0xc0, 0xeb, 0x0b, 0x3d, - 0x27, 0xd4, 0xf0, 0x86, 0xb9, 0xaf, 0x7b, 0x19, 0x58, 0xf4, 0xda, 0x11, 0x34, 0x85, 0x51, 0x29, - 0x29, 0x29, 0xe7, 0x8a, 0x15, 0x5c, 0x1b, 0x45, 0x0c, 0x97, 0x62, 0xce, 0x04, 0x59, 0x94, 0x2c, - 0xc7, 0xf7, 0xdc, 0x3e, 0x76, 0x1b, 0xd9, 0xc1, 0xc2, 0x5b, 0xef, 0xa3, 0xc7, 0x10, 0x69, 0xba, - 0x64, 0x15, 0xc1, 0x9d, 0xff, 0x7b, 0x9d, 0x3b, 0x9a, 0xb5, 0xee, 0xcb, 0x47, 0x5f, 0xae, 0xc6, - 0xc1, 0xef, 0xab, 0x71, 0xf8, 0xe9, 0xd7, 0xb7, 0xa7, 0x27, 0x0d, 0x59, 0x97, 0x26, 0x6d, 0xcb, - 0xce, 0x00, 0xde, 0x90, 0x9a, 0x2c, 0x78, 0xc9, 0xcd, 0x16, 0x21, 0xe8, 0x08, 0x52, 0xf9, 0xa2, - 0xfd, 0xcc, 0xcd, 0xe8, 0x14, 0x06, 0x39, 0xd3, 0x54, 0xf1, 0xda, 0xfe, 0xda, 0x75, 0xea, 0x67, - 0x87, 0x68, 0xf2, 0x0a, 0x7a, 0x19, 0xd3, 0x72, 0xad, 0x28, 0xbb, 0x63, 0xc2, 0x9f, 0x10, 0x22, - 0xdf, 0x19, 0x61, 0x38, 0x6e, 0x98, 0xd2, 0x76, 0xd1, 0x66, 0x74, 0xb3, 0x5b, 0x69, 0x1d, 0x42, - 0xa9, 0x5c, 0x0b, 0xd3, 0x46, 0xdc, 0x4a, 0x34, 0x84, 0x2e, 0xd1, 0x9a, 0x19, 0x7c, 0xe4, 0xb8, - 0x17, 0x96, 0xd2, 0x25, 0xe1, 0xc2, 0x5d, 0x4e, 0x3f, 0xf3, 0x02, 0xc5, 0x00, 0x54, 0xb1, 0x9c, - 0x09, 0xc3, 0x49, 0x89, 0xbb, 0xce, 0x3a, 0x20, 0xe8, 0x01, 0x1c, 0xe5, 0x3c, 0xc7, 0x91, 0x33, - 0xec, 0x68, 0xc9, 0xe5, 0x66, 0x85, 0x8f, 0x3d, 0xb9, 0xdc, 0xac, 0x6c, 0x72, 0xa1, 0x88, 0x30, - 0xb8, 0xe7, 0x93, 0x9d, 0x40, 0x23, 0xe8, 0xad, 0xd8, 0x56, 0x2f, 0x89, 0x62, 0xb8, 0xef, 0x8c, - 0x7f, 0xda, 0x76, 0xaf, 0x95, 0xbc, 0xe0, 0x25, 0xc3, 0xe0, 0xbb, 0xb7, 0x72, 0x36, 0xbd, 0xde, - 0xc5, 0xe1, 0xcd, 0x2e, 0x0e, 0x7f, 0xee, 0xe2, 0xf0, 0xf3, 0x3e, 0x0e, 0x6e, 0xf6, 0x71, 0xf0, - 0x7d, 0x1f, 0x07, 0x1f, 0x26, 0x05, 0x37, 0xcb, 0xf5, 0x22, 0xa1, 0xb2, 0x4a, 0xa5, 0xd0, 0x52, - 0xa8, 0xd4, 0x1d, 0x1f, 0x53, 0xfb, 0xca, 0xcd, 0xb6, 0x66, 0x7a, 0x11, 0xb9, 0x07, 0xfb, 0xe2, - 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfa, 0x30, 0xe3, 0x96, 0xf9, 0x02, 0x00, 0x00, + // 519 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x93, 0x31, 0x6f, 0x13, 0x31, + 0x14, 0xc7, 0x73, 0x34, 0xbd, 0xe6, 0x5e, 0x2b, 0x04, 0x56, 0x85, 0x4c, 0x84, 0x2e, 0x51, 0x06, + 0x54, 0x21, 0x94, 0x53, 0x61, 0xab, 0xb2, 0x50, 0x84, 0x58, 0xd1, 0x75, 0x63, 0x89, 0x9c, 0xbb, + 0xd7, 0x8b, 0x9b, 0x3b, 0xfb, 0x64, 0x3b, 0x49, 0xf3, 0x15, 0x98, 0x18, 0x19, 0x3b, 0x33, 0xf1, + 0x31, 0x3a, 0x76, 0x64, 0x42, 0x28, 0x19, 0xe0, 0x23, 0x30, 0x22, 0xdb, 0x97, 0x12, 0x16, 0xeb, + 0xfd, 0x7f, 0xff, 0xe7, 0xe7, 0xff, 0x8b, 0x72, 0x70, 0x9c, 0x2f, 0x45, 0xb2, 0x38, 0x4d, 0x0a, + 0x14, 0xa8, 0xb9, 0x1e, 0xd6, 0x4a, 0x1a, 0x49, 0xc2, 0x7c, 0x29, 0x86, 0x8b, 0xd3, 0xee, 0x71, + 0x21, 0x0b, 0xe9, 0x50, 0x62, 0x2b, 0xef, 0x76, 0x1f, 0xb3, 0x8a, 0x0b, 0x99, 0xb8, 0xd3, 0xa3, + 0xc1, 0x08, 0x8e, 0xde, 0xfb, 0x09, 0x17, 0x86, 0x19, 0x24, 0x2f, 0x21, 0xac, 0x99, 0x62, 0x95, + 0xa6, 0x41, 0x3f, 0x38, 0x39, 0x7c, 0xf5, 0x70, 0xe8, 0x27, 0x0e, 0x3f, 0x38, 0x7a, 0xde, 0xbe, + 0xfd, 0xd1, 0x6b, 0xa5, 0x4d, 0xcf, 0xe0, 0x6b, 0x00, 0xa1, 0x37, 0x48, 0x0f, 0x0e, 0x79, 0x7d, + 0xa9, 0xc7, 0x2c, 0x33, 0x7c, 0x81, 0xee, 0x76, 0x27, 0x05, 0x8b, 0xde, 0x38, 0x42, 0x46, 0xd0, + 0x2d, 0x65, 0xc6, 0xca, 0xb1, 0xc2, 0x82, 0x6b, 0xa3, 0x98, 0xe1, 0x52, 0x8c, 0x51, 0xb0, 0x49, + 0x89, 0x39, 0x7d, 0xe0, 0xfa, 0xa9, 0xeb, 0x48, 0x77, 0x1a, 0xde, 0x79, 0x9f, 0x3c, 0x87, 0x50, + 0x67, 0x53, 0xac, 0x18, 0x6d, 0xff, 0x9f, 0xeb, 0xc2, 0xd1, 0xb4, 0x71, 0xcf, 0x9e, 0x7e, 0xb9, + 0xe9, 0xb5, 0x7e, 0xdf, 0xf4, 0x82, 0x4f, 0xbf, 0xbe, 0xbd, 0x38, 0x5a, 0xb0, 0x79, 0x69, 0x92, + 0x26, 0xec, 0x35, 0xc0, 0x5b, 0x56, 0xb3, 0x09, 0x2f, 0xb9, 0x59, 0x11, 0x02, 0x6d, 0xc1, 0x2a, + 0x1f, 0x34, 0x4a, 0x5d, 0x4d, 0x9e, 0xb8, 0xe5, 0x51, 0x18, 0x17, 0x27, 0x4a, 0x1b, 0x45, 0xfa, + 0x70, 0x98, 0xa3, 0xce, 0x14, 0xaf, 0x6d, 0x24, 0xba, 0xe7, 0xcc, 0x5d, 0x44, 0x9e, 0x41, 0xa4, + 0x50, 0xcb, 0xb9, 0xca, 0x50, 0xd3, 0x76, 0x7f, 0xef, 0x24, 0x4a, 0xff, 0x81, 0xc1, 0x19, 0x74, + 0xd2, 0x46, 0xd8, 0x77, 0x67, 0x5c, 0xe4, 0xdb, 0x77, 0x6d, 0x4d, 0xba, 0xd0, 0x31, 0x58, 0xd5, + 0x25, 0x33, 0xd8, 0xbc, 0x7c, 0xaf, 0x07, 0x7f, 0x02, 0x08, 0xfd, 0x8e, 0x84, 0xc2, 0xc1, 0x02, + 0x95, 0xb6, 0x11, 0xec, 0xed, 0xfd, 0x74, 0x2b, 0xad, 0xc3, 0xb2, 0x4c, 0xce, 0xef, 0x93, 0x6f, + 0x25, 0x39, 0x86, 0x7d, 0xa6, 0x35, 0x9a, 0x26, 0xb4, 0x17, 0x96, 0x66, 0x53, 0xc6, 0x85, 0xfb, + 0x31, 0xa3, 0xd4, 0x0b, 0x12, 0x03, 0x64, 0x0a, 0x73, 0x14, 0x86, 0xb3, 0x92, 0xee, 0x3b, 0x6b, + 0x87, 0x90, 0x47, 0xb0, 0x97, 0xf3, 0x9c, 0x86, 0xce, 0xb0, 0xa5, 0x25, 0x57, 0xcb, 0x19, 0x3d, + 0xf0, 0xe4, 0x6a, 0x39, 0xb3, 0x93, 0x0b, 0xc5, 0x84, 0xa1, 0x1d, 0x3f, 0xd9, 0x09, 0xbb, 0xe0, + 0x0c, 0x57, 0x7a, 0xca, 0x14, 0xd2, 0xc8, 0x2f, 0xb8, 0xd5, 0x36, 0x7b, 0xad, 0xe4, 0x25, 0x2f, + 0x91, 0x82, 0xcf, 0xde, 0xc8, 0xf3, 0xd1, 0xed, 0x3a, 0x0e, 0xee, 0xd6, 0x71, 0xf0, 0x73, 0x1d, + 0x07, 0x9f, 0x37, 0x71, 0xeb, 0x6e, 0x13, 0xb7, 0xbe, 0x6f, 0xe2, 0xd6, 0xc7, 0x41, 0xc1, 0xcd, + 0x74, 0x3e, 0x19, 0x66, 0xb2, 0x4a, 0xa4, 0xd0, 0x52, 0xa8, 0xc4, 0x1d, 0xd7, 0x89, 0xfd, 0x2a, + 0xcc, 0xaa, 0x46, 0x3d, 0x09, 0xdd, 0x1f, 0xfc, 0xf5, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9d, + 0x36, 0x1c, 0x5c, 0x29, 0x03, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -535,11 +554,27 @@ func (m *Capability) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Resources) > 0 { + for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Resources[iNdEx]) + copy(dAtA[i:], m.Resources[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Resources[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } if len(m.Description) > 0 { i -= len(m.Description) copy(dAtA[i:], m.Description) i = encodeVarintGenesis(dAtA, i, uint64(len(m.Description))) i-- + dAtA[i] = 0x1a + } + if len(m.Parent) > 0 { + i -= len(m.Parent) + copy(dAtA[i:], m.Parent) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Parent))) + i-- dAtA[i] = 0x12 } if len(m.Name) > 0 { @@ -572,17 +607,17 @@ func (m *Resource) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Description) > 0 { - i -= len(m.Description) - copy(dAtA[i:], m.Description) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Description))) + if len(m.Template) > 0 { + i -= len(m.Template) + copy(dAtA[i:], m.Template) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Template))) i-- dAtA[i] = 0x12 } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Name))) + if len(m.Kind) > 0 { + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Kind))) i-- dAtA[i] = 0xa } @@ -731,10 +766,20 @@ func (m *Capability) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } + l = len(m.Parent) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } l = len(m.Description) if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } + if len(m.Resources) > 0 { + for _, s := range m.Resources { + l = len(s) + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -744,11 +789,11 @@ func (m *Resource) Size() (n int) { } var l int _ = l - l = len(m.Name) + l = len(m.Kind) if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - l = len(m.Description) + l = len(m.Template) if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } @@ -1080,6 +1125,38 @@ func (m *Capability) Unmarshal(dAtA []byte) error { m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parent", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Parent = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) } @@ -1111,6 +1188,38 @@ func (m *Capability) Unmarshal(dAtA []byte) error { } m.Description = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resources = append(m.Resources, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -1163,7 +1272,7 @@ func (m *Resource) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1191,11 +1300,11 @@ func (m *Resource) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Kind = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Template", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1223,7 +1332,7 @@ func (m *Resource) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Description = string(dAtA[iNdEx:postIndex]) + m.Template = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/dwn/types/state.pb.go b/x/dwn/types/state.pb.go index d84aba9ef..f139d28cc 100644 --- a/x/dwn/types/state.pb.go +++ b/x/dwn/types/state.pb.go @@ -25,7 +25,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Credential struct { Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` Transports []string `protobuf:"bytes,3,rep,name=transports,proto3" json:"transports,omitempty"` PublicKey []byte `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` AttestationType string `protobuf:"bytes,5,opt,name=attestation_type,json=attestationType,proto3" json:"attestation_type,omitempty"` @@ -72,9 +72,9 @@ func (m *Credential) GetId() []byte { return nil } -func (m *Credential) GetType() string { +func (m *Credential) GetKind() string { if m != nil { - return m.Type + return m.Kind } return "" } @@ -167,29 +167,29 @@ func init() { func init() { proto.RegisterFile("dwn/v1/state.proto", fileDescriptor_040a9b061177db90) } var fileDescriptor_040a9b061177db90 = []byte{ - // 342 bytes of a gzipped FileDescriptorProto + // 339 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x91, 0xb1, 0x4e, 0xeb, 0x30, - 0x18, 0x85, 0xeb, 0x34, 0x37, 0xbd, 0xf9, 0x75, 0x75, 0x6f, 0xe5, 0xe1, 0x62, 0x90, 0x1a, 0xa2, - 0x4e, 0x61, 0x69, 0x54, 0xb1, 0x55, 0x2c, 0xc0, 0xc8, 0x82, 0x22, 0x26, 0x84, 0x54, 0xb9, 0x89, - 0x01, 0x8b, 0xc6, 0x8e, 0xec, 0xbf, 0x2d, 0x7d, 0x09, 0xc4, 0x13, 0xf0, 0x3c, 0x8c, 0x95, 0xba, - 0x30, 0xa2, 0xf6, 0x0d, 0x78, 0x02, 0x14, 0xb7, 0x45, 0x5d, 0x2c, 0x9f, 0xe3, 0xe3, 0xcf, 0xc7, - 0x36, 0xd0, 0x62, 0xa6, 0xd2, 0x69, 0x3f, 0xb5, 0xc8, 0x51, 0xf4, 0x2a, 0xa3, 0x51, 0xd3, 0xa0, - 0x98, 0xa9, 0xde, 0xb4, 0x7f, 0x74, 0x90, 0x6b, 0x5b, 0x6a, 0x9b, 0x6a, 0x53, 0xd6, 0x11, 0x6d, - 0xca, 0x4d, 0xa0, 0xbb, 0x24, 0x00, 0x97, 0x46, 0x14, 0x42, 0xa1, 0xe4, 0x63, 0xfa, 0x17, 0x3c, - 0x59, 0x30, 0x12, 0x93, 0xe4, 0x4f, 0xe6, 0xc9, 0x82, 0x52, 0xf0, 0x71, 0x5e, 0x09, 0xe6, 0xc5, - 0x24, 0x09, 0x33, 0x37, 0xa7, 0x11, 0x00, 0x1a, 0xae, 0x6c, 0xa5, 0x0d, 0x5a, 0xd6, 0x8c, 0x9b, - 0x49, 0x98, 0xed, 0x39, 0xb4, 0x03, 0x50, 0x4d, 0x46, 0x63, 0x99, 0x0f, 0x9f, 0xc4, 0x9c, 0xf9, - 0x8e, 0x15, 0x6e, 0x9c, 0x2b, 0x31, 0xa7, 0x27, 0xd0, 0xe6, 0x88, 0xa2, 0x6e, 0x29, 0xb5, 0x1a, - 0x3a, 0xfc, 0x2f, 0x87, 0xff, 0xb7, 0xe7, 0xdf, 0xd4, 0x27, 0x75, 0x00, 0x72, 0x23, 0x38, 0x8a, - 0x62, 0xc8, 0x91, 0x05, 0x31, 0x49, 0xfc, 0x2c, 0xdc, 0x3a, 0xe7, 0x38, 0x60, 0x5f, 0x6f, 0xcb, - 0x97, 0x26, 0x05, 0xbf, 0x2e, 0x4d, 0x7f, 0x6f, 0xaa, 0xb6, 0x09, 0x23, 0xdd, 0x3b, 0x68, 0x5d, - 0x1b, 0x7d, 0x2f, 0xc7, 0x82, 0x32, 0x68, 0xf1, 0x3c, 0xd7, 0x13, 0x85, 0xdb, 0x6b, 0xed, 0x24, - 0xfd, 0x0f, 0x01, 0x2f, 0xdd, 0x82, 0xe7, 0xc8, 0x5b, 0x35, 0x38, 0x76, 0xd8, 0x43, 0x08, 0x7f, - 0x76, 0x52, 0xd8, 0x45, 0xdb, 0x84, 0x79, 0x17, 0x67, 0xef, 0xab, 0x88, 0x2c, 0x56, 0x11, 0xf9, - 0x5c, 0x45, 0xe4, 0x75, 0x1d, 0x35, 0x16, 0xeb, 0xa8, 0xf1, 0xb1, 0x8e, 0x1a, 0xb7, 0xdd, 0x07, - 0x89, 0x8f, 0x93, 0x51, 0x2f, 0xd7, 0x65, 0xaa, 0x95, 0xd5, 0xca, 0xa4, 0x6e, 0x78, 0x4e, 0xeb, - 0xbf, 0xa9, 0xeb, 0xd9, 0x51, 0xe0, 0x1e, 0xfe, 0xf4, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x23, 0x73, - 0xed, 0xc6, 0xaf, 0x01, 0x00, 0x00, + 0x14, 0x86, 0xeb, 0x34, 0x37, 0xbd, 0x39, 0xba, 0xea, 0xad, 0x3c, 0x80, 0x41, 0x22, 0x44, 0x9d, + 0xc2, 0xd2, 0xa8, 0x62, 0xab, 0x58, 0x80, 0x91, 0x05, 0x45, 0x4c, 0x08, 0xa9, 0x72, 0x13, 0x03, + 0x56, 0x1b, 0x3b, 0x72, 0x4e, 0x5b, 0xf2, 0x12, 0x88, 0x27, 0xe0, 0x79, 0x60, 0xab, 0xc4, 0xc2, + 0x88, 0xda, 0x37, 0xe0, 0x09, 0x50, 0xdc, 0x16, 0x75, 0xb1, 0x7c, 0x3e, 0xff, 0xfe, 0x74, 0x8e, + 0x0d, 0x34, 0x9b, 0xab, 0x78, 0xd6, 0x8f, 0x4b, 0xe4, 0x28, 0x7a, 0x85, 0xd1, 0xa8, 0xa9, 0x97, + 0xcd, 0x55, 0x6f, 0xd6, 0x3f, 0xdc, 0x4f, 0x75, 0x99, 0xeb, 0x32, 0xd6, 0x26, 0xaf, 0x23, 0xda, + 0xe4, 0xeb, 0x40, 0xf7, 0x9d, 0x00, 0x5c, 0x1a, 0x91, 0x09, 0x85, 0x92, 0x4f, 0x68, 0x1b, 0x1c, + 0x99, 0x31, 0x12, 0x92, 0xe8, 0x5f, 0xe2, 0xc8, 0x8c, 0x52, 0x70, 0xc7, 0x52, 0x65, 0xcc, 0x09, + 0x49, 0xe4, 0x27, 0x76, 0x4f, 0x03, 0x00, 0x34, 0x5c, 0x95, 0x85, 0x36, 0x58, 0xb2, 0x66, 0xd8, + 0x8c, 0xfc, 0x64, 0x87, 0xd0, 0x23, 0x80, 0x62, 0x3a, 0x9a, 0xc8, 0x74, 0x38, 0x16, 0x15, 0x73, + 0xad, 0xcb, 0x5f, 0x93, 0x2b, 0x51, 0xd1, 0x13, 0xe8, 0x70, 0x44, 0x51, 0x77, 0x29, 0xb5, 0x1a, + 0x62, 0x55, 0x08, 0xf6, 0xc7, 0xea, 0xff, 0xef, 0xf0, 0x9b, 0xaa, 0x10, 0xb5, 0x29, 0x35, 0x82, + 0xa3, 0xc8, 0x86, 0x1c, 0x99, 0x17, 0x92, 0xc8, 0x4d, 0xfc, 0x0d, 0x39, 0xc7, 0x41, 0xfb, 0xfb, + 0xf5, 0xe3, 0xb9, 0xf9, 0x17, 0xdc, 0x75, 0xd3, 0xdd, 0x3b, 0x68, 0x5d, 0x1b, 0x7d, 0x2f, 0x27, + 0x82, 0x32, 0x68, 0xf1, 0x34, 0xd5, 0x53, 0x85, 0x9b, 0x61, 0xb6, 0x25, 0xdd, 0x03, 0x8f, 0xe7, + 0xf6, 0xc0, 0xb1, 0xbe, 0x4d, 0x35, 0x38, 0xb6, 0xb2, 0x03, 0xf0, 0x7f, 0x6f, 0x52, 0xd8, 0x46, + 0x3b, 0x84, 0x39, 0x17, 0x67, 0x6f, 0xcb, 0x80, 0x2c, 0x96, 0x01, 0xf9, 0x5a, 0x06, 0xe4, 0x65, + 0x15, 0x34, 0x16, 0xab, 0xa0, 0xf1, 0xb9, 0x0a, 0x1a, 0xb7, 0xdd, 0x07, 0x89, 0x8f, 0xd3, 0x51, + 0x2f, 0xd5, 0x79, 0xac, 0x55, 0xa9, 0x95, 0x89, 0xed, 0xf2, 0x14, 0xd7, 0x3f, 0x52, 0x0f, 0x58, + 0x8e, 0x3c, 0xfb, 0xdc, 0xa7, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x45, 0xf1, 0xed, 0xf9, 0xa5, + 0x01, 0x00, 0x00, } func (m *Credential) Marshal() (dAtA []byte, err error) { @@ -240,10 +240,10 @@ func (m *Credential) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1a } } - if len(m.Type) > 0 { - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarintState(dAtA, i, uint64(len(m.Type))) + if len(m.Kind) > 0 { + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintState(dAtA, i, uint64(len(m.Kind))) i-- dAtA[i] = 0x12 } @@ -313,7 +313,7 @@ func (m *Credential) Size() (n int) { if l > 0 { n += 1 + l + sovState(uint64(l)) } - l = len(m.Type) + l = len(m.Kind) if l > 0 { n += 1 + l + sovState(uint64(l)) } @@ -424,7 +424,7 @@ func (m *Credential) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -452,7 +452,7 @@ func (m *Credential) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Type = string(dAtA[iNdEx:postIndex]) + m.Kind = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { From 155ff429586e9cbb2b54f19c687253d8f6c2f0aa Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Tue, 26 Nov 2024 21:23:14 -0500 Subject: [PATCH 22/30] feature/1149-vault-allocation-error --- pkg/webapp/components/ui/layout.templ | 8 -------- pkg/webapp/components/ui/layout_templ.go | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/pkg/webapp/components/ui/layout.templ b/pkg/webapp/components/ui/layout.templ index d7d1b9ae3..f95fed9ad 100644 --- a/pkg/webapp/components/ui/layout.templ +++ b/pkg/webapp/components/ui/layout.templ @@ -150,14 +150,6 @@ document.body.classList.remove('overflow-hidden'); -
    { children... }
    diff --git a/pkg/webapp/components/ui/layout_templ.go b/pkg/webapp/components/ui/layout_templ.go index 8aa496d19..efe84c625 100644 --- a/pkg/webapp/components/ui/layout_templ.go +++ b/pkg/webapp/components/ui/layout_templ.go @@ -334,7 +334,7 @@ func FullScreenModal() templ.Component { templ_7745c5c3_Var11 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

    ;G>>s|74zMf8>b{#1{1K0Gnwh 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

  • QEz3xxmAPaOtgKWeDh?9(a1GmV)t_! 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 {0_uigG8cV$QS^i-9cHgQx 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�gk&z~>w9JAE4J-I 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